@@ -64,6 +64,7 @@ fn check_fn_for_unconditional_recursion<'tcx>(
6464 | TerminatorKind :: Abort
6565 | TerminatorKind :: Return
6666 | TerminatorKind :: Unreachable => {
67+ // We propagate backwards, so these should never be encountered here.
6768 unreachable ! ( "unexpected terminator {:?}" , terminator. kind)
6869 }
6970 } ;
@@ -118,13 +119,15 @@ fn find_blocks_calling_self<'tcx>(
118119 def_id : DefId ,
119120) -> BitSet < BasicBlock > {
120121 let param_env = tcx. param_env ( def_id) ;
122+
123+ // If this is trait/impl method, extract the trait's substs.
121124 let trait_substs_count = match tcx. opt_associated_item ( def_id) {
122125 Some ( AssocItem { container : AssocItemContainer :: TraitContainer ( trait_def_id) , .. } ) => {
123126 tcx. generics_of ( trait_def_id) . count ( )
124127 }
125128 _ => 0 ,
126129 } ;
127- let caller_substs = & InternalSubsts :: identity_for_item ( tcx, def_id) [ ..trait_substs_count] ;
130+ let trait_substs = & InternalSubsts :: identity_for_item ( tcx, def_id) [ ..trait_substs_count] ;
128131
129132 let mut self_calls = BitSet :: new_empty ( body. basic_blocks ( ) . len ( ) ) ;
130133
@@ -142,8 +145,12 @@ fn find_blocks_calling_self<'tcx>(
142145
143146 // FIXME(#57965): Make this work across function boundaries
144147
148+ // If this is a trait fn, the substs on the trait have to match, or we might be
149+ // calling into an entirely different method (for example, a call from the default
150+ // method in the trait to `<A as Trait<B>>::method`, where `A` and/or `B` are
151+ // specific types).
145152 let is_self_call =
146- call_fn_id == def_id && & call_substs[ ..caller_substs . len ( ) ] == caller_substs ;
153+ call_fn_id == def_id && & call_substs[ ..trait_substs . len ( ) ] == trait_substs ;
147154
148155 if is_self_call {
149156 self_calls. insert ( bb) ;
0 commit comments