@@ -76,41 +76,153 @@ fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> FnKind {
7676 }
7777}
7878
79+ struct GenericsBuilder < ' tcx > {
80+ tcx : TyCtxt < ' tcx > ,
81+ sig_id : DefId ,
82+ parent : Option < DefId > ,
83+ }
84+
85+ impl < ' tcx > GenericsBuilder < ' tcx > {
86+ fn new ( tcx : TyCtxt < ' tcx > , sig_id : DefId ) -> GenericsBuilder < ' tcx > {
87+ GenericsBuilder { tcx, sig_id, parent : None }
88+ }
89+
90+ fn build ( self ) -> ty:: Generics {
91+ let mut own_params = vec ! [ ] ;
92+
93+ let sig_generics = self . tcx . generics_of ( self . sig_id ) ;
94+ if let Some ( parent_def_id) = sig_generics. parent {
95+ let sig_parent_generics = self . tcx . generics_of ( parent_def_id) ;
96+ own_params. append ( & mut sig_parent_generics. own_params . clone ( ) ) ;
97+ }
98+ own_params. append ( & mut sig_generics. own_params . clone ( ) ) ;
99+
100+ // Lifetime parameters must be declared before type and const parameters.
101+ // Therefore, When delegating from a free function to a associated function,
102+ // generic parameters need to be reordered:
103+ //
104+ // trait Trait<'a, A> {
105+ // fn foo<'b, B>(...) {...}
106+ // }
107+ //
108+ // reuse Trait::foo;
109+ // desugaring:
110+ // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) {
111+ // Trait::foo(...)
112+ // }
113+ own_params. sort_by_key ( |key| key. kind . is_ty_or_const ( ) ) ;
114+
115+ let param_def_id_to_index =
116+ own_params. iter ( ) . map ( |param| ( param. def_id , param. index ) ) . collect ( ) ;
117+
118+ for ( idx, param) in own_params. iter_mut ( ) . enumerate ( ) {
119+ param. index = idx as u32 ;
120+ // FIXME(fn_delegation): Default parameters are not inherited, because they are
121+ // not permitted in functions. Therefore, there are 2 options here:
122+ //
123+ // - We can create non-default generic parameters.
124+ // - We can substitute default parameters into the signature.
125+ //
126+ // At the moment, first option has been selected as the most general.
127+ if let ty:: GenericParamDefKind :: Type { has_default, .. }
128+ | ty:: GenericParamDefKind :: Const { has_default, .. } = & mut param. kind
129+ {
130+ * has_default = false ;
131+ }
132+ }
133+
134+ ty:: Generics {
135+ parent : self . parent ,
136+ parent_count : 0 ,
137+ own_params,
138+ param_def_id_to_index,
139+ has_self : false ,
140+ has_late_bound_regions : sig_generics. has_late_bound_regions ,
141+ host_effect_index : sig_generics. host_effect_index ,
142+ }
143+ }
144+ }
145+
146+ struct PredicatesBuilder < ' tcx > {
147+ tcx : TyCtxt < ' tcx > ,
148+ args : ty:: GenericArgsRef < ' tcx > ,
149+ parent : Option < DefId > ,
150+ sig_id : DefId ,
151+ }
152+
153+ impl < ' tcx > PredicatesBuilder < ' tcx > {
154+ fn new (
155+ tcx : TyCtxt < ' tcx > ,
156+ args : ty:: GenericArgsRef < ' tcx > ,
157+ sig_id : DefId ,
158+ ) -> PredicatesBuilder < ' tcx > {
159+ PredicatesBuilder { tcx, args, parent : None , sig_id }
160+ }
161+
162+ fn build ( self ) -> ty:: GenericPredicates < ' tcx > {
163+ let mut preds = vec ! [ ] ;
164+
165+ let sig_predicates = self . tcx . predicates_of ( self . sig_id ) ;
166+ if let Some ( parent) = sig_predicates. parent {
167+ let sig_parent_preds = self . tcx . predicates_of ( parent) ;
168+ preds. extend ( sig_parent_preds. instantiate_own ( self . tcx , self . args ) ) ;
169+ }
170+ preds. extend ( sig_predicates. instantiate_own ( self . tcx , self . args ) ) ;
171+
172+ ty:: GenericPredicates {
173+ parent : self . parent ,
174+ predicates : self . tcx . arena . alloc_from_iter ( preds) ,
175+ // FIXME(fn_delegation): Support effects.
176+ effects_min_tys : ty:: List :: empty ( ) ,
177+ }
178+ }
179+ }
180+
181+ struct GenericArgsBuilder < ' tcx > {
182+ tcx : TyCtxt < ' tcx > ,
183+ remap_table : RemapTable ,
184+ sig_id : DefId ,
185+ def_id : LocalDefId ,
186+ }
187+
188+ impl < ' tcx > GenericArgsBuilder < ' tcx > {
189+ fn new ( tcx : TyCtxt < ' tcx > , sig_id : DefId , def_id : LocalDefId ) -> GenericArgsBuilder < ' tcx > {
190+ GenericArgsBuilder { tcx, remap_table : FxHashMap :: default ( ) , sig_id, def_id }
191+ }
192+
193+ fn build_from_args ( mut self , args : ty:: GenericArgsRef < ' tcx > ) -> ty:: GenericArgsRef < ' tcx > {
194+ let caller_generics = self . tcx . generics_of ( self . def_id ) ;
195+ let callee_generics = self . tcx . generics_of ( self . sig_id ) ;
196+
197+ for caller_param in & caller_generics. own_params {
198+ let callee_index =
199+ callee_generics. param_def_id_to_index ( self . tcx , caller_param. def_id ) . unwrap ( ) ;
200+ self . remap_table . insert ( callee_index, caller_param. index ) ;
201+ }
202+
203+ let mut folder = ParamIndexRemapper { tcx : self . tcx , remap_table : self . remap_table } ;
204+ args. fold_with ( & mut folder)
205+ }
206+ }
207+
79208fn create_generic_args < ' tcx > (
80209 tcx : TyCtxt < ' tcx > ,
81210 def_id : LocalDefId ,
82211 sig_id : DefId ,
83212) -> ty:: GenericArgsRef < ' tcx > {
84- let caller_generics = tcx. generics_of ( def_id) ;
85- let callee_generics = tcx. generics_of ( sig_id) ;
213+ let builder = GenericArgsBuilder :: new ( tcx, sig_id, def_id) ;
86214
87215 let caller_kind = fn_kind ( tcx, def_id. into ( ) ) ;
88216 let callee_kind = fn_kind ( tcx, sig_id) ;
89- // FIXME(fn_delegation): Support generics on associated delegation items.
90- // Error will be reported in `check_constraints`.
217+
91218 match ( caller_kind, callee_kind) {
92- ( FnKind :: Free , _) => {
93- // Lifetime parameters must be declared before type and const parameters.
94- // Therefore, When delegating from a free function to a associated function,
95- // generic parameters need to be reordered:
96- //
97- // trait Trait<'a, A> {
98- // fn foo<'b, B>(...) {...}
99- // }
100- //
101- // reuse Trait::foo;
102- // desugaring:
103- // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) {
104- // Trait::foo(...)
105- // }
106- let mut remap_table = RemapTable :: default ( ) ;
107- for caller_param in & caller_generics. own_params {
108- let callee_index =
109- callee_generics. param_def_id_to_index ( tcx, caller_param. def_id ) . unwrap ( ) ;
110- remap_table. insert ( callee_index, caller_param. index ) ;
111- }
112- let mut folder = ParamIndexRemapper { tcx, remap_table } ;
113- ty:: GenericArgs :: identity_for_item ( tcx, sig_id) . fold_with ( & mut folder)
219+ ( FnKind :: Free , FnKind :: Free )
220+ | ( FnKind :: Free , FnKind :: AssocTrait )
221+ | ( FnKind :: AssocInherentImpl , FnKind :: Free )
222+ | ( FnKind :: AssocTrait , FnKind :: Free )
223+ | ( FnKind :: AssocTrait , FnKind :: AssocTrait ) => {
224+ let args = ty:: GenericArgs :: identity_for_item ( tcx, sig_id) ;
225+ builder. build_from_args ( args)
114226 }
115227 // FIXME(fn_delegation): Only `Self` param supported here.
116228 ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait )
@@ -120,7 +232,11 @@ fn create_generic_args<'tcx>(
120232 let generic_self_ty = ty:: GenericArg :: from ( self_ty) ;
121233 tcx. mk_args_from_iter ( std:: iter:: once ( generic_self_ty) )
122234 }
123- _ => ty:: GenericArgs :: identity_for_item ( tcx, sig_id) ,
235+ // For trait impl's `sig_id` is always equal to the corresponding trait method.
236+ ( FnKind :: AssocTraitImpl , _)
237+ | ( _, FnKind :: AssocTraitImpl )
238+ // Delegation to inherent methods is not yet supported.
239+ | ( _, FnKind :: AssocInherentImpl ) => unreachable ! ( ) ,
124240 }
125241}
126242
@@ -129,74 +245,62 @@ pub(crate) fn inherit_generics_for_delegation_item<'tcx>(
129245 def_id : LocalDefId ,
130246 sig_id : DefId ,
131247) -> Option < ty:: Generics > {
132- // FIXME(fn_delegation): Support generics on associated delegation items.
133- // Error will be reported in `check_constraints`.
134- if fn_kind ( tcx, def_id. into ( ) ) != FnKind :: Free {
135- return None ;
136- }
248+ let builder = GenericsBuilder :: new ( tcx, sig_id) ;
137249
138- let mut own_params = vec ! [ ] ;
139-
140- let callee_generics = tcx. generics_of ( sig_id) ;
141- if let Some ( parent_sig_id) = callee_generics. parent {
142- let parent_sig_generics = tcx. generics_of ( parent_sig_id) ;
143- own_params. append ( & mut parent_sig_generics. own_params . clone ( ) ) ;
144- }
145- own_params. append ( & mut callee_generics. own_params . clone ( ) ) ;
250+ let caller_kind = fn_kind ( tcx, def_id. into ( ) ) ;
251+ let callee_kind = fn_kind ( tcx, sig_id) ;
146252
147- // Lifetimes go first.
148- own_params. sort_by_key ( |key| key. kind . is_ty_or_const ( ) ) ;
253+ // FIXME(fn_delegation): Support generics on associated delegation items.
254+ // Error will be reported in `check_constraints`.
255+ match ( caller_kind, callee_kind) {
256+ ( FnKind :: Free , FnKind :: Free )
257+ | ( FnKind :: Free , FnKind :: AssocTrait ) => Some ( builder. build ( ) ) ,
149258
150- for ( idx, param) in own_params. iter_mut ( ) . enumerate ( ) {
151- param. index = idx as u32 ;
152- // Default parameters are not inherited: they are not allowed
153- // in fn's.
154- if let ty:: GenericParamDefKind :: Type { has_default, .. }
155- | ty:: GenericParamDefKind :: Const { has_default, .. } = & mut param. kind
156- {
157- * has_default = false ;
158- }
259+ ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait )
260+ | ( FnKind :: AssocInherentImpl , FnKind :: AssocTrait )
261+ | ( FnKind :: AssocTrait , FnKind :: AssocTrait )
262+ | ( FnKind :: AssocInherentImpl , FnKind :: Free )
263+ | ( FnKind :: AssocTrait , FnKind :: Free ) => None ,
264+
265+ // For trait impl's `sig_id` is always equal to the corresponding trait method.
266+ ( FnKind :: AssocTraitImpl , _)
267+ | ( _, FnKind :: AssocTraitImpl )
268+ // Delegation to inherent methods is not yet supported.
269+ | ( _, FnKind :: AssocInherentImpl ) => unreachable ! ( ) ,
159270 }
160-
161- let param_def_id_to_index =
162- own_params. iter ( ) . map ( |param| ( param. def_id , param. index ) ) . collect ( ) ;
163-
164- Some ( ty:: Generics {
165- parent : None ,
166- parent_count : 0 ,
167- own_params,
168- param_def_id_to_index,
169- has_self : false ,
170- has_late_bound_regions : callee_generics. has_late_bound_regions ,
171- host_effect_index : callee_generics. host_effect_index ,
172- } )
173271}
174272
175273pub ( crate ) fn inherit_predicates_for_delegation_item < ' tcx > (
176274 tcx : TyCtxt < ' tcx > ,
177275 def_id : LocalDefId ,
178276 sig_id : DefId ,
179277) -> Option < ty:: GenericPredicates < ' tcx > > {
278+ let args = create_generic_args ( tcx, def_id, sig_id) ;
279+ let builder = PredicatesBuilder :: new ( tcx, args, sig_id) ;
280+
281+ let caller_kind = fn_kind ( tcx, def_id. into ( ) ) ;
282+ let callee_kind = fn_kind ( tcx, sig_id) ;
283+
180284 // FIXME(fn_delegation): Support generics on associated delegation items.
181285 // Error will be reported in `check_constraints`.
182- if fn_kind ( tcx, def_id. into ( ) ) != FnKind :: Free {
183- return None ;
184- }
185-
186- let callee_predicates = tcx. predicates_of ( sig_id) ;
187- let args = create_generic_args ( tcx, def_id, sig_id) ;
286+ match ( caller_kind, callee_kind) {
287+ ( FnKind :: Free , FnKind :: Free )
288+ | ( FnKind :: Free , FnKind :: AssocTrait ) => {
289+ Some ( builder. build ( ) )
290+ }
188291
189- let mut preds = vec ! [ ] ;
190- if let Some ( parent_id) = callee_predicates. parent {
191- preds. extend ( tcx. predicates_of ( parent_id) . instantiate_own ( tcx, args) ) ;
292+ ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait )
293+ | ( FnKind :: AssocInherentImpl , FnKind :: AssocTrait )
294+ | ( FnKind :: AssocTrait , FnKind :: AssocTrait )
295+ | ( FnKind :: AssocInherentImpl , FnKind :: Free )
296+ | ( FnKind :: AssocTrait , FnKind :: Free ) => None ,
297+
298+ // For trait impl's `sig_id` is always equal to the corresponding trait method.
299+ ( FnKind :: AssocTraitImpl , _)
300+ | ( _, FnKind :: AssocTraitImpl )
301+ // Delegation to inherent methods is not yet supported.
302+ | ( _, FnKind :: AssocInherentImpl ) => unreachable ! ( ) ,
192303 }
193- preds. extend ( callee_predicates. instantiate_own ( tcx, args) ) ;
194-
195- Some ( ty:: GenericPredicates {
196- parent : None ,
197- predicates : tcx. arena . alloc_from_iter ( preds) ,
198- effects_min_tys : ty:: List :: empty ( ) ,
199- } )
200304}
201305
202306fn check_constraints < ' tcx > (
0 commit comments