diff options
| author | lcnr <rust@lcnr.de> | 2025-07-24 14:53:13 +0000 |
|---|---|---|
| committer | lcnr <rust@lcnr.de> | 2025-07-25 12:40:01 +0000 |
| commit | 0b323eacd4c4cf99d18bd75ad02b2139dd990297 (patch) | |
| tree | 7d39741a37ee2613b58a631e744874cac8acafd1 /compiler/rustc_infer | |
| parent | 3c30dbbe31bfbf6029f4534170165ba573ff0fd1 (diff) | |
| download | rust-0b323eacd4c4cf99d18bd75ad02b2139dd990297.tar.gz rust-0b323eacd4c4cf99d18bd75ad02b2139dd990297.zip | |
uniquify root goals during HIR typeck
Diffstat (limited to 'compiler/rustc_infer')
| -rw-r--r-- | compiler/rustc_infer/src/infer/at.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/context.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/mod.rs | 38 |
3 files changed, 41 insertions, 3 deletions
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 5fe795bd23a..ad19cdef4e7 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -71,6 +71,7 @@ impl<'tcx> InferCtxt<'tcx> { tcx: self.tcx, typing_mode: self.typing_mode, considering_regions: self.considering_regions, + in_hir_typeck: self.in_hir_typeck, skip_leak_check: self.skip_leak_check, inner: self.inner.clone(), lexical_region_resolutions: self.lexical_region_resolutions.clone(), @@ -95,6 +96,7 @@ impl<'tcx> InferCtxt<'tcx> { tcx: self.tcx, typing_mode, considering_regions: self.considering_regions, + in_hir_typeck: self.in_hir_typeck, skip_leak_check: self.skip_leak_check, inner: self.inner.clone(), lexical_region_resolutions: self.lexical_region_resolutions.clone(), diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index bb9c8850093..21e999b080d 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -22,6 +22,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.next_trait_solver } + fn in_hir_typeck(&self) -> bool { + self.in_hir_typeck + } + fn typing_mode(&self) -> ty::TypingMode<'tcx> { self.typing_mode() } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 2d269e320b6..17c587c5e7f 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -244,9 +244,28 @@ pub struct InferCtxt<'tcx> { typing_mode: TypingMode<'tcx>, /// Whether this inference context should care about region obligations in - /// the root universe. Most notably, this is used during hir typeck as region + /// the root universe. Most notably, this is used during HIR typeck as region /// solving is left to borrowck instead. pub considering_regions: bool, + /// Whether this inference context is used by HIR typeck. If so, we uniquify regions + /// with `-Znext-solver`. This is necessary as borrowck will start by replacing each + /// occurance of a free region with a unique inference variable so if HIR typeck + /// ends up depending on two regions being equal we'd get unexpected mismatches + /// between HIR typeck and MIR typeck, resulting in an ICE. + /// + /// The trait solver sometimes depends on regions being identical. As a concrete example + /// the trait solver ignores other candidates if one candidate exists without any constraints. + /// The goal `&'a u32: Equals<&'a u32>` has no constraints right now, but if we replace + /// each occurance of `'a` with a unique region the goal now equates these regions. + /// + /// See the tests in trait-system-refactor-initiative#27 for concrete examples. + /// + /// FIXME(-Znext-solver): This is insufficient in theory as a goal `T: Trait<?x, ?x>` + /// may rely on the two occurances of `?x` being identical. If `?x` gets inferred to a + /// type containing regions, this will no longer be the case. We can handle this case + /// by storing goals which hold while still depending on inference vars and then + /// reproving them before writeback. + pub in_hir_typeck: bool, /// If set, this flag causes us to skip the 'leak check' during /// higher-ranked subtyping operations. This flag is a temporary one used @@ -506,6 +525,7 @@ pub struct TypeOutlivesConstraint<'tcx> { pub struct InferCtxtBuilder<'tcx> { tcx: TyCtxt<'tcx>, considering_regions: bool, + in_hir_typeck: bool, skip_leak_check: bool, /// Whether we should use the new trait solver in the local inference context, /// which affects things like which solver is used in `predicate_may_hold`. @@ -518,6 +538,7 @@ impl<'tcx> TyCtxt<'tcx> { InferCtxtBuilder { tcx: self, considering_regions: true, + in_hir_typeck: false, skip_leak_check: false, next_trait_solver: self.next_trait_solver_globally(), } @@ -535,6 +556,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> { self } + pub fn in_hir_typeck(mut self) -> Self { + self.in_hir_typeck = true; + self + } + pub fn skip_leak_check(mut self, skip_leak_check: bool) -> Self { self.skip_leak_check = skip_leak_check; self @@ -568,12 +594,18 @@ impl<'tcx> InferCtxtBuilder<'tcx> { } pub fn build(&mut self, typing_mode: TypingMode<'tcx>) -> InferCtxt<'tcx> { - let InferCtxtBuilder { tcx, considering_regions, skip_leak_check, next_trait_solver } = - *self; + let InferCtxtBuilder { + tcx, + considering_regions, + in_hir_typeck, + skip_leak_check, + next_trait_solver, + } = *self; InferCtxt { tcx, typing_mode, considering_regions, + in_hir_typeck, skip_leak_check, inner: RefCell::new(InferCtxtInner::new()), lexical_region_resolutions: RefCell::new(None), |
