@@ -37,10 +37,11 @@ use snapshot::undo_log::InferCtxtUndoLogs;
37
37
use tracing:: { debug, instrument} ;
38
38
use type_variable:: TypeVariableOrigin ;
39
39
40
- use crate :: infer:: region_constraints :: UndoLog ;
40
+ use crate :: infer:: snapshot :: undo_log :: UndoLog ;
41
41
use crate :: infer:: unify_key:: { ConstVariableOrigin , ConstVariableValue , ConstVidKey } ;
42
42
use crate :: traits:: {
43
- self , ObligationCause , ObligationInspector , PredicateObligations , TraitEngine ,
43
+ self , ObligationCause , ObligationInspector , PredicateObligation , PredicateObligations ,
44
+ TraitEngine ,
44
45
} ;
45
46
46
47
pub mod at;
@@ -156,6 +157,12 @@ pub struct InferCtxtInner<'tcx> {
156
157
/// which may cause types to no longer be considered well-formed.
157
158
region_assumptions : Vec < ty:: ArgOutlivesPredicate < ' tcx > > ,
158
159
160
+ /// `-Znext-solver`: Successfully proven goals during HIR typeck which
161
+ /// reference inference variables and get reproven after writeback.
162
+ ///
163
+ /// See the documentation of `InferCtxt::in_hir_typeck` for more details.
164
+ hir_typeck_potentially_region_dependent_goals : Vec < PredicateObligation < ' tcx > > ,
165
+
159
166
/// Caches for opaque type inference.
160
167
opaque_type_storage : OpaqueTypeStorage < ' tcx > ,
161
168
}
@@ -173,6 +180,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
173
180
region_constraint_storage : Some ( Default :: default ( ) ) ,
174
181
region_obligations : Default :: default ( ) ,
175
182
region_assumptions : Default :: default ( ) ,
183
+ hir_typeck_potentially_region_dependent_goals : Default :: default ( ) ,
176
184
opaque_type_storage : Default :: default ( ) ,
177
185
}
178
186
}
@@ -247,24 +255,25 @@ pub struct InferCtxt<'tcx> {
247
255
/// the root universe. Most notably, this is used during HIR typeck as region
248
256
/// solving is left to borrowck instead.
249
257
pub considering_regions : bool ,
250
- /// Whether this inference context is used by HIR typeck. If so, we uniquify regions
251
- /// with `-Znext-solver`. This is necessary as borrowck will start by replacing each
252
- /// occurance of a free region with a unique inference variable so if HIR typeck
253
- /// ends up depending on two regions being equal we'd get unexpected mismatches
254
- /// between HIR typeck and MIR typeck, resulting in an ICE.
258
+ /// `-Znext-solver`: Whether this inference context is used by HIR typeck. If so, we
259
+ /// need to make sure we don't rely on region identity in the trait solver or for
260
+ /// type equality. This is necessary as borrowck starts by replacing each occurrence of a
261
+ /// free region with a unique inference variable so if HIR typeck ends up depending on two
262
+ /// regions being equal we'd get unexpected mismatches between HIR typeck and MIR typeck,
263
+ /// resulting in an ICE.
255
264
///
256
265
/// The trait solver sometimes depends on regions being identical. As a concrete example
257
266
/// the trait solver ignores other candidates if one candidate exists without any constraints.
258
267
/// The goal `&'a u32: Equals<&'a u32>` has no constraints right now, but if we replace
259
- /// each occurance of `'a` with a unique region the goal now equates these regions.
260
- ///
261
- /// See the tests in trait-system-refactor-initiative#27 for concrete examples.
268
+ /// each occurance of `'a` with a unique region the goal now equates these regions. See
269
+ /// the tests in trait-system-refactor-initiative#27 for concrete examples.
262
270
///
263
- /// FIXME(-Znext-solver): This is insufficient in theory as a goal `T: Trait<?x, ?x>`
264
- /// may rely on the two occurances of `?x` being identical. If `?x` gets inferred to a
265
- /// type containing regions, this will no longer be the case. We can handle this case
266
- /// by storing goals which hold while still depending on inference vars and then
267
- /// reproving them before writeback.
271
+ /// We handle this by *uniquifying* region when canonicalizing root goals during HIR typeck.
272
+ /// This is still insufficient as inference variables may *hide* region variables, so e.g.
273
+ /// `dyn TwoSuper<?x, ?x>: Super<?x>` may hold but MIR typeck could end up having to prove
274
+ /// `dyn TwoSuper<&'0 (), &'1 ()>: Super<&'2 ()>` which is now ambiguous. Because of this we
275
+ /// stash all successfully proven goals which reference inference variables and then reprove
276
+ /// them after writeback.
268
277
pub in_hir_typeck : bool ,
269
278
270
279
/// If set, this flag causes us to skip the 'leak check' during
@@ -1010,6 +1019,22 @@ impl<'tcx> InferCtxt<'tcx> {
1010
1019
}
1011
1020
}
1012
1021
1022
+ pub fn push_hir_typeck_potentially_region_dependent_goal (
1023
+ & self ,
1024
+ goal : PredicateObligation < ' tcx > ,
1025
+ ) {
1026
+ let mut inner = self . inner . borrow_mut ( ) ;
1027
+ inner. undo_log . push ( UndoLog :: PushHirTypeckPotentiallyRegionDependentGoal ) ;
1028
+ inner. hir_typeck_potentially_region_dependent_goals . push ( goal) ;
1029
+ }
1030
+
1031
+ pub fn take_hir_typeck_potentially_region_dependent_goals (
1032
+ & self ,
1033
+ ) -> Vec < PredicateObligation < ' tcx > > {
1034
+ assert ! ( !self . in_snapshot( ) , "cannot take goals in a snapshot" ) ;
1035
+ std:: mem:: take ( & mut self . inner . borrow_mut ( ) . hir_typeck_potentially_region_dependent_goals )
1036
+ }
1037
+
1013
1038
pub fn ty_to_string ( & self , t : Ty < ' tcx > ) -> String {
1014
1039
self . resolve_vars_if_possible ( t) . to_string ( )
1015
1040
}
0 commit comments