@@ -168,6 +168,29 @@ enum Scope<'a, 'tcx> {
168168}
169169
170170impl < ' a , ' tcx > Scope < ' a , ' tcx > {
171+ // FIXME(fmease): This is called in a bunch of places that are probably relatively hot.
172+ // Consider tracking this flag as a field in `BoundVarContext` (to be
173+ // updated in `visit_nested_body` but that's a bit ewww)
174+ fn in_body ( & self ) -> bool {
175+ let mut scope = self ;
176+ loop {
177+ match * scope {
178+ Scope :: Root { .. } => return false ,
179+
180+ Scope :: Body { .. } => return true ,
181+
182+ Scope :: Binder { s, .. }
183+ | Scope :: ObjectLifetimeDefault { s, .. }
184+ | Scope :: Opaque { s, .. }
185+ | Scope :: Supertrait { s, .. }
186+ | Scope :: TraitRefBoundary { s, .. }
187+ | Scope :: LateBoundary { s, .. } => {
188+ scope = s;
189+ }
190+ }
191+ }
192+ }
193+
171194 // A helper for debugging scopes without printing parent scopes
172195 fn debug_truncated ( & self ) -> impl fmt:: Debug {
173196 fmt:: from_fn ( move |f| match self {
@@ -809,11 +832,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
809832 }
810833 hir:: TyKind :: Ref ( lifetime_ref, ref mt) => {
811834 self . visit_lifetime ( lifetime_ref) ;
812- let scope = Scope :: ObjectLifetimeDefault {
813- lifetime : self . rbv . defs . get ( & lifetime_ref. hir_id . local_id ) . cloned ( ) ,
814- s : self . scope ,
815- } ;
816- self . with ( scope, |this| this. visit_ty_unambig ( mt. ty ) ) ;
835+
836+ // NOTE(fmease): Likely hot.
837+ self . maybe_with_object_lifetime_default (
838+ |this| this. rbv . defs . get ( & lifetime_ref. hir_id . local_id ) . cloned ( ) ,
839+ |this| this. visit_ty_unambig ( mt. ty ) ,
840+ ) ;
817841 }
818842 hir:: TyKind :: TraitAscription ( bounds) => {
819843 let scope = Scope :: TraitRefBoundary { s : self . scope } ;
@@ -1121,6 +1145,21 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11211145 * self . opaque_capture_errors . borrow_mut ( ) = this. opaque_capture_errors . into_inner ( ) ;
11221146 }
11231147
1148+ // FIXME(fmease): Temporary.
1149+ fn maybe_with_object_lifetime_default < L , F > ( & mut self , lifetime : L , f : F )
1150+ where
1151+ L : FnOnce ( & mut Self ) -> Option < ResolvedArg > ,
1152+ F : for < ' b > FnOnce ( & mut BoundVarContext < ' b , ' tcx > ) ,
1153+ {
1154+ if !self . scope . in_body ( ) {
1155+ let lifetime = lifetime ( self ) ;
1156+ let scope = Scope :: ObjectLifetimeDefault { lifetime, s : self . scope } ;
1157+ self . with ( scope, f)
1158+ } else {
1159+ f ( self ) ;
1160+ }
1161+ }
1162+
11241163 fn record_late_bound_vars ( & mut self , hir_id : HirId , binder : Vec < ty:: BoundVariableKind < ' tcx > > ) {
11251164 if let Some ( old) = self . rbv . late_bound_vars . insert ( hir_id. local_id , binder) {
11261165 bug ! (
@@ -1722,25 +1761,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
17221761 // vector like `['x, 'static]`. Note that the vector only
17231762 // includes type parameters.
17241763 let object_lifetime_defaults = type_def_id. map_or_else ( Vec :: new, |def_id| {
1725- let in_body = {
1726- let mut scope = self . scope ;
1727- loop {
1728- match * scope {
1729- Scope :: Root { .. } => break false ,
1730-
1731- Scope :: Body { .. } => break true ,
1732-
1733- Scope :: Binder { s, .. }
1734- | Scope :: ObjectLifetimeDefault { s, .. }
1735- | Scope :: Opaque { s, .. }
1736- | Scope :: Supertrait { s, .. }
1737- | Scope :: TraitRefBoundary { s, .. }
1738- | Scope :: LateBoundary { s, .. } => {
1739- scope = s;
1740- }
1741- }
1742- }
1743- } ;
1764+ if self . scope . in_body ( ) {
1765+ return Vec :: new ( ) ;
1766+ }
17441767
17451768 let rbv = & self . rbv ;
17461769 let generics = self . tcx . generics_of ( def_id) ;
@@ -1749,14 +1772,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
17491772 debug_assert_eq ! ( generics. parent_count, 0 ) ;
17501773
17511774 let set_to_region = |set : ObjectLifetimeDefault | match set {
1752- ObjectLifetimeDefault :: Empty => {
1753- if in_body {
1754- None
1755- } else {
1756- Some ( ResolvedArg :: StaticLifetime )
1757- }
1775+ ObjectLifetimeDefault :: Empty | ObjectLifetimeDefault :: Static => {
1776+ Some ( ResolvedArg :: StaticLifetime )
17581777 }
1759- ObjectLifetimeDefault :: Static => Some ( ResolvedArg :: StaticLifetime ) ,
17601778 ObjectLifetimeDefault :: Param ( param_def_id) => {
17611779 // This index can be used with `generic_args` since `parent_count == 0`.
17621780 let index = generics. param_def_id_to_index [ & param_def_id] as usize ;
@@ -1844,13 +1862,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
18441862 // Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or
18451863 // in the trait ref `YY<...>` in `Item: YY<...>`.
18461864 for constraint in generic_args. constraints {
1847- let scope = Scope :: ObjectLifetimeDefault {
1848- lifetime : if has_lifetime_parameter {
1849- None
1850- } else {
1851- Some ( ResolvedArg :: StaticLifetime )
1852- } ,
1853- s : self . scope ,
1865+ let lifetime = |_: & mut _ | {
1866+ if has_lifetime_parameter { None } else { Some ( ResolvedArg :: StaticLifetime ) }
18541867 } ;
18551868 // If the args are parenthesized, then this must be `feature(return_type_notation)`.
18561869 // In that case, introduce a binder over all of the function's early and late bound vars.
@@ -1892,7 +1905,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
18921905 . span_delayed_bug ( constraint. ident . span , "bad return type notation here" ) ;
18931906 vec ! [ ]
18941907 } ;
1895- self . with ( scope , |this| {
1908+ self . maybe_with_object_lifetime_default ( lifetime , |this| {
18961909 let scope = Scope :: Supertrait { bound_vars, s : this. scope } ;
18971910 this. with ( scope, |this| {
18981911 let ( bound_vars, _) = this. poly_trait_ref_binder_info ( ) ;
@@ -1908,15 +1921,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
19081921 ty:: AssocTag :: Type ,
19091922 )
19101923 . map ( |( bound_vars, _) | bound_vars) ;
1911- self . with ( scope , |this| {
1924+ self . maybe_with_object_lifetime_default ( lifetime , |this| {
19121925 let scope = Scope :: Supertrait {
19131926 bound_vars : bound_vars. unwrap_or_default ( ) ,
19141927 s : this. scope ,
19151928 } ;
19161929 this. with ( scope, |this| this. visit_assoc_item_constraint ( constraint) ) ;
19171930 } ) ;
19181931 } else {
1919- self . with ( scope, |this| this. visit_assoc_item_constraint ( constraint) ) ;
1932+ self . maybe_with_object_lifetime_default ( lifetime, |this| {
1933+ this. visit_assoc_item_constraint ( constraint)
1934+ } ) ;
19201935 }
19211936 }
19221937 }
@@ -1995,11 +2010,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
19952010 output : Option < & ' tcx hir:: Ty < ' tcx > > ,
19962011 in_closure : bool ,
19972012 ) {
1998- self . with (
1999- Scope :: ObjectLifetimeDefault {
2000- lifetime : Some ( ResolvedArg :: StaticLifetime ) ,
2001- s : self . scope ,
2002- } ,
2013+ self . maybe_with_object_lifetime_default (
2014+ |_| Some ( ResolvedArg :: StaticLifetime ) ,
20032015 |this| {
20042016 for input in inputs {
20052017 this. visit_ty_unambig ( input) ;
@@ -2009,6 +2021,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
20092021 }
20102022 } ,
20112023 ) ;
2024+
20122025 if in_closure && let Some ( output) = output {
20132026 self . visit_ty_unambig ( output) ;
20142027 }
0 commit comments