@@ -57,6 +57,49 @@ impl<'tcx> InferCtxt<'tcx> {
5757 self . tcx . replace_bound_vars_uncached ( binder, delegate)
5858 }
5959
60+ pub fn enter_forall_with_assumptions_and_leak_universe < T > (
61+ & self ,
62+ binder : ty:: Binder < ' tcx , T > ,
63+ param_env : ty:: ParamEnv < ' tcx > ,
64+ ) -> ( T , ty:: ParamEnv < ' tcx > )
65+ where
66+ T : TypeFoldable < TyCtxt < ' tcx > > ,
67+ {
68+ if !binder. as_ref ( ) . skip_binder_with_clauses ( ) . has_escaping_bound_vars ( ) {
69+ let ( value, assumptions) = binder. skip_binder_with_clauses ( ) ;
70+ return ( value, param_env. extend ( self . tcx , assumptions) ) ;
71+ }
72+
73+ let next_universe = self . create_next_universe ( ) ;
74+
75+ // TODO: Deduplicate this with above.
76+ let delegate = FnMutDelegate {
77+ regions : & mut |br : ty:: BoundRegion | {
78+ ty:: Region :: new_placeholder (
79+ self . tcx ,
80+ ty:: PlaceholderRegion { universe : next_universe, bound : br } ,
81+ )
82+ } ,
83+ types : & mut |bound_ty : ty:: BoundTy | {
84+ Ty :: new_placeholder (
85+ self . tcx ,
86+ ty:: PlaceholderType { universe : next_universe, bound : bound_ty } ,
87+ )
88+ } ,
89+ consts : & mut |bound_var : ty:: BoundVar | {
90+ ty:: Const :: new_placeholder (
91+ self . tcx ,
92+ ty:: PlaceholderConst { universe : next_universe, bound : bound_var } ,
93+ )
94+ } ,
95+ } ;
96+
97+ debug ! ( ?next_universe) ;
98+ let ( value, assumptions) =
99+ self . tcx . replace_bound_vars_uncached_with_clauses ( binder, delegate) ;
100+ ( value, param_env. extend ( self . tcx , assumptions) )
101+ }
102+
60103 /// Replaces all bound variables (lifetimes, types, and constants) bound by
61104 /// `binder` with placeholder variables in a new universe and then calls the
62105 /// closure `f` with the instantiated value. The new placeholders can only be
@@ -82,6 +125,26 @@ impl<'tcx> InferCtxt<'tcx> {
82125 f ( value)
83126 }
84127
128+ #[ instrument( level = "debug" , skip( self , f) ) ]
129+ pub fn enter_forall_with_assumptions < T , U > (
130+ & self ,
131+ forall : ty:: Binder < ' tcx , T > ,
132+ param_env : ty:: ParamEnv < ' tcx > ,
133+ f : impl FnOnce ( T , ty:: ParamEnv < ' tcx > ) -> U ,
134+ ) -> U
135+ where
136+ T : TypeFoldable < TyCtxt < ' tcx > > ,
137+ {
138+ // FIXME: currently we do nothing to prevent placeholders with the new universe being
139+ // used after exiting `f`. For example region subtyping can result in outlives constraints
140+ // that name placeholders created in this function. Nested goals from type relations can
141+ // also contain placeholders created by this function.
142+ let ( value, param_env) =
143+ self . enter_forall_with_assumptions_and_leak_universe ( forall, param_env) ;
144+ debug ! ( ?value) ;
145+ f ( value, param_env)
146+ }
147+
85148 /// See [RegionConstraintCollector::leak_check][1]. We only check placeholder
86149 /// leaking into `outer_universe`, i.e. placeholders which cannot be named by that
87150 /// universe.
0 commit comments