summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_infer/src/infer/canonical/canonicalizer.rs')
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs77
1 files changed, 54 insertions, 23 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 678c4a0be..e808911a3 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -230,9 +230,9 @@ impl CanonicalizeMode for CanonicalizeUserTypeAnnotation {
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
match *r {
- ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic => r,
+ ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReError(_) => r,
ty::ReVar(_) => canonicalizer.canonical_var_for_region_in_root_universe(r),
- _ => {
+ ty::RePlaceholder(..) | ty::ReLateBound(..) => {
// We only expect region names that the user can type.
bug!("unexpected region in query response: `{:?}`", r)
}
@@ -352,19 +352,17 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
}
ty::ReVar(vid) => {
- let resolved_vid = self
+ let resolved = self
.infcx
.inner
.borrow_mut()
.unwrap_region_constraints()
- .opportunistic_resolve_var(vid);
+ .opportunistic_resolve_var(self.tcx, vid);
debug!(
- "canonical: region var found with vid {:?}, \
- opportunistically resolved to {:?}",
- vid, resolved_vid
+ "canonical: region var found with vid {vid:?}, \
+ opportunistically resolved to {resolved:?}",
);
- let r = self.tcx.mk_re_var(resolved_vid);
- self.canonicalize_mode.canonicalize_free_region(self, r)
+ self.canonicalize_mode.canonicalize_free_region(self, resolved)
}
ty::ReStatic
@@ -376,9 +374,18 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
}
}
- fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+ fn fold_ty(&mut self, mut t: Ty<'tcx>) -> Ty<'tcx> {
match *t.kind() {
- ty::Infer(ty::TyVar(vid)) => {
+ ty::Infer(ty::TyVar(mut vid)) => {
+ // We need to canonicalize the *root* of our ty var.
+ // This is so that our canonical response correctly reflects
+ // any equated inference vars correctly!
+ let root_vid = self.infcx.root_var(vid);
+ if root_vid != vid {
+ t = self.infcx.tcx.mk_ty_var(root_vid);
+ vid = root_vid;
+ }
+
debug!("canonical: type var found with vid {:?}", vid);
match self.infcx.probe_ty_var(vid) {
// `t` could be a float / int variable; canonicalize that instead.
@@ -404,15 +411,28 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
}
}
- ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
- CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
- t,
- ),
-
- ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
- CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
- t,
- ),
+ ty::Infer(ty::IntVar(vid)) => {
+ let nt = self.infcx.opportunistic_resolve_int_var(vid);
+ if nt != t {
+ return self.fold_ty(nt);
+ } else {
+ self.canonicalize_ty_var(
+ CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
+ t,
+ )
+ }
+ }
+ ty::Infer(ty::FloatVar(vid)) => {
+ let nt = self.infcx.opportunistic_resolve_float_var(vid);
+ if nt != t {
+ return self.fold_ty(nt);
+ } else {
+ self.canonicalize_ty_var(
+ CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
+ t,
+ )
+ }
+ }
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("encountered a fresh type during canonicalization")
@@ -469,9 +489,18 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
}
}
- fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
+ fn fold_const(&mut self, mut ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.kind() {
- ty::ConstKind::Infer(InferConst::Var(vid)) => {
+ ty::ConstKind::Infer(InferConst::Var(mut vid)) => {
+ // We need to canonicalize the *root* of our const var.
+ // This is so that our canonical response correctly reflects
+ // any equated inference vars correctly!
+ let root_vid = self.infcx.root_const_var(vid);
+ if root_vid != vid {
+ ct = self.infcx.tcx.mk_const(ty::InferConst::Var(root_vid), ct.ty());
+ vid = root_vid;
+ }
+
debug!("canonical: const var found with vid {:?}", vid);
match self.infcx.probe_const_var(vid) {
Ok(c) => {
@@ -532,6 +561,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
where
V: TypeFoldable<TyCtxt<'tcx>>,
{
+ let _inside_canonical_ctxt_guard = infcx.set_canonicalization_ctxt();
+
let needs_canonical_flags = if canonicalize_region_mode.any() {
TypeFlags::NEEDS_INFER |
TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS`
@@ -741,7 +772,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
let var = self.canonical_var(info, r.into());
- let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32(), None) };
+ let br = ty::BoundRegion { var, kind: ty::BrAnon(None) };
self.interner().mk_re_late_bound(self.binder_index, br)
}