@@ -71,22 +71,23 @@ enum SelfPositionKind {
7171 None ,
7272}
7373
74- fn create_self_position_kind (
74+ fn create_self_param_position_kind (
7575 tcx : TyCtxt < ' _ > ,
76- delegation_id : LocalDefId ,
76+ def_id : LocalDefId ,
7777 sig_id : DefId ,
7878) -> SelfPositionKind {
79- match ( fn_kind ( tcx, delegation_id) , fn_kind ( tcx, sig_id) ) {
80- ( FnKind :: AssocInherentImpl , FnKind :: AssocTrait )
81- | ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait )
82- | ( FnKind :: AssocTrait , FnKind :: AssocTrait )
83- | ( FnKind :: AssocTrait , FnKind :: Free ) => SelfPositionKind :: Zero ,
84-
79+ match fn_kinds ( tcx, def_id, sig_id) {
8580 ( FnKind :: Free , FnKind :: AssocTrait ) => {
86- let kind = tcx. hir_delegation_info ( delegation_id ) . self_ty_propagation_kind ;
81+ let kind = tcx. hir_delegation_info ( def_id ) . self_ty_propagation_kind ;
8782 SelfPositionKind :: AfterLifetimes ( kind)
8883 }
8984
85+ ( _, FnKind :: AssocTraitImpl ) => unreachable ! ( ) ,
86+
87+ ( _, FnKind :: AssocTrait ) | ( FnKind :: AssocTrait , _) => SelfPositionKind :: Zero ,
88+
89+ ( FnKind :: AssocTraitImpl , _) => unreachable ! ( ) ,
90+
9091 _ => SelfPositionKind :: None ,
9192 }
9293}
@@ -116,6 +117,17 @@ fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> FnKind {
116117 }
117118}
118119
120+ fn fn_kinds ( tcx : TyCtxt < ' _ > , def_id : LocalDefId , sig_id : DefId ) -> ( FnKind , FnKind ) {
121+ let kinds = ( fn_kind ( tcx, def_id) , fn_kind ( tcx, sig_id) ) ;
122+
123+ // For trait impl's `sig_id` is always equal to the corresponding trait method.
124+ assert ! ( !matches!( kinds, ( _, FnKind :: AssocTraitImpl ) ) ) ;
125+ // Delegation to inherent impls is not yet supported.
126+ assert ! ( !matches!( kinds, ( _, FnKind :: AssocInherentImpl ) ) ) ;
127+
128+ kinds
129+ }
130+
119131/// Given the current context(caller and callee `FnKind`), it specifies
120132/// the policy of predicates and generic parameters inheritance.
121133#[ derive( Clone , Copy , Debug , PartialEq ) ]
@@ -152,7 +164,7 @@ fn create_mapping<'tcx>(
152164) -> FxHashMap < u32 , u32 > {
153165 let mut mapping: FxHashMap < u32 , u32 > = Default :: default ( ) ;
154166
155- let self_pos_kind = create_self_position_kind ( tcx, def_id, sig_id) ;
167+ let self_pos_kind = create_self_param_position_kind ( tcx, def_id, sig_id) ;
156168 let is_self_at_zero = matches ! ( self_pos_kind, SelfPositionKind :: Zero ) ;
157169
158170 // Is self at zero? If so insert mapping, self in sig parent is always at 0.
@@ -215,30 +227,24 @@ fn create_mapping<'tcx>(
215227
216228fn get_delegation_parent_args_count_without_self < ' tcx > (
217229 tcx : TyCtxt < ' tcx > ,
218- delegation_id : LocalDefId ,
230+ def_id : LocalDefId ,
219231 sig_id : DefId ,
220232) -> usize {
221- let delegation_parent_args_count = tcx . generics_of ( delegation_id ) . parent_count ;
233+ let kinds @ ( def_kind , _ ) = fn_kinds ( tcx , def_id , sig_id ) ;
222234
223- match ( fn_kind ( tcx, delegation_id) , fn_kind ( tcx, sig_id) ) {
224- ( FnKind :: Free , FnKind :: Free )
225- | ( FnKind :: Free , FnKind :: AssocTrait )
226- | ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait ) => 0 ,
235+ match kinds {
236+ ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait ) => 0 ,
227237
228- ( FnKind :: AssocInherentImpl , FnKind :: Free )
229- | ( FnKind :: AssocInherentImpl , FnKind :: AssocTrait ) => {
230- delegation_parent_args_count /* No Self in AssocInherentImpl */
231- }
238+ ( FnKind :: AssocTraitImpl , _) | ( _, FnKind :: AssocTraitImpl ) => unreachable ! ( ) ,
232239
233- ( FnKind :: AssocTrait , FnKind :: Free ) | ( FnKind :: AssocTrait , FnKind :: AssocTrait ) => {
234- delegation_parent_args_count - 1 /* Without Self */
235- }
240+ ( FnKind :: Free , _) => 0 ,
236241
237- // For trait impl's `sig_id` is always equal to the corresponding trait method.
238- // For inherent methods delegation is not yet supported.
239- ( FnKind :: AssocTraitImpl , _)
240- | ( _, FnKind :: AssocTraitImpl )
241- | ( _, FnKind :: AssocInherentImpl ) => unreachable ! ( ) ,
242+ ( _, _) => {
243+ let delegation_parent_args_count = tcx. generics_of ( def_id) . parent_count ;
244+ let has_self = def_kind == FnKind :: AssocTrait ;
245+
246+ delegation_parent_args_count - usize:: from ( has_self)
247+ }
242248 }
243249}
244250
@@ -247,75 +253,57 @@ fn get_parent_and_inheritance_kind<'tcx>(
247253 def_id : LocalDefId ,
248254 sig_id : DefId ,
249255) -> ( Option < DefId > , InheritanceKind ) {
250- match ( fn_kind ( tcx, def_id) , fn_kind ( tcx, sig_id) ) {
251- ( FnKind :: Free , FnKind :: Free ) | ( FnKind :: Free , FnKind :: AssocTrait ) => {
252- ( None , InheritanceKind :: WithParent ( true ) )
253- }
256+ let kinds @ ( _, sig_kind) = fn_kinds ( tcx, def_id, sig_id) ;
254257
258+ match kinds {
255259 ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait ) => {
256260 ( Some ( tcx. parent ( def_id. to_def_id ( ) ) ) , InheritanceKind :: Own )
257261 }
258262
259- ( FnKind :: AssocInherentImpl , FnKind :: AssocTrait )
260- | ( FnKind :: AssocTrait , FnKind :: AssocTrait )
261- | ( FnKind :: AssocInherentImpl , FnKind :: Free )
262- | ( FnKind :: AssocTrait , FnKind :: Free ) => {
263- ( Some ( tcx . parent ( def_id . to_def_id ( ) ) ) , InheritanceKind :: WithParent ( false ) )
263+ ( FnKind :: AssocTraitImpl , _ ) | ( _ , FnKind :: AssocTraitImpl ) => unreachable ! ( ) ,
264+
265+ ( FnKind :: Free , _ ) => {
266+ let copy_self_clauses = sig_kind == FnKind :: AssocTrait ;
267+ ( None , InheritanceKind :: WithParent ( copy_self_clauses ) )
264268 }
265269
266- // For trait impl's `sig_id` is always equal to the corresponding trait method.
267- // For inherent methods delegation is not yet supported.
268- ( FnKind :: AssocTraitImpl , _)
269- | ( _, FnKind :: AssocTraitImpl )
270- | ( _, FnKind :: AssocInherentImpl ) => unreachable ! ( ) ,
270+ ( _, _) => ( Some ( tcx. parent ( def_id. to_def_id ( ) ) ) , InheritanceKind :: WithParent ( false ) ) ,
271271 }
272272}
273273
274- fn get_delegation_self_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , delegation_id : LocalDefId ) -> Option < Ty < ' tcx > > {
275- let sig_id = tcx. hir_opt_delegation_sig_id ( delegation_id ) . expect ( "Delegation must have sig_id " ) ;
276- let ( caller_kind, callee_kind) = ( fn_kind ( tcx, delegation_id ) , fn_kind ( tcx , sig_id) ) ;
274+ fn get_delegation_self_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId ) -> Option < Ty < ' tcx > > {
275+ let sig_id = tcx. hir_opt_delegation_sig_id ( def_id ) . expect ( "processing delegation " ) ;
276+ let ( caller_kind, callee_kind) = fn_kinds ( tcx, def_id , sig_id) ;
277277
278278 match ( caller_kind, callee_kind) {
279- ( FnKind :: Free , FnKind :: AssocTrait )
280- | ( FnKind :: AssocInherentImpl , FnKind :: Free )
281- | ( FnKind :: Free , FnKind :: Free )
282- | ( FnKind :: AssocTrait , FnKind :: Free )
283- | ( FnKind :: AssocTrait , FnKind :: AssocTrait ) => {
284- match create_self_position_kind ( tcx, delegation_id, sig_id) {
285- SelfPositionKind :: None => None ,
286- SelfPositionKind :: AfterLifetimes ( propagation_kind) => {
287- Some ( match propagation_kind {
288- Some ( kind) => match kind {
289- DelegationSelfTyPropagationKind :: SelfTy ( self_ty_id) => {
290- let ctx = ItemCtxt :: new ( tcx, delegation_id) ;
291- ctx. lower_ty ( tcx. hir_node ( self_ty_id) . expect_ty ( ) )
292- }
293- DelegationSelfTyPropagationKind :: SelfParam => {
294- let index = tcx. generics_of ( delegation_id) . own_counts ( ) . lifetimes ;
295- Ty :: new_param ( tcx, index as u32 , kw:: SelfUpper )
296- }
297- } ,
298- None => Ty :: new_error_with_message (
299- tcx,
300- tcx. def_span ( delegation_id) ,
301- "self propagation kind must be specified for `AfterLifetimes` variant" ,
302- ) ,
303- } )
304- }
305- SelfPositionKind :: Zero => Some ( Ty :: new_param ( tcx, 0 , kw:: SelfUpper ) ) ,
306- }
279+ ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait ) | ( FnKind :: AssocInherentImpl , _) => {
280+ Some ( tcx. type_of ( tcx. local_parent ( def_id) ) . instantiate_identity ( ) . skip_norm_wip ( ) )
307281 }
308282
309- ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait )
310- | ( FnKind :: AssocInherentImpl , FnKind :: AssocTrait ) => Some (
311- tcx. type_of ( tcx. local_parent ( delegation_id) ) . instantiate_identity ( ) . skip_norm_wip ( ) ,
312- ) ,
313-
314283 // For trait impl's `sig_id` is always equal to the corresponding trait method.
315- // For inherent methods delegation is not yet supported.
316- ( FnKind :: AssocTraitImpl , _)
317- | ( _, FnKind :: AssocTraitImpl )
318- | ( _, FnKind :: AssocInherentImpl ) => unreachable ! ( ) ,
284+ ( FnKind :: AssocTraitImpl , _) | ( _, FnKind :: AssocTraitImpl ) => unreachable ! ( ) ,
285+
286+ ( _, _) => match create_self_param_position_kind ( tcx, def_id, sig_id) {
287+ SelfPositionKind :: None => None ,
288+ SelfPositionKind :: AfterLifetimes ( propagation_kind) => Some ( match propagation_kind {
289+ Some ( kind) => match kind {
290+ DelegationSelfTyPropagationKind :: SelfTy ( self_ty_id) => {
291+ let ctx = ItemCtxt :: new ( tcx, def_id) ;
292+ ctx. lower_ty ( tcx. hir_node ( self_ty_id) . expect_ty ( ) )
293+ }
294+ DelegationSelfTyPropagationKind :: SelfParam => {
295+ let index = tcx. generics_of ( def_id) . own_counts ( ) . lifetimes ;
296+ Ty :: new_param ( tcx, index as u32 , kw:: SelfUpper )
297+ }
298+ } ,
299+ None => Ty :: new_error_with_message (
300+ tcx,
301+ tcx. def_span ( def_id) ,
302+ "self propagation kind must be specified for `AfterLifetimes` variant" ,
303+ ) ,
304+ } ) ,
305+ SelfPositionKind :: Zero => Some ( Ty :: new_param ( tcx, 0 , kw:: SelfUpper ) ) ,
306+ } ,
319307 }
320308}
321309
@@ -337,12 +325,12 @@ fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) ->
337325fn create_generic_args < ' tcx > (
338326 tcx : TyCtxt < ' tcx > ,
339327 sig_id : DefId ,
340- delegation_id : LocalDefId ,
328+ def_id : LocalDefId ,
341329 mut parent_args : & [ ty:: GenericArg < ' tcx > ] ,
342330 mut child_args : & [ ty:: GenericArg < ' tcx > ] ,
343331) -> ( Vec < ty:: GenericArg < ' tcx > > , & ' tcx [ ty:: GenericArg < ' tcx > ] ) {
344- let delegation_generics = tcx. generics_of ( delegation_id ) ;
345- let delegation_args = ty:: GenericArgs :: identity_for_item ( tcx, delegation_id ) ;
332+ let delegation_generics = tcx. generics_of ( def_id ) ;
333+ let delegation_args = ty:: GenericArgs :: identity_for_item ( tcx, def_id ) ;
346334
347335 let real_args_count = delegation_args. len ( ) - delegation_generics. own_synthetic_params_count ( ) ;
348336 let synth_args = & delegation_args[ real_args_count..] ;
@@ -352,12 +340,12 @@ fn create_generic_args<'tcx>(
352340
353341 let delegation_args = & delegation_args[ delegation_generics. parent_count ..] ;
354342
355- let kinds = ( fn_kind ( tcx, delegation_id ) , fn_kind ( tcx , sig_id) ) ;
343+ let kinds = fn_kinds ( tcx, def_id , sig_id) ;
356344 if matches ! ( kinds, ( FnKind :: AssocTraitImpl , FnKind :: AssocTrait ) ) {
357345 // Special case, as user specifies Trait args in trait impl header, we want to treat
358346 // them as parent args. We always generate a function whose generics match
359347 // child generics in trait.
360- let parent = tcx. local_parent ( delegation_id ) ;
348+ let parent = tcx. local_parent ( def_id ) ;
361349
362350 parent_args =
363351 tcx. impl_trait_header ( parent) . trait_ref . instantiate_identity ( ) . skip_norm_wip ( ) . args ;
@@ -368,7 +356,7 @@ fn create_generic_args<'tcx>(
368356 delegation_parent_args = & [ ] ;
369357 }
370358
371- let self_type = get_delegation_self_ty ( tcx, delegation_id ) . map ( |t| t . into ( ) ) ;
359+ let self_type = get_delegation_self_ty ( tcx, def_id ) . map ( ty :: GenericArg :: from ) ;
372360
373361 // Remove `Self` from parent args (it is always at the `0th` index) as it is
374362 // added manually.
@@ -377,7 +365,7 @@ fn create_generic_args<'tcx>(
377365 }
378366
379367 let ( zero_self, after_lifetimes_self) =
380- match create_self_position_kind ( tcx, delegation_id , sig_id) {
368+ match create_self_param_position_kind ( tcx, def_id , sig_id) {
381369 SelfPositionKind :: AfterLifetimes ( _) => {
382370 assert ! ( self_type. is_some( ) ) ;
383371 ( None , self_type)
@@ -505,7 +493,7 @@ pub(crate) fn inherit_clauses_for_delegation_item<'tcx>(
505493
506494 let ( parent_args, child_args) = tcx. delegation_user_specified_args ( def_id) ;
507495 let ( folder, args) = create_folder_and_args ( tcx, def_id, sig_id, parent_args, child_args) ;
508- let self_pos_kind = create_self_position_kind ( tcx, def_id, sig_id) ;
496+ let self_pos_kind = create_self_param_position_kind ( tcx, def_id, sig_id) ;
509497 let filter_self_clauses = matches ! (
510498 self_pos_kind,
511499 SelfPositionKind :: AfterLifetimes ( Some ( DelegationSelfTyPropagationKind :: SelfTy ( ..) ) )
@@ -584,7 +572,6 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
584572) -> & ' tcx [ Ty < ' tcx > ] {
585573 let sig_id = tcx. hir_opt_delegation_sig_id ( def_id) . expect ( "Delegation must have sig_id" ) ;
586574 let caller_sig = tcx. fn_sig ( sig_id) ;
587-
588575 if let Err ( err) = check_constraints ( tcx, def_id, sig_id) {
589576 let sig_len = caller_sig. instantiate_identity ( ) . skip_binder ( ) . inputs ( ) . len ( ) + 1 ;
590577 let err_type = Ty :: new_error ( tcx, err) ;
@@ -606,23 +593,24 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
606593// we want to extract [Self, 'static, i32, 1] for parent and [A, B] for child.
607594pub ( crate ) fn delegation_user_specified_args < ' tcx > (
608595 tcx : TyCtxt < ' tcx > ,
609- delegation_id : LocalDefId ,
596+ def_id : LocalDefId ,
610597) -> ( & ' tcx [ ty:: GenericArg < ' tcx > ] , & ' tcx [ ty:: GenericArg < ' tcx > ] ) {
611- let info = tcx. hir_delegation_info ( delegation_id ) ;
598+ let info = tcx. hir_delegation_info ( def_id ) ;
612599
613600 let get_segment = |hir_id| -> Option < ( & ' tcx PathSegment < ' tcx > , DefId ) > {
614601 let segment = tcx. hir_node ( hir_id) . expect_path_segment ( ) ;
615602 segment. res . opt_def_id ( ) . map ( |def_id| ( segment, def_id) )
616603 } ;
617604
618- let ctx = ItemCtxt :: new_for_delegation ( tcx, delegation_id ) ;
605+ let ctx = ItemCtxt :: new_for_delegation ( tcx, def_id ) ;
619606 let lowerer = ctx. lowerer ( ) ;
620607 let parent_args = info
621608 . parent_seg_id_for_sig
622609 . and_then ( get_segment)
623610 . filter ( |( _, def_id) | matches ! ( tcx. def_kind( * def_id) , DefKind :: Trait ) )
624611 . map ( |( segment, def_id) | {
625- let self_ty = get_delegation_self_ty ( tcx, delegation_id) ;
612+ let self_ty = ( tcx. def_kind ( def_id) == DefKind :: Trait )
613+ . then ( || Ty :: new_param ( tcx, 0 , kw:: SelfUpper ) ) ;
626614
627615 lowerer
628616 . lower_generic_args_of_path ( segment. ident . span , def_id, & [ ] , segment, self_ty)
0 commit comments