@@ -2162,16 +2162,55 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
21622162
21632163 /// List all the lifetimes that appear in the provided type.
21642164 fn find_lifetime_for_self ( & self , ty : & ' ast Ty ) -> Set1 < LifetimeRes > {
2165- struct SelfVisitor < ' r , ' a , ' tcx > {
2165+ /// Visits a type to find all the &references, and determines the
2166+ /// set of lifetimes for all of those references where the referent
2167+ /// contains Self.
2168+ struct FindReferenceVisitor < ' r , ' a , ' tcx > {
21662169 r : & ' r Resolver < ' a , ' tcx > ,
21672170 impl_self : Option < Res > ,
21682171 lifetime : Set1 < LifetimeRes > ,
2172+ }
2173+
2174+ impl < ' a > Visitor < ' a > for FindReferenceVisitor < ' _ , ' _ , ' _ > {
2175+ fn visit_ty ( & mut self , ty : & ' a Ty ) {
2176+ trace ! ( "FindReferenceVisitor considering ty={:?}" , ty) ;
2177+ if let TyKind :: Ref ( lt, _) = ty. kind {
2178+ // See if anything inside the &thing contains Self
2179+ let mut visitor =
2180+ SelfVisitor { r : self . r , impl_self : self . impl_self , self_found : false } ;
2181+ visitor. visit_ty ( ty) ;
2182+ trace ! ( "FindReferenceVisitor: SelfVisitor self_found={:?}" , visitor. self_found) ;
2183+ if visitor. self_found {
2184+ let lt_id = if let Some ( lt) = lt {
2185+ lt. id
2186+ } else {
2187+ let res = self . r . lifetimes_res_map [ & ty. id ] ;
2188+ let LifetimeRes :: ElidedAnchor { start, .. } = res else { bug ! ( ) } ;
2189+ start
2190+ } ;
2191+ let lt_res = self . r . lifetimes_res_map [ & lt_id] ;
2192+ trace ! ( "FindReferenceVisitor inserting res={:?}" , lt_res) ;
2193+ self . lifetime . insert ( lt_res) ;
2194+ }
2195+ }
2196+ visit:: walk_ty ( self , ty)
2197+ }
2198+
2199+ // A type may have an expression as a const generic argument.
2200+ // We do not want to recurse into those.
2201+ fn visit_expr ( & mut self , _: & ' a Expr ) { }
2202+ }
2203+
2204+ /// Visitor which checks the referent of a &Thing to see if the
2205+ /// Thing contains Self
2206+ struct SelfVisitor < ' r , ' a , ' tcx > {
2207+ r : & ' r Resolver < ' a , ' tcx > ,
2208+ impl_self : Option < Res > ,
21692209 self_found : bool ,
21702210 }
21712211
21722212 impl SelfVisitor < ' _ , ' _ , ' _ > {
2173- // Look for `self: &'a Self` - also desugared from `&'a self`,
2174- // and if that matches, use it for elision and return early.
2213+ // Look for `self: &'a Self` - also desugared from `&'a self`
21752214 fn is_self_ty ( & self , ty : & Ty ) -> bool {
21762215 match ty. kind {
21772216 TyKind :: ImplicitSelf => true ,
@@ -2194,18 +2233,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
21942233 trace ! ( "SelfVisitor found Self" ) ;
21952234 self . self_found = true ;
21962235 }
2197- if let TyKind :: Ref ( lt, _) = ty. kind {
2198- let lt_id = if let Some ( lt) = lt {
2199- lt. id
2200- } else {
2201- let res = self . r . lifetimes_res_map [ & ty. id ] ;
2202- let LifetimeRes :: ElidedAnchor { start, .. } = res else { bug ! ( ) } ;
2203- start
2204- } ;
2205- let lt_res = self . r . lifetimes_res_map [ & lt_id] ;
2206- trace ! ( "SelfVisitor inserting res={:?}" , lt_res) ;
2207- self . lifetime . insert ( lt_res) ;
2208- }
22092236 visit:: walk_ty ( self , ty)
22102237 }
22112238
@@ -2235,11 +2262,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
22352262 Res :: Def ( DefKind :: Struct | DefKind :: Union | DefKind :: Enum , _, ) | Res :: PrimTy ( _)
22362263 )
22372264 } ) ;
2238- let mut visitor =
2239- SelfVisitor { r : self . r , impl_self, lifetime : Set1 :: Empty , self_found : false } ;
2265+ let mut visitor = FindReferenceVisitor { r : self . r , impl_self, lifetime : Set1 :: Empty } ;
22402266 visitor. visit_ty ( ty) ;
2241- trace ! ( "SelfVisitor found={:?}, self_found={:?} " , visitor. lifetime, visitor . self_found ) ;
2242- if visitor. self_found { visitor . lifetime } else { Set1 :: Empty }
2267+ trace ! ( "FindReferenceVisitor found={:?}" , visitor. lifetime) ;
2268+ visitor. lifetime
22432269 }
22442270
22452271 /// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
0 commit comments