@@ -57,6 +57,49 @@ impl<'tcx> InferCtxt<'tcx> {
57
57
self . tcx . replace_bound_vars_uncached ( binder, delegate)
58
58
}
59
59
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
+
60
103
/// Replaces all bound variables (lifetimes, types, and constants) bound by
61
104
/// `binder` with placeholder variables in a new universe and then calls the
62
105
/// closure `f` with the instantiated value. The new placeholders can only be
@@ -82,6 +125,26 @@ impl<'tcx> InferCtxt<'tcx> {
82
125
f ( value)
83
126
}
84
127
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
+
85
148
/// See [RegionConstraintCollector::leak_check][1]. We only check placeholder
86
149
/// leaking into `outer_universe`, i.e. placeholders which cannot be named by that
87
150
/// universe.
0 commit comments