@@ -37,10 +37,11 @@ use snapshot::undo_log::InferCtxtUndoLogs;
3737use tracing:: { debug, instrument} ;
3838use type_variable:: TypeVariableOrigin ;
3939
40- use crate :: infer:: region_constraints :: UndoLog ;
40+ use crate :: infer:: snapshot :: undo_log :: UndoLog ;
4141use crate :: infer:: unify_key:: { ConstVariableOrigin , ConstVariableValue , ConstVidKey } ;
4242use crate :: traits:: {
43- self , ObligationCause , ObligationInspector , PredicateObligations , TraitEngine ,
43+ self , ObligationCause , ObligationInspector , PredicateObligation , PredicateObligations ,
44+ TraitEngine ,
4445} ;
4546
4647pub mod at;
@@ -156,6 +157,12 @@ pub struct InferCtxtInner<'tcx> {
156157 /// which may cause types to no longer be considered well-formed.
157158 region_assumptions : Vec < ty:: ArgOutlivesPredicate < ' tcx > > ,
158159
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+
159166 /// Caches for opaque type inference.
160167 opaque_type_storage : OpaqueTypeStorage < ' tcx > ,
161168}
@@ -173,6 +180,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
173180 region_constraint_storage : Some ( Default :: default ( ) ) ,
174181 region_obligations : Default :: default ( ) ,
175182 region_assumptions : Default :: default ( ) ,
183+ hir_typeck_potentially_region_dependent_goals : Default :: default ( ) ,
176184 opaque_type_storage : Default :: default ( ) ,
177185 }
178186 }
@@ -247,24 +255,25 @@ pub struct InferCtxt<'tcx> {
247255 /// the root universe. Most notably, this is used during HIR typeck as region
248256 /// solving is left to borrowck instead.
249257 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 when
260+ /// relating types. This is necessary as borrowck starts by replacing each occurrence of a
261+ /// free region with a unique inference variable. 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.
255264 ///
256265 /// The trait solver sometimes depends on regions being identical. As a concrete example
257266 /// the trait solver ignores other candidates if one candidate exists without any constraints.
258- /// 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.
267+ /// The goal `&'a u32: Equals<&'a u32>` has no constraints right now. If we replace each
268+ /// occurrence 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.
262270 ///
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.
268277 pub in_hir_typeck : bool ,
269278
270279 /// If set, this flag causes us to skip the 'leak check' during
@@ -1010,6 +1019,22 @@ impl<'tcx> InferCtxt<'tcx> {
10101019 }
10111020 }
10121021
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+
10131038 pub fn ty_to_string ( & self , t : Ty < ' tcx > ) -> String {
10141039 self . resolve_vars_if_possible ( t) . to_string ( )
10151040 }
0 commit comments