@@ -6,7 +6,7 @@ use rustc_hir::def_id::DefId;
66use rustc_middle:: ty:: GenericParamDefKind ;
77use rustc_middle:: { bug, ty} ;
88use rustc_span:: symbol:: kw;
9- use rustc_span:: { Ident , Span } ;
9+ use rustc_span:: { Ident , Span , sym } ;
1010
1111use crate :: { LoweringContext , ResolverAstLoweringExt } ;
1212
@@ -25,22 +25,37 @@ pub(super) enum DelegationGenericsKind {
2525 TraitImpl ( bool /* Has user-specified args */ ) ,
2626}
2727
28+ #[ derive( Debug , Clone , Copy ) ]
29+ pub ( super ) enum GenericsPosition {
30+ Parent ,
31+ Child ,
32+ }
33+
2834pub ( super ) struct DelegationGenerics < T > {
2935 generics : T ,
3036 kind : DelegationGenericsKind ,
37+ pos : GenericsPosition ,
3138}
3239
3340impl < ' hir > DelegationGenerics < & ' hir [ ty:: GenericParamDef ] > {
34- fn default ( generics : & ' hir [ ty:: GenericParamDef ] ) -> Self {
35- DelegationGenerics { generics, kind : DelegationGenericsKind :: Default }
41+ fn default ( generics : & ' hir [ ty:: GenericParamDef ] , pos : GenericsPosition ) -> Self {
42+ DelegationGenerics { generics, pos , kind : DelegationGenericsKind :: Default }
3643 }
3744
38- fn user_specified ( generics : & ' hir [ ty:: GenericParamDef ] ) -> Self {
39- DelegationGenerics { generics, kind : DelegationGenericsKind :: UserSpecified }
45+ fn user_specified ( generics : & ' hir [ ty:: GenericParamDef ] , pos : GenericsPosition ) -> Self {
46+ DelegationGenerics { generics, pos , kind : DelegationGenericsKind :: UserSpecified }
4047 }
4148
42- fn trait_impl ( generics : & ' hir [ ty:: GenericParamDef ] , user_specified : bool ) -> Self {
43- DelegationGenerics { generics, kind : DelegationGenericsKind :: TraitImpl ( user_specified) }
49+ fn trait_impl (
50+ generics : & ' hir [ ty:: GenericParamDef ] ,
51+ user_specified : bool ,
52+ pos : GenericsPosition ,
53+ ) -> Self {
54+ DelegationGenerics {
55+ generics,
56+ pos,
57+ kind : DelegationGenericsKind :: TraitImpl ( user_specified) ,
58+ }
4459 }
4560}
4661
@@ -103,8 +118,14 @@ impl<'hir> HirOrTyGenerics<'hir> {
103118 span : Span ,
104119 ) -> & mut HirOrTyGenerics < ' hir > {
105120 if let HirOrTyGenerics :: Ty ( ty) = self {
106- let params = ctx. uplift_delegation_generic_params ( span, ty. generics ) ;
107- * self = HirOrTyGenerics :: Hir ( DelegationGenerics { generics : params, kind : ty. kind } ) ;
121+ let rename_self = matches ! ( ty. pos, GenericsPosition :: Child ) ;
122+ let params = ctx. uplift_delegation_generic_params ( span, ty. generics , rename_self) ;
123+
124+ * self = HirOrTyGenerics :: Hir ( DelegationGenerics {
125+ generics : params,
126+ kind : ty. kind ,
127+ pos : ty. pos ,
128+ } ) ;
108129 }
109130
110131 self
@@ -120,14 +141,14 @@ impl<'hir> HirOrTyGenerics<'hir> {
120141 pub ( super ) fn into_generic_args (
121142 & self ,
122143 ctx : & mut LoweringContext < ' _ , ' hir , impl ResolverAstLoweringExt < ' hir > > ,
123- add_lifetimes : bool ,
124144 span : Span ,
125145 ) -> & ' hir hir:: GenericArgs < ' hir > {
126146 match self {
127147 HirOrTyGenerics :: Ty ( _) => {
128148 bug ! ( "Attempting to get generic args before uplifting to HIR" )
129149 }
130150 HirOrTyGenerics :: Hir ( hir) => {
151+ let add_lifetimes = matches ! ( hir. pos, GenericsPosition :: Parent ) ;
131152 ctx. create_generics_args_from_params ( hir. generics . params , add_lifetimes, span)
132153 }
133154 }
@@ -227,10 +248,15 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
227248 if matches ! ( delegation_parent_kind, DefKind :: Impl { of_trait: true } ) {
228249 // Considering parent generics, during signature inheritance
229250 // we will take those args that are in trait impl header trait ref.
230- let parent = DelegationGenerics :: trait_impl ( & [ ] , true ) ;
251+ let parent = DelegationGenerics :: trait_impl ( & [ ] , true , GenericsPosition :: Parent ) ;
231252 let parent = GenericsGenerationResult :: new ( parent) ;
232253
233- let child = DelegationGenerics :: trait_impl ( sig_params, child_user_specified) ;
254+ let child = DelegationGenerics :: trait_impl (
255+ sig_params,
256+ child_user_specified,
257+ GenericsPosition :: Child ,
258+ ) ;
259+
234260 let child = GenericsGenerationResult :: new ( child) ;
235261
236262 return GenericsGenerationResults {
@@ -263,25 +289,32 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
263289 DelegationGenerics {
264290 kind : DelegationGenericsKind :: SelfAndUserSpecified ,
265291 generics : & sig_parent_params[ ..1 ] ,
292+ pos : GenericsPosition :: Parent ,
266293 }
267294 } else {
268- DelegationGenerics :: user_specified ( & [ ] )
295+ DelegationGenerics :: user_specified ( & [ ] , GenericsPosition :: Parent )
269296 }
270297 } else {
271298 let skip_self = usize:: from ( !generate_self) ;
272- DelegationGenerics :: default ( & sig_parent_params[ skip_self..] )
299+ DelegationGenerics :: default (
300+ & sig_parent_params[ skip_self..] ,
301+ GenericsPosition :: Parent ,
302+ )
273303 }
274304 } else {
275- DelegationGenerics :: default ( & [ ] )
305+ DelegationGenerics :: default ( & [ ] , GenericsPosition :: Parent )
276306 } ;
277307
278308 let child_generics = if child_user_specified {
279309 let synth_params_index =
280310 sig_params. iter ( ) . position ( |p| p. kind . is_synthetic ( ) ) . unwrap_or ( sig_params. len ( ) ) ;
281311
282- DelegationGenerics :: user_specified ( & sig_params[ synth_params_index..] )
312+ DelegationGenerics :: user_specified (
313+ & sig_params[ synth_params_index..] ,
314+ GenericsPosition :: Child ,
315+ )
283316 } else {
284- DelegationGenerics :: default ( sig_params)
317+ DelegationGenerics :: default ( sig_params, GenericsPosition :: Child )
285318 } ;
286319
287320 GenericsGenerationResults {
@@ -296,6 +329,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
296329 & mut self ,
297330 span : Span ,
298331 params : & ' hir [ ty:: GenericParamDef ] ,
332+ rename_self : bool ,
299333 ) -> & ' hir hir:: Generics < ' hir > {
300334 let params = self . arena . alloc_from_iter ( params. iter ( ) . map ( |p| {
301335 let def_kind = match p. kind {
@@ -304,7 +338,20 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
304338 GenericParamDefKind :: Const { .. } => DefKind :: ConstParam ,
305339 } ;
306340
307- let param_ident = Ident :: new ( p. name , span) ;
341+ // Rename Self generic param to This so it is properly propagated.
342+ // If the user will create a function `fn foo<Self>() {}` with generic
343+ // param "Self" then it will not be generated in HIR, the same thing
344+ // applies to traits, `trait Trait<Self> {}` will be represented as
345+ // `trait Trait {}` in HIR and "unexpected keyword `Self` in generic parameters"
346+ // error will be emitted.
347+ // Note that we do not rename `Self` to `This` after non-recursive reuse
348+ // from Trait, in this case the `Self` should not be propagated
349+ // (we rely that implicit `Self` generic param of a trait is named "Self")
350+ // and it is OK to have Self generic param generated during lowering.
351+ let param_name =
352+ if rename_self && p. name == kw:: SelfUpper { sym:: This } else { p. name } ;
353+
354+ let param_ident = Ident :: new ( param_name, span) ;
308355 let def_name = Some ( param_ident. name ) ;
309356 let node_id = self . next_node_id ( ) ;
310357
0 commit comments