@@ -2205,16 +2205,55 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
22052205
22062206 /// List all the lifetimes that appear in the provided type.
22072207 fn find_lifetime_for_self ( & self , ty : & ' ast Ty ) -> Set1 < LifetimeRes > {
2208- struct SelfVisitor < ' r , ' a , ' tcx > {
2208+ /// Visits a type to find all the &references, and determines the
2209+ /// set of lifetimes for all of those references where the referent
2210+ /// contains Self.
2211+ struct FindReferenceVisitor < ' r , ' a , ' tcx > {
22092212 r : & ' r Resolver < ' a , ' tcx > ,
22102213 impl_self : Option < Res > ,
22112214 lifetime : Set1 < LifetimeRes > ,
2215+ }
2216+
2217+ impl < ' a > Visitor < ' a > for FindReferenceVisitor < ' _ , ' _ , ' _ > {
2218+ fn visit_ty ( & mut self , ty : & ' a Ty ) {
2219+ trace ! ( "FindReferenceVisitor considering ty={:?}" , ty) ;
2220+ if let TyKind :: Ref ( lt, _) = ty. kind {
2221+ // See if anything inside the &thing contains Self
2222+ let mut visitor =
2223+ SelfVisitor { r : self . r , impl_self : self . impl_self , self_found : false } ;
2224+ visitor. visit_ty ( ty) ;
2225+ trace ! ( "FindReferenceVisitor: SelfVisitor self_found={:?}" , visitor. self_found) ;
2226+ if visitor. self_found {
2227+ let lt_id = if let Some ( lt) = lt {
2228+ lt. id
2229+ } else {
2230+ let res = self . r . lifetimes_res_map [ & ty. id ] ;
2231+ let LifetimeRes :: ElidedAnchor { start, .. } = res else { bug ! ( ) } ;
2232+ start
2233+ } ;
2234+ let lt_res = self . r . lifetimes_res_map [ & lt_id] ;
2235+ trace ! ( "FindReferenceVisitor inserting res={:?}" , lt_res) ;
2236+ self . lifetime . insert ( lt_res) ;
2237+ }
2238+ }
2239+ visit:: walk_ty ( self , ty)
2240+ }
2241+
2242+ // A type may have an expression as a const generic argument.
2243+ // We do not want to recurse into those.
2244+ fn visit_expr ( & mut self , _: & ' a Expr ) { }
2245+ }
2246+
2247+ /// Visitor which checks the referent of a &Thing to see if the
2248+ /// Thing contains Self
2249+ struct SelfVisitor < ' r , ' a , ' tcx > {
2250+ r : & ' r Resolver < ' a , ' tcx > ,
2251+ impl_self : Option < Res > ,
22122252 self_found : bool ,
22132253 }
22142254
22152255 impl SelfVisitor < ' _ , ' _ , ' _ > {
2216- // Look for `self: &'a Self` - also desugared from `&'a self`,
2217- // and if that matches, use it for elision and return early.
2256+ // Look for `self: &'a Self` - also desugared from `&'a self`
22182257 fn is_self_ty ( & self , ty : & Ty ) -> bool {
22192258 match ty. kind {
22202259 TyKind :: ImplicitSelf => true ,
@@ -2237,18 +2276,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
22372276 trace ! ( "SelfVisitor found Self" ) ;
22382277 self . self_found = true ;
22392278 }
2240- if let TyKind :: Ref ( lt, _) = ty. kind {
2241- let lt_id = if let Some ( lt) = lt {
2242- lt. id
2243- } else {
2244- let res = self . r . lifetimes_res_map [ & ty. id ] ;
2245- let LifetimeRes :: ElidedAnchor { start, .. } = res else { bug ! ( ) } ;
2246- start
2247- } ;
2248- let lt_res = self . r . lifetimes_res_map [ & lt_id] ;
2249- trace ! ( "SelfVisitor inserting res={:?}" , lt_res) ;
2250- self . lifetime . insert ( lt_res) ;
2251- }
22522279 visit:: walk_ty ( self , ty)
22532280 }
22542281
@@ -2278,11 +2305,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
22782305 Res :: Def ( DefKind :: Struct | DefKind :: Union | DefKind :: Enum , _, ) | Res :: PrimTy ( _)
22792306 )
22802307 } ) ;
2281- let mut visitor =
2282- SelfVisitor { r : self . r , impl_self, lifetime : Set1 :: Empty , self_found : false } ;
2308+ let mut visitor = FindReferenceVisitor { r : self . r , impl_self, lifetime : Set1 :: Empty } ;
22832309 visitor. visit_ty ( ty) ;
2284- trace ! ( "SelfVisitor found={:?}, self_found={:?} " , visitor. lifetime, visitor . self_found ) ;
2285- if visitor. self_found { visitor . lifetime } else { Set1 :: Empty }
2310+ trace ! ( "FindReferenceVisitor found={:?}" , visitor. lifetime) ;
2311+ visitor. lifetime
22862312 }
22872313
22882314 /// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
0 commit comments