@@ -2117,48 +2117,77 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2117
2117
// First (determined here), if `self` is by-reference, then the
2118
2118
// implied output region is the region of the self parameter.
2119
2119
if has_self {
2120
- // Look for `self: &'a Self` - also desugared from `&'a self`,
2121
- // and if that matches, use it for elision and return early.
2122
- let is_self_ty = |res : Res | {
2123
- if let Res :: SelfTy ( ..) = res {
2124
- return true ;
2125
- }
2126
-
2127
- // Can't always rely on literal (or implied) `Self` due
2128
- // to the way elision rules were originally specified.
2129
- let impl_self = impl_self. map ( |ty| & ty. node ) ;
2130
- if let Some ( & hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , ref path) ) ) = impl_self {
2131
- match path. res {
2132
- // Whitelist the types that unambiguously always
2133
- // result in the same type constructor being used
2134
- // (it can't differ between `Self` and `self`).
2135
- Res :: Def ( DefKind :: Struct , _)
2136
- | Res :: Def ( DefKind :: Union , _)
2137
- | Res :: Def ( DefKind :: Enum , _)
2138
- | Res :: PrimTy ( _) => {
2139
- return res == path. res
2120
+ struct SelfVisitor < ' a > {
2121
+ map : & ' a NamedRegionMap ,
2122
+ impl_self : Option < & ' a hir:: TyKind > ,
2123
+ lifetime : Set1 < Region > ,
2124
+ }
2125
+
2126
+ impl SelfVisitor < ' _ > {
2127
+ // Look for `self: &'a Self` - also desugared from `&'a self`,
2128
+ // and if that matches, use it for elision and return early.
2129
+ fn is_self_ty ( & self , res : Res ) -> bool {
2130
+ if let Res :: SelfTy ( ..) = res {
2131
+ return true ;
2132
+ }
2133
+
2134
+ // Can't always rely on literal (or implied) `Self` due
2135
+ // to the way elision rules were originally specified.
2136
+ if let Some ( & hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , ref path) ) ) =
2137
+ self . impl_self
2138
+ {
2139
+ match path. res {
2140
+ // Whitelist the types that unambiguously always
2141
+ // result in the same type constructor being used
2142
+ // (it can't differ between `Self` and `self`).
2143
+ Res :: Def ( DefKind :: Struct , _)
2144
+ | Res :: Def ( DefKind :: Union , _)
2145
+ | Res :: Def ( DefKind :: Enum , _)
2146
+ | Res :: PrimTy ( _) => {
2147
+ return res == path. res
2148
+ }
2149
+ _ => { }
2140
2150
}
2141
- _ => { }
2142
2151
}
2152
+
2153
+ false
2143
2154
}
2155
+ }
2144
2156
2145
- false
2146
- } ;
2157
+ impl < ' a > Visitor < ' a > for SelfVisitor < ' a > {
2158
+ fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' a > {
2159
+ NestedVisitorMap :: None
2160
+ }
2147
2161
2148
- if let hir:: TyKind :: Rptr ( lifetime_ref, ref mt) = inputs[ 0 ] . node {
2149
- if let hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , ref path) ) = mt. ty . node {
2150
- if is_self_ty ( path. res ) {
2151
- if let Some ( & lifetime) = self . map . defs . get ( & lifetime_ref. hir_id ) {
2152
- let scope = Scope :: Elision {
2153
- elide : Elide :: Exact ( lifetime) ,
2154
- s : self . scope ,
2155
- } ;
2156
- self . with ( scope, |_, this| this. visit_ty ( output) ) ;
2157
- return ;
2162
+ fn visit_ty ( & mut self , ty : & ' a hir:: Ty ) {
2163
+ if let hir:: TyKind :: Rptr ( lifetime_ref, ref mt) = ty. node {
2164
+ if let hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , ref path) ) = mt. ty . node
2165
+ {
2166
+ if self . is_self_ty ( path. res ) {
2167
+ if let Some ( lifetime) = self . map . defs . get ( & lifetime_ref. hir_id ) {
2168
+ self . lifetime . insert ( * lifetime) ;
2169
+ }
2170
+ }
2158
2171
}
2159
2172
}
2173
+ intravisit:: walk_ty ( self , ty)
2160
2174
}
2161
2175
}
2176
+
2177
+ let mut visitor = SelfVisitor {
2178
+ map : self . map ,
2179
+ impl_self : impl_self. map ( |ty| & ty. node ) ,
2180
+ lifetime : Set1 :: Empty ,
2181
+ } ;
2182
+ visitor. visit_ty ( & inputs[ 0 ] ) ;
2183
+ if let Set1 :: One ( lifetime) = visitor. lifetime {
2184
+ let scope = Scope :: Elision {
2185
+ elide : Elide :: Exact ( lifetime) ,
2186
+ s : self . scope ,
2187
+ } ;
2188
+ self . with ( scope, |_, this| this. visit_ty ( output) ) ;
2189
+ return ;
2190
+ }
2162
2191
}
2163
2192
2164
2193
// Second, if there was exactly one lifetime (either a substitution or a
0 commit comments