From a2b6881de53891ac2c8e5c7fdfc7a19d61b2c35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 11 Aug 2026 10:49:33 +0200 Subject: [PATCH 1/8] optimize resolve, and properly document the related methods --- compiler/rustc_infer/src/infer/mod.rs | 189 ++++++++++++++++++-------- 1 file changed, 129 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 0e4dfc6854e22..35f6929c2f0e5 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -29,9 +29,10 @@ use rustc_middle::traits::solve::Goal; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, BoundVarReplacerDelegate, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, - GenericArgsRef, GenericParamDefKind, InferConst, OpaqueTypeKey, ProvisionalHiddenType, - PseudoCanonicalInput, RegionExt, Term, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions, + GenericArgsRef, GenericParamDefKind, InferConst, InferTy, IntVid, OpaqueTypeKey, + ProvisionalHiddenType, PseudoCanonicalInput, RegionExt, Term, Ty, TyCtxt, TyVid, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, + fold_regions, }; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_type_ir::MayBeErased; @@ -1214,10 +1215,10 @@ impl<'tcx> InferCtxt<'tcx> { /// If `TyVar(vid)` resolves to a type, return that type. Else, return the /// universe index of `TyVar(vid)`. pub fn try_resolve_ty_var(&self, vid: TyVid) -> Result, ty::UniverseIndex> { - use self::type_variable::TypeVariableValue; + let value = self.inner.borrow_mut().type_variables().probe(vid); - match self.inner.borrow_mut().type_variables().probe(vid) { - TypeVariableValue::Known { value } => Ok(value), + match value { + TypeVariableValue::Known { value } => Ok(self.shallow_resolve_non_recursive(value)), TypeVariableValue::Unknown { universe } => Err(universe), } } @@ -1227,76 +1228,142 @@ impl<'tcx> InferCtxt<'tcx> { let (root, value) = self.inner.borrow_mut().type_variables().probe_with_root_vid(vid); match value { - TypeVariableValue::Known { value } => Ok(value), + TypeVariableValue::Known { value } => Ok(self.shallow_resolve_non_recursive(value)), TypeVariableValue::Unknown { universe: _ } => Err(root), } } - pub fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Infer(v) = *ty.kind() { - match v { - ty::TyVar(v) => { - // Not entirely obvious: if `typ` is a type variable, - // it can be resolved to an int/float variable, which - // can then be recursively resolved, hence the - // recursion. Note though that we prevent type - // variables from unifying to other type variables - // directly (though they may be embedded - // structurally), and we prevent cycles in any case, - // so this recursion should always be of very limited - // depth. - // - // Note: if these two lines are combined into one we get - // dynamic borrow errors on `self.inner`. - let (root_vid, value) = - self.inner.borrow_mut().type_variables().probe_with_root_vid(v); - value.known().map_or_else( - || if root_vid == v { ty } else { Ty::new_var(self.tcx, root_vid) }, - |t| self.shallow_resolve(t), - ) + /// Resolve a type variable to a type, if known. + /// Otherwise return a type with the root vid in it. + /// + /// Not entirely obvious: + /// It's possible for a type variable to resolve to an int/float variable. + /// When that happens, the int/float variable may itself already be resolved + /// to an int/float, which is the type we actually want to return, not the variable. + /// + /// Only one step of this is ever possible. We never resolve type variables to other + /// type variables. Therefore, we use [`shallow_resolve_non_recursive`](Self::shallow_resolve_non_recursive), + /// to call into a version of shallow_resolve that only knows about int/float variables + /// and panics (and notably: doesn't recurse again) when it sees type variables. + /// That way the compiler knows the recursion can only ever go two deep, which helps performance. + #[inline(always)] + fn shallow_resolve_ty_var(&self, v: TyVid, ty: Ty<'tcx>) -> Ty<'tcx> { + let (root_vid, value) = self.inner.borrow_mut().type_variables().inlined_probe_with_vid(v); + match value { + TypeVariableValue::Known { value } => self.shallow_resolve_non_recursive(value), + TypeVariableValue::Unknown { .. } => { + if root_vid == v { + ty + } else { + Ty::new_var(self.tcx, root_vid) } + } + } + } - ty::IntVar(v) => { - let (root, value) = - self.inner.borrow_mut().int_unification_table().inlined_probe_key_value(v); - match value { - ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty), - ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty), - ty::IntVarValue::Unknown => { - if root == v { - ty - } else { - Ty::new_int_var(self.tcx, root) - } - } - } + /// Resolve a type variable to an integer type, if known. + /// Otherwise return a type with the root int vid in it. + #[inline(always)] + fn shallow_resolve_int_var(&self, v: IntVid, ty: Ty<'tcx>) -> Ty<'tcx> { + let (root, value) = + self.inner.borrow_mut().int_unification_table().inlined_probe_key_value(v); + match value { + ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty), + ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty), + ty::IntVarValue::Unknown => { + if root == v { + ty + } else { + Ty::new_int_var(self.tcx, root) } + } + } + } - ty::FloatVar(v) => { - let (root, value) = self - .inner - .borrow_mut() - .float_unification_table() - .inlined_probe_key_value(v); - match value { - ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty), - ty::FloatVarValue::Unknown => { - if root == v { - ty - } else { - Ty::new_float_var(self.tcx, root) - } - } - } + /// Resolve a type variable to a float type, if known. + /// Otherwise return a type with the root float vid in it. + #[inline(always)] + fn shallow_resolve_float_var(&self, v: FloatVid, ty: Ty<'tcx>) -> Ty<'tcx> { + let (root, value) = + self.inner.borrow_mut().float_unification_table().inlined_probe_key_value(v); + match value { + ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty), + ty::FloatVarValue::Unknown => { + if root == v { + ty + } else { + Ty::new_float_var(self.tcx, root) } + } + } + } - ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => ty, + /// Shallow resolve a type/int infer var, panics on type variables. + /// + /// See docs on [`shallow_resolve_ty_var`](Self::shallow_resolve_ty_var) for why this exists. + #[inline(never)] + // Cold because the case in which a tyvar resolves to an intvar which resolves to a type is + // quite rare. It's way more common for `shallow_resolve_non_recursive` to return ty. + #[cold] + fn shallow_resolve_infer_non_recursive(&self, infer: InferTy, ty: Ty<'tcx>) -> Ty<'tcx> { + match infer { + ty::TyVar(_) => { + unreachable!() } + ty::IntVar(v) => self.shallow_resolve_int_var(v, ty), + ty::FloatVar(v) => self.shallow_resolve_float_var(v, ty), + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => ty, + } + } + + #[inline(always)] + fn shallow_resolve_infer(&self, infer: InferTy, ty: Ty<'tcx>) -> Ty<'tcx> { + match infer { + ty::TyVar(v) => self.shallow_resolve_ty_var(v, ty), + ty::IntVar(v) => self.shallow_resolve_int_var(v, ty), + ty::FloatVar(v) => self.shallow_resolve_float_var(v, ty), + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => ty, + } + } + + /// Shallow resolve a type, panics on type variables. + /// See [`shallow_resolve`](Self::shallow_resolve) for more docs. + /// + /// See docs on [`shallow_resolve_ty_var`](Self::shallow_resolve_ty_var) for why this alternate + /// version of shallow_resolve exists. + #[inline(always)] + fn shallow_resolve_non_recursive(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Infer(infer) = *ty.kind() { + self.shallow_resolve_infer_non_recursive(infer, ty) } else { ty } } + /// Resolve a type variable. Resolving means the following: + /// + /// - If a `Ty` is a rigid type (like, an integer, or some ADT), do nothing. + /// - If a `Ty` is a type infer variable, but has been equated with an actual type, + /// return that type. + /// - If a `Ty` is an int or float infer variable, and has been equated with an integer + /// or floating point type, return that type. + /// - If a `Ty` is any kind of infer variable that has been equated, but not yet with a rigid + /// type, then this set of equated variables forms an equivalence class. One of the variables + /// in that equivalent class is said to be the root variable, and resolving makes sure to + /// consistently return this root variable. This is beneficial for caching. + /// This behavior, of returning roots, changed in . + /// + /// Otherwise, resolving simply does nothing. + /// + /// The "shallow" part of the name refers to the fact that types may themselves contain more + /// type variables. e.g. The field types of a struct. `shallow_resolve` does not recurse into + /// these nested variables. If that's what you want, use [`resolve_vars_if_possible`](Self::resolve_vars_if_possible) + pub fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Infer(infer) = *ty.kind() { self.shallow_resolve_infer(infer, ty) } else { ty } + } + + /// See docs on [`shallow_resolve`](Self::shallow_resolve) for more explanation. + /// It's the same, but for consts. pub fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { match ct.kind() { ty::ConstKind::Infer(infer_ct) => match infer_ct { @@ -1323,6 +1390,8 @@ impl<'tcx> InferCtxt<'tcx> { } } + /// See docs on [`shallow_resolve`](Self::shallow_resolve) for more explanation. + /// It's the same, but for terms (types or consts). pub fn shallow_resolve_term(&self, term: ty::Term<'tcx>) -> ty::Term<'tcx> { match term.kind() { ty::TermKind::Ty(ty) => self.shallow_resolve(ty).into(), From 5cab5ba9d883628228e7e3de8afa22cc48c60173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 11 Aug 2026 13:45:23 +0200 Subject: [PATCH 2/8] unify implementations of shallow_resolve and opportunistic_resolve --- .../src/infer/canonical/canonicalizer.rs | 4 +- compiler/rustc_infer/src/infer/context.rs | 4 +- compiler/rustc_infer/src/infer/mod.rs | 60 +++++++++---------- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index e0adcfc06a0ed..1a51c20bfe8dd 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -362,7 +362,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { } ty::Infer(ty::IntVar(vid)) => { - let nt = self.infcx.unwrap().opportunistic_resolve_int_var(vid); + let nt = self.infcx.unwrap().shallow_resolve_int_var(vid); if nt != t { return self.fold_ty(nt); } else { @@ -370,7 +370,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { } } ty::Infer(ty::FloatVar(vid)) => { - let nt = self.infcx.unwrap().opportunistic_resolve_float_var(vid); + let nt = self.infcx.unwrap().shallow_resolve_float_var(vid); if nt != t { return self.fold_ty(nt); } else { diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 9a4cfab3dd4d9..a1b660069ccd4 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -131,11 +131,11 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { - self.opportunistic_resolve_int_var(vid) + self.shallow_resolve_int_var(vid) } fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { - self.opportunistic_resolve_float_var(vid) + self.shallow_resolve_float_var(vid) } fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 35f6929c2f0e5..09c774d781de1 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1246,13 +1246,18 @@ impl<'tcx> InferCtxt<'tcx> { /// to call into a version of shallow_resolve that only knows about int/float variables /// and panics (and notably: doesn't recurse again) when it sees type variables. /// That way the compiler knows the recursion can only ever go two deep, which helps performance. + /// + /// `ty` is a type that we may already have available, which represents the `TyVid`. + /// In cases where we do, this can aid performance. #[inline(always)] - fn shallow_resolve_ty_var(&self, v: TyVid, ty: Ty<'tcx>) -> Ty<'tcx> { + fn shallow_resolve_ty_var_with_ty(&self, v: TyVid, ty: Option>) -> Ty<'tcx> { let (root_vid, value) = self.inner.borrow_mut().type_variables().inlined_probe_with_vid(v); match value { TypeVariableValue::Known { value } => self.shallow_resolve_non_recursive(value), TypeVariableValue::Unknown { .. } => { - if root_vid == v { + if root_vid == v + && let Some(ty) = ty + { ty } else { Ty::new_var(self.tcx, root_vid) @@ -1263,15 +1268,20 @@ impl<'tcx> InferCtxt<'tcx> { /// Resolve a type variable to an integer type, if known. /// Otherwise return a type with the root int vid in it. + /// + /// `ty` is a type that we may already have available, which represents the `IntVid`. + /// In cases where we do, this can aid performance. #[inline(always)] - fn shallow_resolve_int_var(&self, v: IntVid, ty: Ty<'tcx>) -> Ty<'tcx> { + fn shallow_resolve_int_var_with_ty(&self, v: IntVid, ty: Option>) -> Ty<'tcx> { let (root, value) = self.inner.borrow_mut().int_unification_table().inlined_probe_key_value(v); match value { ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty), ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty), ty::IntVarValue::Unknown => { - if root == v { + if root == v + && let Some(ty) = ty + { ty } else { Ty::new_int_var(self.tcx, root) @@ -1282,14 +1292,19 @@ impl<'tcx> InferCtxt<'tcx> { /// Resolve a type variable to a float type, if known. /// Otherwise return a type with the root float vid in it. + /// + /// `ty` is a type that we may already have available, which represents the `FloatVid`. + /// In cases where we do, this can aid performance. #[inline(always)] - fn shallow_resolve_float_var(&self, v: FloatVid, ty: Ty<'tcx>) -> Ty<'tcx> { + fn shallow_resolve_float_var_with_ty(&self, v: FloatVid, ty: Option>) -> Ty<'tcx> { let (root, value) = self.inner.borrow_mut().float_unification_table().inlined_probe_key_value(v); match value { ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty), ty::FloatVarValue::Unknown => { - if root == v { + if root == v + && let Some(ty) = ty + { ty } else { Ty::new_float_var(self.tcx, root) @@ -1310,8 +1325,8 @@ impl<'tcx> InferCtxt<'tcx> { ty::TyVar(_) => { unreachable!() } - ty::IntVar(v) => self.shallow_resolve_int_var(v, ty), - ty::FloatVar(v) => self.shallow_resolve_float_var(v, ty), + ty::IntVar(v) => self.shallow_resolve_int_var_with_ty(v, Some(ty)), + ty::FloatVar(v) => self.shallow_resolve_float_var_with_ty(v, Some(ty)), ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => ty, } } @@ -1319,9 +1334,9 @@ impl<'tcx> InferCtxt<'tcx> { #[inline(always)] fn shallow_resolve_infer(&self, infer: InferTy, ty: Ty<'tcx>) -> Ty<'tcx> { match infer { - ty::TyVar(v) => self.shallow_resolve_ty_var(v, ty), - ty::IntVar(v) => self.shallow_resolve_int_var(v, ty), - ty::FloatVar(v) => self.shallow_resolve_float_var(v, ty), + ty::TyVar(v) => self.shallow_resolve_ty_var_with_ty(v, Some(ty)), + ty::IntVar(v) => self.shallow_resolve_int_var_with_ty(v, Some(ty)), + ty::FloatVar(v) => self.shallow_resolve_float_var_with_ty(v, Some(ty)), ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => ty, } } @@ -1428,29 +1443,14 @@ impl<'tcx> InferCtxt<'tcx> { /// Resolves an int var to a rigid int type, if it was constrained to one, /// or else the root int var in the unification table. - pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { - let mut inner = self.inner.borrow_mut(); - let value = inner.int_unification_table().probe_value(vid); - match value { - ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty), - ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty), - ty::IntVarValue::Unknown => { - Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid)) - } - } + pub fn shallow_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { + self.shallow_resolve_int_var_with_ty(vid, None) } /// Resolves a float var to a rigid int type, if it was constrained to one, /// or else the root float var in the unification table. - pub fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { - let mut inner = self.inner.borrow_mut(); - let value = inner.float_unification_table().probe_value(vid); - match value { - ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty), - ty::FloatVarValue::Unknown => { - Ty::new_float_var(self.tcx, inner.float_unification_table().find(vid)) - } - } + pub fn shallow_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { + self.shallow_resolve_float_var_with_ty(vid, None) } /// Where possible, replaces type/const variables in From 3e87ef31ea01834327e8c92363ef454aa646875c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 11 Aug 2026 13:45:23 +0200 Subject: [PATCH 3/8] Make region methods consistent and faster. --- .../src/check/compare_impl_item.rs | 4 ++-- .../src/infer/canonical/canonicalizer.rs | 4 ++-- compiler/rustc_infer/src/infer/context.rs | 7 +++++-- .../rustc_infer/src/infer/region_constraints/mod.rs | 13 ++++++------- compiler/rustc_infer/src/infer/resolve.rs | 2 +- .../rustc_trait_selection/src/traits/coherence.rs | 2 +- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 2f65b443dd5ec..b78440692c2f6 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1296,7 +1296,7 @@ fn check_region_late_boundedness<'tcx>( .inner .borrow_mut() .unwrap_region_constraints() - .opportunistic_resolve_var(tcx, vid) + .shallow_resolve_region_var(tcx, vid) && let ty::ReLateParam(ty::LateParamRegion { kind: ty::LateParamRegionKind::Named(trait_param_def_id), .. @@ -1321,7 +1321,7 @@ fn check_region_late_boundedness<'tcx>( .inner .borrow_mut() .unwrap_region_constraints() - .opportunistic_resolve_var(tcx, vid) + .shallow_resolve_region_var(tcx, vid) && let ty::ReLateParam(ty::LateParamRegion { kind: ty::LateParamRegionKind::Named(impl_param_def_id), .. diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 1a51c20bfe8dd..732c68ab84c37 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -164,7 +164,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { .inner .borrow_mut() .unwrap_region_constraints() - .opportunistic_resolve_var(canonicalizer.tcx, vid); + .shallow_resolve_region_var(canonicalizer.tcx, vid); debug!( "canonical: region var found with vid {vid:?}, \ opportunistically resolved to {r:?}", @@ -182,7 +182,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { .inner .borrow_mut() .unwrap_region_constraints() - .probe_value(vid) + .try_resolve_region_var(vid) .unwrap_err(); canonicalizer.canonical_var_for_region(CanonicalVarKind::Region(universe), r) } diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index a1b660069ccd4..6d736e4de7119 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -88,7 +88,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn universe_of_lt(&self, lt: ty::RegionVid) -> Option { - match self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) { + match self.inner.borrow_mut().unwrap_region_constraints().try_resolve_region_var(lt) { Err(universe) => Some(universe), Ok(_) => None, } @@ -146,7 +146,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> { - self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid) + self.inner + .borrow_mut() + .unwrap_region_constraints() + .shallow_resolve_region_var(self.tcx, vid) } fn ty_or_const_infer_var_changed(&self, var: TyOrConstInferVar) -> bool { diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 7db45fde6c8d7..3476685a496e3 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -672,20 +672,19 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { /// Resolves a region var to its value in the unification table, if it exists. /// Otherwise, it is resolved to the root `ReVar` in the table. - pub fn opportunistic_resolve_var( + pub fn shallow_resolve_region_var( &mut self, tcx: TyCtxt<'tcx>, vid: ty::RegionVid, ) -> ty::Region<'tcx> { - let mut ut = self.unification_table_mut(); - let root_vid = ut.find(vid).vid; - match ut.probe_value(root_vid) { + let (root_vid, value) = self.unification_table_mut().inlined_probe_key_value(vid); + match value { RegionVariableValue::Known { value } => value, - RegionVariableValue::Unknown { .. } => ty::Region::new_var(tcx, root_vid), + RegionVariableValue::Unknown { .. } => ty::Region::new_var(tcx, root_vid.vid), } } - pub fn probe_value( + pub fn try_resolve_region_var( &mut self, vid: ty::RegionVid, ) -> Result, ty::UniverseIndex> { @@ -743,7 +742,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { | ty::ReEarlyParam(..) | ty::ReError(_) => ty::UniverseIndex::ROOT, ty::RePlaceholder(placeholder) => placeholder.universe, - ty::ReVar(vid) => match self.probe_value(vid) { + ty::ReVar(vid) => match self.try_resolve_region_var(vid) { Ok(value) => self.universe(value), Err(universe) => universe, }, diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 13df23a39b967..e38492c921528 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -103,7 +103,7 @@ impl<'a, 'tcx> TypeFolder> for OpportunisticRegionResolver<'a, 'tcx .inner .borrow_mut() .unwrap_region_constraints() - .opportunistic_resolve_var(TypeFolder::cx(self), vid), + .shallow_resolve_region_var(TypeFolder::cx(self), vid), _ => r, } } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 78ccf04d456a3..4ce7841826779 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -638,7 +638,7 @@ fn plug_infer_with_placeholders<'tcx>( .inner .borrow_mut() .unwrap_region_constraints() - .opportunistic_resolve_var(self.infcx.tcx, vid); + .shallow_resolve_region_var(self.infcx.tcx, vid); if r.is_var() { let Ok(InferOk { value: (), obligations }) = self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( From ebd31df76a277b5ebe58a950453a1f65619e537f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 11 Aug 2026 14:28:09 +0200 Subject: [PATCH 4/8] Make const methods consistent and expose methods to shallow resolve a tyvar. --- compiler/rustc_infer/src/infer/mod.rs | 51 +++++++++++++++++++++------ 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 09c774d781de1..e02329a57f338 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1313,6 +1313,33 @@ impl<'tcx> InferCtxt<'tcx> { } } + /// Resolve a const variable to a const, if known. + /// Otherwise return a const with the root const vid in it. + /// + /// `ct` is const type that we may already have available, which represents the `ConstVid`. + /// In cases where we do, this can aid performance. + #[inline(always)] + fn shallow_resolve_const_var_with_ct( + &self, + v: ConstVid, + ct: Option>, + ) -> ty::Const<'tcx> { + let (root, value) = + self.inner.borrow_mut().const_unification_table().inlined_probe_key_value(v); + match value { + ConstVariableValue::Known { value } => value, + ConstVariableValue::Unknown { .. } => { + if root.vid == v + && let Some(ct) = ct + { + ct + } else { + ty::Const::new_var(self.tcx, root.vid) + } + } + } + } + /// Shallow resolve a type/int infer var, panics on type variables. /// /// See docs on [`shallow_resolve_ty_var`](Self::shallow_resolve_ty_var) for why this exists. @@ -1382,19 +1409,9 @@ impl<'tcx> InferCtxt<'tcx> { pub fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { match ct.kind() { ty::ConstKind::Infer(infer_ct) => match infer_ct { - InferConst::Var(vid) => { - let (root, value) = self - .inner - .borrow_mut() - .const_unification_table() - .inlined_probe_key_value(vid); - value.known().unwrap_or_else(|| { - if root.vid == vid { ct } else { ty::Const::new_var(self.tcx, root.vid) } - }) - } + InferConst::Var(vid) => self.shallow_resolve_const_var_with_ct(vid, Some(ct)), InferConst::Fresh(_) => ct, }, - ty::ConstKind::Param(_) | ty::ConstKind::Bound(_, _) | ty::ConstKind::Placeholder(_) @@ -1453,6 +1470,18 @@ impl<'tcx> InferCtxt<'tcx> { self.shallow_resolve_float_var_with_ty(vid, None) } + /// Resolves a type var to a rigid type, if it was constrained to one, + /// or else the root type var in the unification table. + pub fn shallow_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> { + self.shallow_resolve_ty_var_with_ty(vid, None) + } + + /// Resolves a type var to a rigid type, if it was constrained to one, + /// or else the root type var in the unification table. + pub fn shallow_resolve_const_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { + self.shallow_resolve_const_var_with_ct(vid, None) + } + /// Where possible, replaces type/const variables in /// `value` with their final value. Note that region variables /// are unaffected. If a type/const variable has not been unified, it From 97cd76a07770259ae592ab804774ab73190f68fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 11 Aug 2026 14:28:09 +0200 Subject: [PATCH 5/8] expose the same through inferctxlike --- compiler/rustc_infer/src/infer/context.rs | 13 +++++------ .../src/canonical/canonicalizer.rs | 8 +++---- compiler/rustc_type_ir/src/infer_ctxt.rs | 22 +++++++------------ 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 6d736e4de7119..a7551afd46124 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -123,22 +123,19 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.root_const_var(var) } - fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> { - match self.try_resolve_ty_var(vid) { - Ok(ty) => ty, - Err(_) => Ty::new_var(self.tcx, self.root_var(vid)), - } + fn shallow_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> { + self.shallow_resolve_ty_var_with_ty(vid, None) } - fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { + fn shallow_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { self.shallow_resolve_int_var(vid) } - fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { + fn shallow_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { self.shallow_resolve_float_var(vid) } - fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { + fn shallow_resolve_const_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { match self.try_resolve_const_var(vid) { Ok(ct) => ct, Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)), diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 32476ed21372b..5a30582489e8c 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -309,7 +309,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { ty::Infer(i) => match i { ty::TyVar(vid) => { debug_assert_eq!( - self.delegate.opportunistic_resolve_ty_var(vid), + self.delegate.shallow_resolve_ty_var(vid), t, "ty vid should have been resolved fully before canonicalization" ); @@ -326,7 +326,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { } ty::IntVar(vid) => { debug_assert_eq!( - self.delegate.opportunistic_resolve_int_var(vid), + self.delegate.shallow_resolve_int_var(vid), t, "ty vid should have been resolved fully before canonicalization" ); @@ -334,7 +334,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { } ty::FloatVar(vid) => { debug_assert_eq!( - self.delegate.opportunistic_resolve_float_var(vid), + self.delegate.shallow_resolve_float_var(vid), t, "ty vid should have been resolved fully before canonicalization" ); @@ -515,7 +515,7 @@ impl, I: Interner> TypeFolder for Canonicaliz ty::ConstKind::Infer(i) => match i { ty::InferConst::Var(vid) => { debug_assert_eq!( - self.delegate.opportunistic_resolve_ct_var(vid), + self.delegate.shallow_resolve_const_var(vid), c, "const vid should have been resolved fully before canonicalization" ); diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 1cd070365f651..d28851d8de939 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -410,16 +410,10 @@ pub trait InferCtxtLike: Sized { fn is_sub_unification_table_root_var(&self, var: ty::TyVid) -> bool; fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid; - fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> ::Ty; - fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> ::Ty; - fn opportunistic_resolve_float_var( - &self, - vid: ty::FloatVid, - ) -> ::Ty; - fn opportunistic_resolve_ct_var( - &self, - vid: ty::ConstVid, - ) -> ::Const; + fn shallow_resolve_ty_var(&self, vid: ty::TyVid) -> ::Ty; + fn shallow_resolve_int_var(&self, vid: ty::IntVid) -> ::Ty; + fn shallow_resolve_float_var(&self, vid: ty::FloatVid) -> ::Ty; + fn shallow_resolve_const_var(&self, vid: ty::ConstVid) -> ::Const; fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> Region; fn ty_or_const_infer_var_changed(&self, var: TyOrConstInferVar) -> bool; @@ -644,15 +638,15 @@ impl, I: Interner> TypeFolder for EagerRes fn fold_ty(&mut self, t: I::Ty) -> I::Ty { match t.kind() { ty::Infer(ty::TyVar(vid)) => { - let resolved = self.delegate.opportunistic_resolve_ty_var(vid); + let resolved = self.delegate.shallow_resolve_ty_var(vid); if t != resolved && resolved.has_infer() { resolved.fold_with(self) } else { resolved } } - ty::Infer(ty::IntVar(vid)) => self.delegate.opportunistic_resolve_int_var(vid), - ty::Infer(ty::FloatVar(vid)) => self.delegate.opportunistic_resolve_float_var(vid), + ty::Infer(ty::IntVar(vid)) => self.delegate.shallow_resolve_int_var(vid), + ty::Infer(ty::FloatVar(vid)) => self.delegate.shallow_resolve_float_var(vid), _ => { if t.has_infer() { if let Some(&ty) = self.cache.get(&t) { @@ -678,7 +672,7 @@ impl, I: Interner> TypeFolder for EagerRes fn fold_const(&mut self, c: I::Const) -> I::Const { match c.kind() { ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { - let resolved = self.delegate.opportunistic_resolve_ct_var(vid); + let resolved = self.delegate.shallow_resolve_const_var(vid); if c != resolved && resolved.has_infer() { resolved.fold_with(self) } else { From 8bf20a7ae3373c69c26274ac291556e5c786717d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 11 Aug 2026 14:10:08 +0200 Subject: [PATCH 6/8] rename resolver folders and their access functions --- .../src/diagnostics/region_errors.rs | 2 +- .../src/region_infer/opaque_types/mod.rs | 2 +- .../src/type_check/constraint_conversion.rs | 2 +- .../src/type_check/relate_tys.rs | 2 +- compiler/rustc_hir_analysis/src/autoderef.rs | 6 +-- .../rustc_hir_analysis/src/check/check.rs | 8 ++-- .../src/check/compare_impl_item.rs | 4 +- .../src/coherence/orphan.rs | 4 +- compiler/rustc_hir_analysis/src/collect.rs | 4 +- compiler/rustc_hir_typeck/src/callee.rs | 10 ++-- compiler/rustc_hir_typeck/src/cast.rs | 36 +++++++-------- compiler/rustc_hir_typeck/src/closure.rs | 14 +++--- compiler/rustc_hir_typeck/src/coercion.rs | 10 ++-- compiler/rustc_hir_typeck/src/demand.rs | 8 ++-- compiler/rustc_hir_typeck/src/expectation.rs | 10 ++-- compiler/rustc_hir_typeck/src/expr.rs | 30 ++++++------ .../rustc_hir_typeck/src/expr_use_visitor.rs | 12 ++--- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 14 +++--- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 10 ++-- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 26 +++++------ .../src/fn_ctxt/inspect_obligations.rs | 2 +- .../src/fn_ctxt/suggestions.rs | 9 ++-- compiler/rustc_hir_typeck/src/inline_asm.rs | 4 +- compiler/rustc_hir_typeck/src/method/probe.rs | 17 ++++--- .../rustc_hir_typeck/src/method/suggest.rs | 10 ++-- compiler/rustc_hir_typeck/src/op.rs | 6 +-- compiler/rustc_hir_typeck/src/opaque_types.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 32 ++++++------- compiler/rustc_hir_typeck/src/place_op.rs | 2 +- compiler/rustc_hir_typeck/src/upvar.rs | 6 +-- compiler/rustc_hir_typeck/src/writeback.rs | 8 ++-- compiler/rustc_infer/src/infer/context.rs | 4 +- compiler/rustc_infer/src/infer/mod.rs | 21 +++++---- .../rustc_infer/src/infer/opaque_types/mod.rs | 2 +- .../rustc_infer/src/infer/outlives/mod.rs | 2 +- .../src/infer/outlives/obligations.rs | 4 +- compiler/rustc_infer/src/infer/resolve.rs | 30 ++++++------ .../rustc_infer/src/infer/snapshot/fudge.rs | 2 +- .../src/canonical/mod.rs | 4 +- .../rustc_next_trait_solver/src/normalize.rs | 10 ++-- .../src/solve/assembly/mod.rs | 2 +- .../src/solve/eval_ctxt/mod.rs | 22 ++++----- .../rustc_next_trait_solver/src/solve/mod.rs | 2 +- .../src/unstable/internal_cx/mod.rs | 6 +-- .../src/error_reporting/infer/mod.rs | 20 ++++---- .../error_reporting/infer/need_type_info.rs | 14 +++--- .../nice_region_error/placeholder_error.rs | 6 +-- .../error_reporting/infer/note_and_explain.rs | 2 +- .../src/error_reporting/infer/region.rs | 4 +- .../src/error_reporting/infer/suggest.rs | 6 +-- .../src/error_reporting/traits/ambiguity.rs | 2 +- .../traits/fulfillment_errors.rs | 36 +++++++-------- .../src/error_reporting/traits/overflow.rs | 10 ++-- .../src/error_reporting/traits/suggestions.rs | 46 +++++++++---------- compiler/rustc_trait_selection/src/infer.rs | 6 +-- .../src/solve/delegate.rs | 8 ++-- .../src/solve/fulfill/derive_errors.rs | 6 +-- .../src/solve/inspect/analyse.rs | 6 +-- .../src/solve/normalize.rs | 4 +- .../src/traits/auto_trait.rs | 6 +-- .../src/traits/coherence.rs | 9 ++-- .../src/traits/effects.rs | 2 +- .../src/traits/fulfill.rs | 15 +++--- .../rustc_trait_selection/src/traits/mod.rs | 6 +-- .../src/traits/normalize.rs | 4 +- .../src/traits/outlives_bounds.rs | 6 +-- .../src/traits/project.rs | 14 +++--- .../src/traits/query/type_op/custom.rs | 2 +- .../query/type_op/implied_outlives_bounds.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 10 ++-- .../src/traits/select/mod.rs | 10 ++-- .../src/traits/specialize/mod.rs | 2 +- .../src/traits/structural_normalize.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_traits/src/codegen.rs | 2 +- .../rustc_traits/src/coroutine_witnesses.rs | 4 +- .../src/normalize_erasing_regions.rs | 2 +- compiler/rustc_type_ir/src/infer_ctxt.rs | 22 +++++---- compiler/rustc_type_ir/src/relate/combine.rs | 2 +- compiler/rustc_type_ir/src/universe.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/html/format.rs | 2 +- 82 files changed, 372 insertions(+), 357 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index a2669ced50c30..0fa1cb013c2f3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -960,7 +960,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { tcx, self.infcx.typing_env(self.infcx.param_env), fn_did, - self.infcx.resolve_vars_if_possible(args.no_bound_vars().unwrap()), + self.infcx.deep_resolve_non_region_vars(args.no_bound_vars().unwrap()), ) else { return; }; diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index e347dc2d13dfc..80b41cf826a05 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -73,7 +73,7 @@ pub(crate) fn clone_and_resolve_opaque_types<'tcx>( let opaque_types = opaque_types .into_iter() .map(|entry| { - fold_regions(infcx.tcx, infcx.resolve_vars_if_possible(entry), |r, _| { + fold_regions(infcx.tcx, infcx.deep_resolve_non_region_vars(entry), |r, _| { let vid = if let ty::RePlaceholder(placeholder) = r.kind() { constraints.placeholder_region(infcx, placeholder).as_var() } else { diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index f1db73fdd7654..31801245e407b 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -158,7 +158,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { GenericArgKind::Type(mut t1) => { // Scraped constraints may have had inference vars. - t1 = self.infcx.resolve_vars_if_possible(t1); + t1 = self.infcx.deep_resolve_non_region_vars(t1); let implicit_region_bound = ty::Region::new_var(tcx, universal_regions.implicit_region_bound()); diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index e99a757b76305..a8a2b7fee5f23 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -144,7 +144,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { variance, ty, )?; - Ok(infcx.resolve_vars_if_possible(Ty::new_infer(infcx.tcx, ty::TyVar(ty_vid)))) + Ok(infcx.deep_resolve_non_region_vars(Ty::new_infer(infcx.tcx, ty::TyVar(ty_vid)))) }; let (a, b) = match (a.kind(), b.kind()) { diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 20c3ac6036678..a39663732dbc5 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -86,7 +86,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> { // and Deref, and this has benefits for const and the emitted MIR. let (kind, new_ty) = if let Some(ty) = self.state.cur_ty.builtin_deref(self.include_raw_pointers) { - debug_assert_eq!(ty, self.infcx.resolve_vars_if_possible(ty)); + debug_assert_eq!(ty, self.infcx.deep_resolve_non_region_vars(ty)); (AutoderefKind::Builtin, ty) } else if let Some(ty) = self.overloaded_deref_ty(self.state.cur_ty) { // The overloaded deref check already normalizes the pointee type. @@ -123,7 +123,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { param_env, state: AutoderefSnapshot { steps: vec![], - cur_ty: infcx.resolve_vars_if_possible(base_ty), + cur_ty: infcx.deep_resolve_non_region_vars(base_ty), obligations: PredicateObligations::new(), at_start: true, reached_recursion_limit: false, @@ -171,7 +171,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations); self.state.obligations.extend(obligations); - Some(self.infcx.resolve_vars_if_possible(normalized_ty)) + Some(self.infcx.deep_resolve_non_region_vars(normalized_ty)) } #[instrument(level = "debug", skip(self), ret)] diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index d98125f7cd9f9..3f66f77c0d9d9 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -433,8 +433,8 @@ fn check_opaque_meets_bounds<'tcx>( } else { // Check that any hidden types found during wf checking match the hidden types that `type_of` sees. for (mut key, mut ty) in infcx.take_opaque_types() { - ty.ty = infcx.resolve_vars_if_possible(ty.ty); - key = infcx.resolve_vars_if_possible(key); + ty.ty = infcx.deep_resolve_non_region_vars(ty.ty); + key = infcx.deep_resolve_non_region_vars(key); sanity_check_found_hidden_type(tcx, key, ty)?; } Ok(()) @@ -2301,8 +2301,8 @@ pub(super) fn check_coroutine_obligations( // Check that any hidden types found when checking these stalled coroutine obligations // are valid. for (key, ty) in infcx.take_opaque_types() { - let hidden_type = infcx.resolve_vars_if_possible(ty); - let key = infcx.resolve_vars_if_possible(key); + let hidden_type = infcx.deep_resolve_non_region_vars(ty); + let key = infcx.deep_resolve_non_region_vars(key); sanity_check_found_hidden_type(tcx, key, hidden_type)?; } } else { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index b78440692c2f6..af9f67d49e37a 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -584,9 +584,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( .iter() .map(|(_, &(ty, _))| { assert!( - infcx.resolve_vars_if_possible(ty) == ty && ty.is_ty_var(), + infcx.deep_resolve_non_region_vars(ty) == ty && ty.is_ty_var(), "{ty:?} should not have been constrained via normalization", - ty = infcx.resolve_vars_if_possible(ty) + ty = infcx.deep_resolve_non_region_vars(ty) ); idx += 1; ( diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 34a7c3b7c01de..059d6ebf0294b 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -330,7 +330,7 @@ fn orphan_check<'tcx>( let ocx = traits::ObligationCtxt::new(&infcx); let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), Unnormalized::new_wip(user_ty)); - let ty = infcx.resolve_vars_if_possible(ty); + let ty = infcx.deep_resolve_non_region_vars(ty); let errors = ocx.try_evaluate_obligations(); if !errors.no_errors() { return Ok(user_ty); @@ -374,7 +374,7 @@ fn orphan_check<'tcx>( id_arg, ); } - infcx.resolve_vars_if_possible(tys) + infcx.deep_resolve_non_region_vars(tys) }); OrphanCheckErr::NonLocalInputType(tys) } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 25ba0c810489e..69a7bb1772848 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1374,11 +1374,11 @@ pub fn suggest_impl_trait<'tcx>( ); // FIXME(compiler-errors): We may benefit from resolving regions here. if ocx.try_evaluate_obligations().no_errors() - && let item_ty = infcx.resolve_vars_if_possible(item_ty) + && let item_ty = infcx.deep_resolve_non_region_vars(item_ty) && let Some(item_ty) = item_ty.make_suggestable(infcx.tcx, false, None) && let Some(sugg) = formatter( infcx.tcx, - infcx.resolve_vars_if_possible(args), + infcx.deep_resolve_non_region_vars(args), trait_def_id, assoc_item_def_id, item_ty, diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index e250ec4c7af40..76c4365fc8005 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -103,7 +103,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => self.check_expr(callee_expr), }; - let expr_ty = self.resolve_vars_with_obligations(original_callee_ty); + let expr_ty = self.deep_resolve_non_regionvars_with_obligations(original_callee_ty); let mut autoderef = self.autoderef(callee_expr.span, expr_ty); let mut result = None; @@ -237,7 +237,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arg_exprs: &'tcx [hir::Expr<'tcx>], autoderef: &Autoderef<'a, 'tcx>, ) -> Option> { - let adjusted_ty = self.resolve_vars_with_obligations(autoderef.final_ty()); + let adjusted_ty = self.deep_resolve_non_regionvars_with_obligations(autoderef.final_ty()); // If the callee is a function pointer or a closure, then we're all set. match *adjusted_ty.kind() { @@ -736,7 +736,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return do_check(); } - resolved_inputs = self.resolve_vars_if_possible(formal_input_tys.to_vec()); + resolved_inputs = self.deep_resolve_non_region_vars(formal_input_tys.to_vec()); } // Fool typechecker by placing an adjusted type of the first arg to avoid errors. @@ -873,7 +873,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (rest_span, format!(").{}({rest_snippet}", segment.ident)), ] }; - let self_ty = self.resolve_vars_if_possible(pick.callee.sig.inputs()[0]); + let self_ty = self.deep_resolve_non_region_vars(pick.callee.sig.inputs()[0]); diag.multipart_suggestion( format!( "use the `.` operator to call the method `{}{}` on `{self_ty}`", @@ -925,7 +925,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(self, qpath))); } - let callee_ty = self.resolve_vars_if_possible(callee_ty); + let callee_ty = self.deep_resolve_non_region_vars(callee_ty); let mut path = None; let mut err = self.dcx().create_err(diagnostics::InvalidCallee { span: callee_expr.span, diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 4cbeaa6278049..cbc0353a528e7 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -94,14 +94,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Result>, ErrorGuaranteed> { debug!("pointer_kind({:?}, {:?})", t, span); - let t = self.resolve_vars_if_possible(t); + let t = self.deep_resolve_non_region_vars(t); t.error_reported()?; if self.type_is_sized_modulo_regions(self.param_env, t) { return Ok(Some(PointerKind::Thin)); } - let t = self.resolve_vars_with_obligations(t); + let t = self.deep_resolve_non_regionvars_with_obligations(t); Ok(match *t.kind() { ty::Slice(_) | ty::Str => Some(PointerKind::Length), @@ -394,7 +394,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.emit(); } CastError::CastToBool => { - let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); + let expr_ty = fcx.deep_resolve_non_region_vars(self.expr_ty); let help = if self.expr_ty.is_numeric() { diagnostics::CannotCastToBoolHelp::Numeric( self.expr_span.shrink_to_hi().with_hi(self.span.hi()), @@ -537,8 +537,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { ) { // Check `impl From for self.cast_ty {}` for accurate suggestion: if let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From) { - let ty = fcx.resolve_vars_if_possible(self.cast_ty); - let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); + let ty = fcx.deep_resolve_non_region_vars(self.cast_ty); + let expr_ty = fcx.deep_resolve_non_region_vars(self.expr_ty); if fcx .infcx .type_implements_trait(from_trait, [ty, expr_ty], fcx.param_env) @@ -602,8 +602,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.emit(); } CastError::SizedUnsizedCast => { - let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); - let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); + let cast_ty = fcx.deep_resolve_non_region_vars(self.cast_ty); + let expr_ty = fcx.deep_resolve_non_region_vars(self.expr_ty); fcx.dcx().emit_err(diagnostics::CastThinPointerToWidePointer { span: self.span, expr_ty, @@ -613,8 +613,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { } CastError::IntToWideCast(known_metadata) => { let expr_if_nightly = fcx.tcx.sess.is_nightly_build().then_some(self.expr_span); - let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); - let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); + let cast_ty = fcx.deep_resolve_non_region_vars(self.cast_ty); + let expr_ty = fcx.deep_resolve_non_region_vars(self.expr_ty); let metadata = known_metadata.unwrap_or("type-specific metadata"); let known_wide = known_metadata.is_some(); let span = self.cast_span; @@ -657,8 +657,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { }); } CastError::CastEnumDrop => { - let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); - let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); + let expr_ty = fcx.deep_resolve_non_region_vars(self.expr_ty); + let cast_ty = fcx.deep_resolve_non_region_vars(self.cast_ty); fcx.dcx().emit_err(diagnostics::CastEnumDrop { span: self.span, expr_ty, cast_ty }); } @@ -705,7 +705,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { self.expr_ty, E0620, "cast to unsized type: `{}` as `{}`", - fcx.resolve_vars_if_possible(self.expr_ty), + fcx.deep_resolve_non_region_vars(self.expr_ty), tstr ); match self.expr_ty.kind() { @@ -745,8 +745,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { } else { (false, lint::builtin::TRIVIAL_CASTS) }; - let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); - let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); + let expr_ty = fcx.deep_resolve_non_region_vars(self.expr_ty); + let cast_ty = fcx.deep_resolve_non_region_vars(self.cast_ty); fcx.tcx.emit_node_span_lint( lint, self.expr.hir_id, @@ -786,8 +786,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { fn expr_span_for_type_resolution(&self, fcx: &FnCtxt<'a, 'tcx>) -> Span { if let hir::ExprKind::Index(_, idx, _) = self.expr.kind - && fcx.resolve_vars_if_possible(self.expr_ty).is_ty_var() - && fcx.resolve_vars_if_possible(fcx.node_ty(idx.hir_id)).is_ty_var() + && fcx.deep_resolve_non_region_vars(self.expr_ty).is_ty_var() + && fcx.deep_resolve_non_region_vars(fcx.node_ty(idx.hir_id)).is_ty_var() { index_operand_ambiguity_span(idx) } else { @@ -1134,8 +1134,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { mut m_cast: ty::TypeAndMut<'tcx>, ) -> Result> { // array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const - m_expr.ty = fcx.resolve_vars_with_obligations(m_expr.ty); - m_cast.ty = fcx.resolve_vars_with_obligations(m_cast.ty); + m_expr.ty = fcx.deep_resolve_non_regionvars_with_obligations(m_expr.ty); + m_cast.ty = fcx.deep_resolve_non_regionvars_with_obligations(m_cast.ty); if m_expr.mutbl >= m_cast.mutbl && let ty::Array(ety, _) = m_expr.ty.kind() diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index a9ce46b68527f..d53f63373904e 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -61,7 +61,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // type, and see if can glean a closure kind from there. let (expected_sig, expected_kind) = match expected.to_option(self) { Some(ty) => { - self.deduce_closure_signature(self.resolve_vars_with_obligations(ty), closure.kind) + self.deduce_closure_signature(self.deep_resolve_non_regionvars_with_obligations(ty), closure.kind) } None => (None, None), }; @@ -411,7 +411,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let inferred_fnptr_sig = Ty::new_fn_ptr(self.tcx, inferred_sig.sig); self.demand_eqtype(span, inferred_fnptr_sig, generalized_fnptr_sig); - let resolved_sig = self.resolve_vars_if_possible(generalized_fnptr_sig); + let resolved_sig = self.deep_resolve_non_region_vars(generalized_fnptr_sig); if resolved_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() { expected_sig = Some(ExpectedSig { @@ -517,7 +517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { cause_span: Option, projection: ty::PolyProjectionPredicate<'tcx>, ) -> Option> { - let projection = self.resolve_vars_if_possible(projection); + let projection = self.deep_resolve_non_region_vars(projection); let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1); debug!(?arg_param_ty); @@ -562,7 +562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { cause_span: Option, projection: ty::PolyProjectionPredicate<'tcx>, ) -> Option> { - let projection = self.resolve_vars_if_possible(projection); + let projection = self.deep_resolve_non_region_vars(projection); let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1); debug!(?arg_param_ty); @@ -852,7 +852,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { all_obligations.extend(obligations); let inputs = - supplied_sig.inputs().into_iter().map(|&ty| self.resolve_vars_if_possible(ty)); + supplied_sig.inputs().into_iter().map(|&ty| self.deep_resolve_non_region_vars(ty)); let fn_sig_kind = FnSigKind::default() .set_abi(ExternAbi::RustCall) @@ -959,7 +959,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let closure_span = self.tcx.def_span(body_def_id); let ret_ty = ret_coercion.borrow().expected_ty(); - let ret_ty = self.resolve_vars_with_obligations(ret_ty); + let ret_ty = self.deep_resolve_non_regionvars_with_obligations(ret_ty); let get_future_output = |clause: ty::Clause<'tcx>, span| { // Search for a pending obligation like @@ -1064,7 +1064,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Extract the type from the projection. Note that there can // be no bound variables in this type because the "self type" // does not have any regions in it. - let output_ty = self.resolve_vars_if_possible(predicate.term); + let output_ty = self.deep_resolve_non_region_vars(predicate.term); debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty); // This is a projection on a Fn trait so will always be a type. Some(output_ty.expect_type()) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 6aa88ee627e83..00115e6761e88 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -736,7 +736,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred))) if traits.contains(&trait_pred.def_id()) => { - self.resolve_vars_if_possible(trait_pred) + self.deep_resolve_non_region_vars(trait_pred) } _ => { coercion.obligations.push(obligation); @@ -1140,7 +1140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { allow_two_phase: AllowTwoPhase, cause: Option>, ) -> RelateResult<'tcx, Ty<'tcx>> { - let source = self.resolve_vars_with_obligations(expr_ty); + let source = self.deep_resolve_non_regionvars_with_obligations(expr_ty); debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target); let cause = @@ -1323,8 +1323,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { new: &hir::Expr<'_>, new_ty: Ty<'tcx>, ) -> RelateResult<'tcx, Ty<'tcx>> { - let prev_ty = self.resolve_vars_with_obligations(prev_ty); - let new_ty = self.resolve_vars_with_obligations(new_ty); + let prev_ty = self.deep_resolve_non_regionvars_with_obligations(prev_ty); + let new_ty = self.deep_resolve_non_regionvars_with_obligations(new_ty); debug!( "coercion::try_find_coercion_lub({:?}, {:?}, exprs={:?} exprs)", prev_ty, @@ -1743,7 +1743,7 @@ impl<'tcx> CoerceMany<'tcx> { fcx.set_tainted_by_errors( fcx.dcx().span_delayed_bug(cause.span, "coercion error but no error emitted"), ); - let (expected, found) = fcx.resolve_vars_if_possible((expected, found)); + let (expected, found) = fcx.deep_resolve_non_region_vars((expected, found)); let mut err; let mut unsized_return = false; diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 671bf52205689..b909de458bf9e 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -261,7 +261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, allow_two_phase: AllowTwoPhase, ) -> Result, Diag<'a>> { - let expected = self.resolve_vars_with_obligations(expected); + let expected = self.deep_resolve_non_regionvars_with_obligations(expected); let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) { Ok(ty) => return Ok(ty), @@ -276,7 +276,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); let expr = expr.peel_drop_temps(); let cause = self.misc(expr.span); - let expr_ty = self.resolve_vars_if_possible(checked_ty); + let expr_ty = self.deep_resolve_non_region_vars(checked_ty); let mut err = self.err_ctxt().report_mismatched_types(&cause, self.param_env, expected, expr_ty, e); @@ -423,7 +423,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Yeet the errors, we're already reporting errors. errs.clear(); }); - Some(self.resolve_vars_if_possible(possible_rcvr_ty)) + Some(self.deep_resolve_non_region_vars(possible_rcvr_ty)) }); let Some(rcvr_ty) = possible_rcvr_ty else { return false }; rcvr_ty @@ -546,7 +546,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .borrow() .type_dependent_def_id(parent_expr.hir_id) && let ideal_arg_ty = - self.resolve_vars_if_possible(ideal_method.sig.inputs()[idx + 1]) + self.deep_resolve_non_region_vars(ideal_method.sig.inputs()[idx + 1]) && !ideal_arg_ty.has_non_region_infer() { self.emit_type_mismatch_suggestions( diff --git a/compiler/rustc_hir_typeck/src/expectation.rs b/compiler/rustc_hir_typeck/src/expectation.rs index 37c8d7b2ae24e..b6d90a13c11c5 100644 --- a/compiler/rustc_hir_typeck/src/expectation.rs +++ b/compiler/rustc_hir_typeck/src/expectation.rs @@ -46,7 +46,7 @@ impl<'a, 'tcx> Expectation<'tcx> { ) -> Expectation<'tcx> { match *self { ExpectHasType(ety) => { - let ety = fcx.resolve_vars_with_obligations(ety); + let ety = fcx.deep_resolve_non_regionvars_with_obligations(ety); if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation } } ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety), @@ -93,9 +93,9 @@ impl<'a, 'tcx> Expectation<'tcx> { fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> { match self { NoExpectation => NoExpectation, - ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(t)), - ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(t)), - ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(t)), + ExpectCastableToType(t) => ExpectCastableToType(fcx.deep_resolve_non_region_vars(t)), + ExpectHasType(t) => ExpectHasType(fcx.deep_resolve_non_region_vars(t)), + ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.deep_resolve_non_region_vars(t)), } } @@ -112,7 +112,7 @@ impl<'a, 'tcx> Expectation<'tcx> { /// such a constraint, if it exists. pub(super) fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option> { match self { - ExpectHasType(ty) => Some(fcx.resolve_vars_if_possible(ty)), + ExpectHasType(ty) => Some(fcx.deep_resolve_non_region_vars(ty)), NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None, } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index cbbd66f648eb8..48f113e2a8a4f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -82,7 +82,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // While we don't allow *arbitrary* coercions here, we *do* allow // coercions from ! to `expected`. - if self.resolve_vars_with_obligations(ty).is_never() + if self.deep_resolve_non_regionvars_with_obligations(ty).is_never() && self.tcx.expr_guaranteed_to_constitute_read_for_never(expr) { if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) { @@ -271,7 +271,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) => self.check_expr_path(qpath, expr, call_expr_and_args), _ => self.check_expr_kind(expr, expected), }; - let ty = self.resolve_vars_if_possible(ty); + let ty = self.deep_resolve_non_region_vars(ty); // Warn for non-block expressions with diverging children. match expr.kind { @@ -300,7 +300,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // unless it's a place expression that isn't being read from, in which case // diverging would be unsound since we may never actually read the `!`. // e.g. `let _ = *never_ptr;` with `never_ptr: *const !`. - if self.resolve_vars_with_obligations(ty).is_never() + if self.deep_resolve_non_regionvars_with_obligations(ty).is_never() && self.tcx.expr_guaranteed_to_constitute_read_for_never(expr) { self.diverges.set(self.diverges.get() | Diverges::always(expr.span)); @@ -454,7 +454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| { - match self.resolve_vars_with_obligations(ty).kind() { + match self.deep_resolve_non_regionvars_with_obligations(ty).kind() { ty::Ref(_, ty, _) | ty::RawPtr(ty, _) => { if oprnd.is_syntactic_place_expr() { // Places may legitimately have unsized types. @@ -1467,7 +1467,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Expectation<'tcx>, ) -> Ty<'tcx> { let rcvr_t = self.check_expr(rcvr); - let rcvr_t = self.resolve_vars_with_obligations(rcvr_t); + let rcvr_t = self.deep_resolve_non_regionvars_with_obligations(rcvr_t); match self.lookup_method(rcvr_t, segment, segment.ident.span, expr, rcvr, args) { Ok(method) => { @@ -1538,9 +1538,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Find the type of `e`. Supply hints based on the type we are casting to, // if appropriate. let t_cast = self.lower_ty_saving_user_provided_ty(t); - let t_cast = self.resolve_vars_if_possible(t_cast); + let t_cast = self.deep_resolve_non_region_vars(t_cast); let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast)); - let t_expr = self.resolve_vars_if_possible(t_expr); + let t_expr = self.deep_resolve_non_region_vars(t_expr); // Eagerly check for some obvious errors. if let Err(guar) = (t_expr, t_cast).error_reported() { @@ -1662,11 +1662,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let coerce_to = expected .to_option(self) .and_then(|uty| { - self.resolve_vars_with_obligations(uty) + self.deep_resolve_non_regionvars_with_obligations(uty) .builtin_index() // Avoid using the original type variable as the coerce_to type, as it may resolve // during the first coercion instead of being the LUB type. - .filter(|t| !self.resolve_vars_with_obligations(*t).is_ty_var()) + .filter(|t| { + !self.deep_resolve_non_regionvars_with_obligations(*t).is_ty_var() + }) }) .unwrap_or_else(|| self.next_ty_var(expr.span)); let mut coerce = CoerceMany::with_capacity(coerce_to, args.len()); @@ -1791,7 +1793,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { let mut expectations = expected .only_has_type(self) - .and_then(|ty| self.resolve_vars_with_obligations(ty).opt_tuple_fields()) + .and_then(|ty| self.deep_resolve_non_regionvars_with_obligations(ty).opt_tuple_fields()) .unwrap_or_default() .iter(); @@ -1865,7 +1867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let tcx = self.tcx; - let adt_ty = self.resolve_vars_with_obligations(adt_ty); + let adt_ty = self.deep_resolve_non_regionvars_with_obligations(adt_ty); let adt_ty_hint = expected.only_has_type(self).and_then(|expected| { self.fudge_inference_if_ok(|| { let ocx = ObligationCtxt::new(self); @@ -1873,7 +1875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !ocx.try_evaluate_obligations().no_errors() { return Err(TypeError::Mismatch); } - Ok(self.resolve_vars_if_possible(adt_ty)) + Ok(self.deep_resolve_non_region_vars(adt_ty)) }) .ok() }); @@ -2131,7 +2133,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - self.resolve_vars_if_possible(fru_ty) + self.deep_resolve_non_region_vars(fru_ty) }) .collect(); // The use of fresh args that we have subtyped against @@ -2155,7 +2157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let fresh_base_ty = Ty::new_adt(self.tcx, *adt, fresh_args); self.check_expr_has_type_or_error( base_expr, - self.resolve_vars_if_possible(fresh_base_ty), + self.deep_resolve_non_region_vars(fresh_base_ty), |_| {}, ); fru_tys diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index b2255c8d9679a..552bc8a82a56d 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -157,7 +157,7 @@ pub trait TypeInformationCtxt<'tcx> { fn typeck_results(&self) -> Self::TypeckResults<'_>; - fn resolve_vars_if_possible>>(&self, t: T) -> T; + fn deep_resolve_non_region_vars>>(&self, t: T) -> T; fn structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>; @@ -188,8 +188,8 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { self.typeck_results.borrow() } - fn resolve_vars_if_possible>>(&self, t: T) -> T { - self.infcx.resolve_vars_if_possible(t) + fn deep_resolve_non_region_vars>>(&self, t: T) -> T { + self.infcx.deep_resolve_non_region_vars(t) } fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { @@ -242,7 +242,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { ty } - fn resolve_vars_if_possible>>(&self, t: T) -> T { + fn deep_resolve_non_region_vars>>(&self, t: T) -> T { t } @@ -1133,7 +1133,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ) -> Result, Cx::Error> { match ty { Some(ty) => { - let ty = self.cx.resolve_vars_if_possible(ty); + let ty = self.cx.deep_resolve_non_region_vars(ty); self.cx.error_reported_in_ty(ty)?; Ok(ty) } @@ -1272,7 +1272,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx where F: FnOnce() -> Result, Cx::Error>, { - let target = self.cx.resolve_vars_if_possible(adjustment.target); + let target = self.cx.deep_resolve_non_region_vars(adjustment.target); match adjustment.kind { adjustment::Adjust::Deref(deref_kind) => { // Equivalent to *expr or something similar. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 8ff4c3bf28c34..a28abd60ed4b7 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -141,11 +141,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Resolves type and const variables in `t` if possible. Unlike the infcx - /// version (resolve_vars_if_possible), this version will + /// version (deep_resolve_non_region_vars), this version will /// also select obligations if it seems useful, in an effort /// to get more type information. #[instrument(skip(self), level = "debug", ret)] - pub(crate) fn resolve_vars_with_obligations>>( + pub(crate) fn deep_resolve_non_regionvars_with_obligations>>( &self, mut t: T, ) -> T { @@ -156,7 +156,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // If `t` is a type variable, see whether we already know what it is. - t = self.resolve_vars_if_possible(t); + t = self.deep_resolve_non_region_vars(t); if !t.has_non_region_infer() { debug!(?t); return t; @@ -167,7 +167,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // indirect dependencies that don't seem worth tracking // precisely. self.select_obligations_where_possible(|_| {}); - self.resolve_vars_if_possible(t) + self.deep_resolve_non_region_vars(t) } pub(crate) fn record_deferred_call_resolution( @@ -199,7 +199,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[inline] pub(crate) fn write_ty(&self, id: HirId, ty: Ty<'tcx>) { - debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag()); + debug!("write_ty({:?}, {:?}) in fcx {}", id, self.deep_resolve_non_region_vars(ty), self.tag()); let mut typeck = self.typeck_results.borrow_mut(); let mut node_ty = typeck.node_types_mut(); @@ -1518,7 +1518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sp: Span, ct: ty::Const<'tcx>, ) -> ty::Const<'tcx> { - let ct = self.resolve_vars_with_obligations(ct); + let ct = self.deep_resolve_non_regionvars_with_obligations(ct); if self.next_trait_solver() && let ty::ConstKind::Alias(..) = ct.kind() @@ -1553,7 +1553,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// If no resolution is possible, then an error is reported. /// Numeric inference variables may be left unresolved. pub(crate) fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { - let ty = self.resolve_vars_with_obligations(ty); + let ty = self.deep_resolve_non_regionvars_with_obligations(ty); if !ty.is_ty_var() { ty } else { self.type_must_be_known_at_this_point(sp, ty) } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index be24a5e7d0b8c..356827793b5db 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -196,18 +196,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let hir::ExprKind::Index(indexed_expr, idx, _) = rhs_expr.kind else { return false; }; - if !self.resolve_vars_if_possible(self.node_ty(idx.hir_id)).is_ty_var() { + if !self.deep_resolve_non_region_vars(self.node_ty(idx.hir_id)).is_ty_var() { return false; } - let lhs_ty = self.resolve_vars_if_possible(self.node_ty(lhs_expr.hir_id)); - let indexed_ty = self.resolve_vars_if_possible(self.node_ty(indexed_expr.hir_id)); + let lhs_ty = self.deep_resolve_non_region_vars(self.node_ty(lhs_expr.hir_id)); + let indexed_ty = self.deep_resolve_non_region_vars(self.node_ty(indexed_expr.hir_id)); let rhs_ty = match *indexed_ty.kind() { ty::Array(element_ty, _) | ty::Slice(element_ty) => element_ty, ty::Ref(_, pointee_ty, _) => match *pointee_ty.kind() { ty::Array(element_ty, _) | ty::Slice(element_ty) => element_ty, - _ => self.resolve_vars_if_possible(self.node_ty(rhs_expr.hir_id)), + _ => self.deep_resolve_non_region_vars(self.node_ty(rhs_expr.hir_id)), }, - _ => self.resolve_vars_if_possible(self.node_ty(rhs_expr.hir_id)), + _ => self.deep_resolve_non_region_vars(self.node_ty(rhs_expr.hir_id)), }; if !self.binop_accepts_types(binop.node, lhs_ty, rhs_ty) { return false; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 9becad0db1ca2..74e94cf9e8c56 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -247,7 +247,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut expected_input_tys: Option> = expectation .only_has_type(self) .and_then(|expected_output| { - let formal_output = self.resolve_vars_with_obligations(formal_output); + let formal_output = + self.deep_resolve_non_regionvars_with_obligations(formal_output); // FIXME(#149379): This operation results in expected input // types which are potentially not well-formed or for whom the // function where-bounds don't actually hold. This results @@ -284,7 +285,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(Some( formal_input_tys .iter() - .map(|&ty| self.resolve_vars_if_possible(ty)) + .map(|&ty| self.deep_resolve_non_region_vars(ty)) .collect::>(), )) }) @@ -388,7 +389,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Cause selection errors caused by resolving a single argument to point at the // argument and not the call. This lets us customize the span pointed to in the // fulfillment error to be more accurate. - let coerced_ty = self.resolve_vars_with_obligations(coerced_ty); + let coerced_ty = self.deep_resolve_non_regionvars_with_obligations(coerced_ty); let coerce_error = self.coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None).err(); @@ -542,7 +543,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::FnDef(..) => { let fn_ptr = Ty::new_fn_ptr(self.tcx, arg_ty.fn_sig(self.tcx)); - let fn_ptr = self.resolve_vars_if_possible(fn_ptr).to_string(); + let fn_ptr = self.deep_resolve_non_region_vars(fn_ptr).to_string(); let fn_item_spa = arg.span; tcx.sess.dcx().emit_err(diagnostics::PassFnItemToVariadicFunction { @@ -573,7 +574,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .copied() .zip_eq(expected_input_tys.iter().copied()) - .map(|vars| self.resolve_vars_if_possible(vars)), + .map(|vars| self.deep_resolve_non_region_vars(vars)), ); self.report_arg_errors( @@ -653,7 +654,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let formal_input_tupled_ty = formal_input_tys[first_tupled_arg_index_usz]; // Keep the type variable if the argument is splatted, so we can force it to be a tuple later. let tuple_type = if tuple_arguments.is_splatted() { - let callee_tuple_type = self.resolve_vars_with_obligations(formal_input_tupled_ty); + let callee_tuple_type = + self.deep_resolve_non_regionvars_with_obligations(formal_input_tupled_ty); if callee_tuple_type.is_ty_var() && let Some(tupled_args_count) = tupled_args_count { @@ -1836,7 +1838,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { param.param.span(), format!( "this parameter needs to match the {} type of {deps_list}", - self.resolve_vars_if_possible( + self.deep_resolve_non_region_vars( formal_and_expected_inputs[param.deps[0]].1 ) .sort_string(self.tcx), @@ -1860,8 +1862,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!( "{deps_list} need{} to match the {} type of this parameter", pluralize!((deps.len() != 1) as u32), - self.resolve_vars_if_possible(expected_ty) - .sort_string(self.tcx), + self.deep_resolve_non_region_vars(expected_ty).sort_string(self.tcx), ), ); } @@ -2039,7 +2040,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let expected_display_type = self - .resolve_vars_if_possible(formal_and_expected_inputs[idx].1) + .deep_resolve_non_region_vars(formal_and_expected_inputs[idx].1) .sort_string(self.tcx); let label = if idxs_matched == params_with_generics.len() - 1 { format!( @@ -3333,10 +3334,7 @@ impl<'a, 'tcx> ArgsCtxt<'a, 'tcx> { .borrow() .expr_ty_adjusted_opt(expr) .unwrap_or_else(|| Ty::new_misc_error(self.call_ctxt.fn_ctxt.tcx)); - ( - self.call_ctxt.fn_ctxt.resolve_vars_if_possible(ty), - self.normalize_span(expr.span), - ) + (self.call_ctxt.fn_ctxt.deep_resolve_non_region_vars(ty), self.normalize_span(expr.span)) }) .collect() } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index e6de8b55ef2f9..1b3e275e26722 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -139,7 +139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } obligations_for_self_ty.retain_mut(|obligation| { - obligation.predicate = self.resolve_vars_if_possible(obligation.predicate); + obligation.predicate = self.deep_resolve_non_region_vars(obligation.predicate); !obligation.predicate.has_placeholders() }); obligations_for_self_ty diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 506e2822a8745..905aeeb6b4ebd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -262,8 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { found_type: Ty<'tcx>, ) -> bool { let tcx = self.tcx; - let expected = self.resolve_vars_if_possible(expected_type); - let found = self.resolve_vars_if_possible(found_type); + let expected = self.deep_resolve_non_region_vars(expected_type); + let found = self.deep_resolve_non_region_vars(found_type); if expected.references_error() || found.references_error() || expected.is_unit() { return false; @@ -991,8 +991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - let found = - self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found)); + let found = self.resolve_numeric_literals_with_default(self.deep_resolve_non_region_vars(found)); // Only suggest changing the return type for methods that // haven't set a return type at all (and aren't `fn main()`, impl or closure). match &fn_decl.output { @@ -1322,7 +1321,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !expected.is_unit() { return; } - let found = self.resolve_vars_if_possible(found); + let found = self.deep_resolve_non_region_vars(found); let innermost_loop = if self.is_loop(id) { Some(self.tcx.hir_node(id)) diff --git a/compiler/rustc_hir_typeck/src/inline_asm.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs index cfe64fce180e9..7928ca7019f31 100644 --- a/compiler/rustc_hir_typeck/src/inline_asm.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -45,7 +45,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> { let ty = self.fcx.typeck_results.borrow().expr_ty_adjusted(expr); - let ty = self.fcx.resolve_vars_with_obligations(ty); + let ty = self.fcx.deep_resolve_non_regionvars_with_obligations(ty); if ty.has_non_region_infer() { Ty::new_misc_error(self.tcx()) } else { @@ -60,7 +60,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if self.fcx.type_is_sized_modulo_regions(self.fcx.param_env, ty) { return true; } - if let ty::Foreign(..) = self.fcx.resolve_vars_with_obligations(ty).kind() { + if let ty::Foreign(..) = self.fcx.deep_resolve_non_regionvars_with_obligations(ty).kind() { return true; } false diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index b2e0a3bd7a195..f0c88f1e428c2 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -2133,8 +2133,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { for nested_obligation in candidate.nested_obligations() { if !self.infcx.predicate_may_hold(&nested_obligation) { possibly_unsatisfied_predicates.push(( - self.resolve_vars_if_possible(nested_obligation.predicate), - Some(self.resolve_vars_if_possible(obligation.predicate)), + self.deep_resolve_non_region_vars( + nested_obligation.predicate, + ), + Some( + self.deep_resolve_non_region_vars(obligation.predicate), + ), Some(nested_obligation.cause), )); } @@ -2206,9 +2210,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Evaluate those obligations to see if they might possibly hold. for error in ocx.try_evaluate_obligations() { result = ProbeResult::NoMatch; - let nested_predicate = self.resolve_vars_if_possible(error.obligation.predicate); + let nested_predicate = + self.deep_resolve_non_region_vars(error.obligation.predicate); if let Some(trait_predicate) = trait_predicate - && nested_predicate == self.resolve_vars_if_possible(trait_predicate) + && nested_predicate == self.deep_resolve_non_region_vars(trait_predicate) { // Don't report possibly unsatisfied predicates if the root // trait obligation from a `TraitCandidate` is unsatisfied. @@ -2216,7 +2221,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } else { possibly_unsatisfied_predicates.push(( nested_predicate, - Some(self.resolve_vars_if_possible(error.root_obligation.predicate)) + Some(self.deep_resolve_non_region_vars(error.root_obligation.predicate)) .filter(|root_predicate| *root_predicate != nested_predicate), Some(error.obligation.cause), )); @@ -2337,7 +2342,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return false; } - !self.resolve_vars_if_possible(self_ty).is_ty_var() + !self.deep_resolve_non_region_vars(self_ty).is_ty_var() }); if constrained_opaque { debug!("opaque type has been constrained"); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a22b6f746a952..3c4fdcd9762f5 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1254,7 +1254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { within_macro_span: Option, ) -> ErrorGuaranteed { let tcx = self.tcx; - let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); + let rcvr_ty = self.deep_resolve_non_region_vars(rcvr_ty); if let Err(guar) = rcvr_ty.error_reported() { return guar; @@ -2256,7 +2256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("{item_kind} `{item_name}` is available on `{prev_match}`"), ); } - let rcvr_ty = self.resolve_vars_if_possible( + let rcvr_ty = self.deep_resolve_non_region_vars( self.typeck_results .borrow() .expr_ty_adjusted_opt(rcvr_expr) @@ -3307,7 +3307,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let field_ty = field.ty(tcx, args).skip_norm_wip(); // Skip `_`, since that'll just lead to ambiguity. - if self.resolve_vars_if_possible(field_ty).is_ty_var() { + if self.deep_resolve_non_region_vars(field_ty).is_ty_var() { return None; } @@ -3327,7 +3327,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(ret_ty) = self .ret_coercion .as_ref() - .map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty())) + .map(|c| self.deep_resolve_non_region_vars(c.borrow().expected_ty())) && let ty::Adt(kind, _) = ret_ty.kind() && tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did()) { @@ -3883,7 +3883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type: Option>, ) { let Some(output_ty) = self.tcx.get_impl_future_output_ty(ty) else { return }; - let output_ty = self.resolve_vars_if_possible(output_ty); + let output_ty = self.deep_resolve_non_region_vars(output_ty); let method_exists = self.method_exists_for_diagnostic(item_name, output_ty, call.hir_id, return_type); debug!("suggest_await_before_method: is_method_exist={}", method_exists); diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index c28976555432b..fe1bfaa0a1209 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -221,7 +221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_expr(lhs_expr) } }; - let lhs_ty = self.resolve_vars_with_obligations(lhs_ty); + let lhs_ty = self.deep_resolve_non_regionvars_with_obligations(lhs_ty); // N.B., as we have not yet type-checked the RHS, we don't have the // type at hand. Make a variable to represent it. The whole reason @@ -256,7 +256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }, ); - let rhs_ty = self.resolve_vars_with_obligations(rhs_ty); + let rhs_ty = self.deep_resolve_non_regionvars_with_obligations(rhs_ty); let return_ty = self.overloaded_binop_ret_ty( expr, lhs_expr, rhs_expr, op, expected, lhs_ty, result, rhs_ty, @@ -979,7 +979,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method.sig.output() } Err(errors) => { - let actual = self.resolve_vars_if_possible(operand_ty); + let actual = self.deep_resolve_non_region_vars(operand_ty); let guar = actual.error_reported().err().unwrap_or_else(|| { let mut file = None; let ty_str = self.tcx.short_string(actual, &mut file); diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index 17e193d7f44ab..54ecc49d75b81 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -93,7 +93,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { error_on_missing_defining_use: bool, ) { for entry in opaque_types.iter_mut() { - *entry = self.resolve_vars_if_possible(*entry); + *entry = self.deep_resolve_non_region_vars(*entry); } debug!(?opaque_types); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index f7ba6a78c65bd..1c6382987d3d1 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -497,7 +497,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expected = if let AdjustMode::Peel { .. } = adjust_mode && pat.default_binding_modes { - self.resolve_vars_with_obligations(expected) + self.deep_resolve_non_regionvars_with_obligations(expected) } else { expected }; @@ -794,14 +794,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lt.kind ); } - // Call `resolve_vars_if_possible` here for inline const blocks. - let lit_ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt)); + // Call `deep_resolve_non_region_vars` here for inline const blocks. + let lit_ty = self.deep_resolve_non_region_vars(self.check_pat_expr_unadjusted(lt)); // If `deref_patterns` is enabled, allow `if let "foo" = &&"foo" {}`. if self.tcx.features().deref_patterns() { let mut peeled_ty = lit_ty; let mut pat_ref_layers = 0; while let ty::Ref(_, inner_ty, mutbl) = - *self.resolve_vars_with_obligations(peeled_ty).kind() + *self.deep_resolve_non_regionvars_with_obligations(peeled_ty).kind() { // We rely on references at the head of constants being immutable. debug_assert!(mutbl.is_not()); @@ -947,7 +947,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *expected.kind() { // Allow `b"...": &[u8]` ty::Ref(_, inner_ty, _) - if self.resolve_vars_with_obligations(inner_ty).is_slice() => + if self.deep_resolve_non_regionvars_with_obligations(inner_ty).is_slice() => { trace!(?expr.hir_id.local_id, "polymorphic byte string lit"); pat_ty = Ty::new_imm_ref( @@ -976,7 +976,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // string literal patterns to have type `str`. This is accounted for when lowering to MIR. if self.tcx.features().deref_patterns() && matches!(lit_kind, ast::LitKind::Str(..)) - && self.resolve_vars_with_obligations(expected).is_str() + && self.deep_resolve_non_regionvars_with_obligations(expected).is_str() { pat_ty = self.tcx.types.str_; } @@ -994,7 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let cause = self.pattern_cause(ti, span); if let Err(mut err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) { // If scrutinee is String and pattern is &str, suggest .as_str() - let expected = self.resolve_vars_with_obligations(expected); + let expected = self.deep_resolve_non_regionvars_with_obligations(expected); if let ty::Adt(adt, _) = expected.kind() && self.tcx.is_lang_item(adt.did(), LangItem::String) && pat_ty.is_ref() @@ -1032,7 +1032,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // be peeled to `str` while ty here is still `&str`, if we don't // err early here, a rather confusing unification error will be // emitted instead). - let ty = self.resolve_vars_with_obligations(ty); + let ty = self.deep_resolve_non_regionvars_with_obligations(ty); let fail = !(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error()); Some((fail, ty, expr.span)) @@ -1111,13 +1111,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "only `char` and numeric types are allowed in range patterns" ); let msg = |ty| { - let ty = self.resolve_vars_if_possible(ty); + let ty = self.deep_resolve_non_region_vars(ty); format!("this is of type `{ty}` but it should be `char` or numeric") }; let mut one_side_err = |first_span, first_ty, second: Option<(bool, Ty<'tcx>, Span)>| { err.span_label(first_span, msg(first_ty)); if let Some((_, ty, sp)) = second { - let ty = self.resolve_vars_if_possible(ty); + let ty = self.deep_resolve_non_region_vars(ty); self.endpoint_has_type(&mut err, sp, ty); } }; @@ -1293,7 +1293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let var_ty = self.local_ty(span, var_id); if let Err(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) { - let var_ty = self.resolve_vars_if_possible(var_ty); + let var_ty = self.deep_resolve_non_region_vars(var_ty); let msg = format!("first introduced with type `{var_ty}` here"); err.span_label(self.tcx.hir_span(var_id), msg); let in_match = self.tcx.hir_parent_iter(var_id).any(|(_, n)| { @@ -1311,7 +1311,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut err, span, var_ty, - self.resolve_vars_if_possible(ty), + self.deep_resolve_non_region_vars(ty), ba, ); err.emit(); @@ -2764,7 +2764,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [source_ty], ); let target_ty = self.normalize(span, Unnormalized::new_wip(target_ty)); - self.resolve_vars_with_obligations(target_ty) + self.deep_resolve_non_regionvars_with_obligations(target_ty) } /// Check if the interior of a deref pattern (either explicit or implicit) has any `ref mut` @@ -2812,7 +2812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span); } - expected = self.resolve_vars_with_obligations(expected); + expected = self.deep_resolve_non_regionvars_with_obligations(expected); // Determine whether we're consuming an inherited reference and resetting the default // binding mode, based on edition and enabled experimental features. if let ByRef::Yes(inh_pin, inh_mut) = pat_info.binding_mode @@ -3103,7 +3103,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { - let expected = self.resolve_vars_with_obligations(expected); + let expected = self.deep_resolve_non_regionvars_with_obligations(expected); // If the pattern is irrefutable and `expected` is an infer ty, we try to equate it // to an array if the given pattern allows it. See issue #76342 @@ -3281,7 +3281,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Some(span) = ti.span && let Some(_) = ti.origin_expr { - let resolved_ty = self.resolve_vars_if_possible(ti.expected); + let resolved_ty = self.deep_resolve_non_region_vars(ti.expected); let (is_slice_or_array_or_vector, resolved_ty) = self.is_slice_or_array_or_vector(resolved_ty); match resolved_ty.kind() { diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index b3ac237adf956..e3956897243f8 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -74,7 +74,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, base_expr: &hir::Expr<'_>, ) -> Option<(Ty<'tcx>, Ty<'tcx>)> { - let ty = self.resolve_vars_if_possible(ty); + let ty = self.deep_resolve_non_region_vars(ty); let mut err = self.dcx().struct_span_err( span, format!("negative integers cannot be used to index on a `{ty}`"), diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 91771fb37d18a..18cd0bb26c0b5 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -194,7 +194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } }; - let args = self.resolve_vars_if_possible(args); + let args = self.deep_resolve_non_region_vars(args); let closure_def_id = closure_def_id.expect_local(); assert_eq!(self.tcx.hir_body_owner_def_id(body.id()), closure_def_id); @@ -1242,7 +1242,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let root_var_min_capture_list = min_captures.and_then(|m| m.get(&var_hir_id))?; - let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id)); + let ty = self.deep_resolve_non_region_vars(self.node_ty(var_hir_id)); let ty = match closure_clause { hir::CaptureBy::Value { .. } => ty, // For move closure the capture kind should be by value @@ -1340,7 +1340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_clause: hir::CaptureBy, var_hir_id: HirId, ) -> Option> { - let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id)); + let ty = self.deep_resolve_non_region_vars(self.node_ty(var_hir_id)); // FIXME(#132279): Using `non_body_analysis` here feels wrong. if !ty.has_significant_drop( diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 7b1f38f882747..d3e9c357a9de4 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -808,7 +808,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { if self.fcx.tainted_by_errors().is_none() { for obligation in obligations { let (predicate, mut cause) = - self.fcx.resolve_vars_if_possible((obligation.predicate, obligation.cause)); + self.fcx.deep_resolve_non_region_vars((obligation.predicate, obligation.cause)); if predicate.has_non_region_infer() { self.fcx.dcx().span_delayed_bug( cause.span, @@ -833,7 +833,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { where T: TypeFoldable>, { - let value = self.fcx.resolve_vars_if_possible(value); + let value = self.fcx.deep_resolve_non_region_vars(value); let mut goals = vec![]; let value = @@ -847,7 +847,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { goals .into_iter() .map(|pred| { - self.fcx.resolve_vars_if_possible(pred).fold_with(&mut Resolver::new( + self.fcx.deep_resolve_non_region_vars(pred).fold_with(&mut Resolver::new( self.fcx, span, self.body, @@ -876,7 +876,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { where T: TypeFoldable>, { - let value = self.fcx.resolve_vars_if_possible(value); + let value = self.fcx.deep_resolve_non_region_vars(value); let mut goals = vec![]; let value = diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index a7551afd46124..d7918f1583e39 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -283,11 +283,11 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.shallow_resolve_const(ct) } - fn resolve_vars_if_possible(&self, value: T) -> T + fn deep_resolve_non_region_vars(&self, value: T) -> T where T: TypeFoldable>, { - self.resolve_vars_if_possible(value) + self.deep_resolve_non_region_vars(value) } fn probe(&self, probe: impl FnOnce() -> T) -> T { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e02329a57f338..06ff8d0942642 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1209,7 +1209,7 @@ impl<'tcx> InferCtxt<'tcx> { } pub fn ty_to_string(&self, t: Ty<'tcx>) -> String { - self.resolve_vars_if_possible(t).to_string() + self.deep_resolve_non_region_vars(t).to_string() } /// If `TyVar(vid)` resolves to a type, return that type. Else, return the @@ -1399,7 +1399,7 @@ impl<'tcx> InferCtxt<'tcx> { /// /// The "shallow" part of the name refers to the fact that types may themselves contain more /// type variables. e.g. The field types of a struct. `shallow_resolve` does not recurse into - /// these nested variables. If that's what you want, use [`resolve_vars_if_possible`](Self::resolve_vars_if_possible) + /// these nested variables. If that's what you want, use [`deep_resolve_non_region_vars`](Self::deep_resolve_non_region_vars) pub fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> { if let ty::Infer(infer) = *ty.kind() { self.shallow_resolve_infer(infer, ty) } else { ty } } @@ -1482,13 +1482,14 @@ impl<'tcx> InferCtxt<'tcx> { self.shallow_resolve_const_var_with_ct(vid, None) } - /// Where possible, replaces type/const variables in - /// `value` with their final value. Note that region variables - /// are unaffected. If a type/const variable has not been unified, it - /// is left as is. This is an idempotent operation that does - /// not affect inference state in any way and so you can do it - /// at will. - pub fn resolve_vars_if_possible(&self, value: T) -> T + /// Where possible, replaces type/const variables in `value` with their final value. + /// If a type/const variable has not (yet) been unified, it is left as is. + /// + /// This is an idempotent operation that does not affect inference state in any way, + /// which means it's safe to call this function at will. + /// + /// Region variables are unaffected. + pub fn deep_resolve_non_region_vars(&self, value: T) -> T where T: TypeFoldable>, { @@ -1498,7 +1499,7 @@ impl<'tcx> InferCtxt<'tcx> { if !value.has_non_region_infer() { return value; } - let mut r = resolve::OpportunisticVarResolver::new(self); + let mut r = resolve::DeepNonRegionResolver::new(self); value.fold_with(&mut r) } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 08c7c49417124..a96303774f47c 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -166,7 +166,7 @@ impl<'tcx> InferCtxt<'tcx> { } else if let Some(res) = process(b, a) { res } else { - let (a, b) = self.resolve_vars_if_possible((a, b)); + let (a, b) = self.deep_resolve_non_region_vars((a, b)); Err(TypeError::Sorts(ExpectedFound::new(a, b))) } } diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 4a107b1325932..2a0d993a8522f 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -36,7 +36,7 @@ impl<'tcx> InferCtxt<'tcx> { /// Process the region constraints and return any errors that /// result. After this, no more unification operations should be /// done -- or the compiler will panic -- but it is legal to use - /// `resolve_vars_if_possible` as well as `fully_resolve`. + /// `deep_resolve_non_region_vars` as well as `fully_resolve`. /// /// Don't call this directly unless you know what you're doing. /// You probably want to use `resolve_regions` instead. diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 570223b2b4881..a35b23971fcd2 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -66,7 +66,7 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::outlives::{Component, push_outlives_components}; use rustc_middle::ty::{ self, GenericArgKind, GenericArgsRef, PolyTypeOutlivesClause, Region, RegionExt, RegionVid, Ty, - TyCtxt, TypeVisitableExt, eager_resolve_vars, + TyCtxt, TypeVisitableExt, deep_resolve_vars, }; use rustc_span::Span; use smallvec::smallvec; @@ -318,7 +318,7 @@ impl<'tcx> InferCtxt<'tcx> { // `TypeOutlives` is structural, so we should try to opportunistically resolve all // region vids before processing regions, so we have a better chance to match clauses // in our param-env. - let (sup_type, sub_region) = eager_resolve_vars(self, (sup_type, sub_region)); + let (sup_type, sub_region) = deep_resolve_vars(self, (sup_type, sub_region)); if self.tcx.sess.opts.unstable_opts.higher_ranked_assumptions && outlives_env diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index e38492c921528..5b39c3b694ea3 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -8,28 +8,28 @@ use super::{FixupError, FixupResult, InferCtxt}; use crate::infer::TyOrConstInferVar; /////////////////////////////////////////////////////////////////////////// -// OPPORTUNISTIC VAR RESOLVER +// DEEP VAR RESOLVER -/// The opportunistic resolver can be used at any time. It simply replaces +/// The type and const resolver can be used at any time. It simply replaces /// type/const variables that have been unified with the things they have /// been unified with (similar to `shallow_resolve`, but deep). This is /// useful for printing messages etc but also required at various /// points for correctness. -pub struct OpportunisticVarResolver<'a, 'tcx> { +pub struct DeepNonRegionResolver<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, /// We're able to use a cache here as the folder does /// not have any mutable state. cache: DelayedMap, Ty<'tcx>>, } -impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> { +impl<'a, 'tcx> DeepNonRegionResolver<'a, 'tcx> { #[inline] pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { - OpportunisticVarResolver { infcx, cache: Default::default() } + DeepNonRegionResolver { infcx, cache: Default::default() } } } -impl<'a, 'tcx> TypeFolder> for OpportunisticVarResolver<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for DeepNonRegionResolver<'a, 'tcx> { fn cx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -66,24 +66,24 @@ impl<'a, 'tcx> TypeFolder> for OpportunisticVarResolver<'a, 'tcx> { } } -/// The opportunistic region resolver opportunistically resolves regions -/// variables to the variable with the least variable id. It is used when -/// normalizing projections to avoid hitting the recursion limit by creating -/// many versions of a predicate for types that in the end have to unify. +/// The region resolver resolves region variables to the variable with the +/// least variable id. It is used when normalizing projections to avoid +/// hitting the recursion limit by creating many versions of a predicate +/// for types that in the end have to unify. /// /// If you want to resolve type and const variables as well, call -/// [InferCtxt::resolve_vars_if_possible] first. -pub struct OpportunisticRegionResolver<'a, 'tcx> { +/// [InferCtxt::deep_resolve_non_region_vars] first. +pub struct DeepRegionResolver<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, } -impl<'a, 'tcx> OpportunisticRegionResolver<'a, 'tcx> { +impl<'a, 'tcx> DeepRegionResolver<'a, 'tcx> { pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { - OpportunisticRegionResolver { infcx } + DeepRegionResolver { infcx } } } -impl<'a, 'tcx> TypeFolder> for OpportunisticRegionResolver<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for DeepRegionResolver<'a, 'tcx> { fn cx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index 2ce98b7541afa..f3b33d8585a31 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -111,7 +111,7 @@ impl<'tcx> InferCtxt<'tcx> { // going to be popped, so we will have to // eliminate any references to them. let snapshot_vars = SnapshotVarData::new(self, variable_lengths); - Ok((snapshot_vars, self.resolve_vars_if_possible(value))) + Ok((snapshot_vars, self.deep_resolve_non_region_vars(value))) })?; // At this point, we need to replace any of the now-popped diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index 093b930ce9c70..d954ea23f043c 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -19,7 +19,7 @@ use rustc_type_ir::relate::{ }; use rustc_type_ir::{ self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, Region, - TypeFoldable, TypingMode, TypingModeEqWrapper, eager_resolve_vars, + TypeFoldable, TypingMode, TypingModeEqWrapper, deep_resolve_vars, }; use thin_vec::ThinVec; use tracing::instrument; @@ -554,7 +554,7 @@ where { let var_values = CanonicalVarValues { var_values: delegate.cx().mk_args(var_values) }; let state = inspect::State { var_values, data }; - let state = eager_resolve_vars(&**delegate, state); + let state = deep_resolve_vars(&**delegate, state); Canonicalizer::canonicalize_response(delegate, max_input_universe, state) } diff --git a/compiler/rustc_next_trait_solver/src/normalize.rs b/compiler/rustc_next_trait_solver/src/normalize.rs index ff9ed6cb06cfd..356690222c0c8 100644 --- a/compiler/rustc_next_trait_solver/src/normalize.rs +++ b/compiler/rustc_next_trait_solver/src/normalize.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use rustc_type_ir::inherent::*; use rustc_type_ir::{ self as ty, AliasTerm, Binder, FallibleTypeFolder, InferCtxtLike, Interner, TypeFoldable, - TypeSuperFoldable, TypeVisitableExt, UniverseIndex, eager_resolve_vars, + TypeSuperFoldable, TypeVisitableExt, UniverseIndex, deep_resolve_vars, }; use tracing::instrument; @@ -139,8 +139,8 @@ where if self.cx().renormalize_rigid_aliases() && orig_is_rigid == ty::IsRigid::Yes { // find out missing typing env change. - let original = eager_resolve_vars(infcx, original); - let normalized = eager_resolve_vars(infcx, normalized); + let original = deep_resolve_vars(infcx, original); + let normalized = deep_resolve_vars(infcx, normalized); assert_eq!(original, normalized, "rigid alias is further normalized"); } Ok(normalized) @@ -189,8 +189,8 @@ where if self.cx().renormalize_rigid_aliases() && orig_is_rigid == ty::IsRigid::Yes { // find out missing typing env change. - let original = eager_resolve_vars(infcx, original); - let normalized = eager_resolve_vars(infcx, normalized); + let original = deep_resolve_vars(infcx, original); + let normalized = deep_resolve_vars(infcx, normalized); assert_eq!(original, normalized, "rigid alias is further normalized"); } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 040f98de7bcfd..de6d7f08d1b0c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -458,7 +458,7 @@ where // Vars that show up in the rest of the goal substs may have been constrained by // normalizing the self type as well, since type variables are not uniquified. - let goal = self.resolve_vars_if_possible(goal); + let goal = self.deep_resolve_non_region_vars(goal); if self.typing_mode().is_coherence() && let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index ba06f8a2a0193..3450f1cfac799 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -17,7 +17,7 @@ use rustc_type_ir::solve::{ use rustc_type_ir::{ self as ty, CanonicalVarValues, ClauseKind, InferCtxtLike, Interner, MayBeErased, OpaqueTypeKey, PredicateKind, Region, TypeFoldable, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, TypingMode, eager_resolve_vars, + TypeVisitableExt, TypeVisitor, TypingMode, deep_resolve_vars, }; use thin_vec::ThinVec; use tracing::{Level, debug, instrument, trace, warn}; @@ -662,7 +662,7 @@ where // so we only canonicalize the lookup table and ignore // duplicate entries. let opaque_types = self.delegate.clone_opaque_types_lookup_table(); - let (goal, opaque_types) = eager_resolve_vars(&**self.delegate, (goal, opaque_types)); + let (goal, opaque_types) = deep_resolve_vars(&**self.delegate, (goal, opaque_types)); let typing_mode = self.typing_mode(); let step_kind = self.step_kind_for_source(source); @@ -1302,11 +1302,11 @@ where }) } - pub(super) fn resolve_vars_if_possible(&self, value: T) -> T + pub(super) fn deep_resolve_non_region_vars(&self, value: T) -> T where T: TypeFoldable, { - self.delegate.resolve_vars_if_possible(value) + self.delegate.deep_resolve_non_region_vars(value) } pub(super) fn shallow_resolve(&self, ty: I::Ty) -> I::Ty { @@ -1432,14 +1432,14 @@ where self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } None if self.cx().features().generic_const_args() => { - // HACK(khyperia): calling `resolve_vars_if_possible` here shouldn't be necessary, - // `try_evaluate_const` calls `resolve_vars_if_possible` already. However, we want + // HACK(khyperia): calling `deep_resolve_non_region_vars` here shouldn't be necessary, + // `try_evaluate_const` calls `deep_resolve_non_region_vars` already. However, we want // to check `has_non_region_infer` against the type with vars resolved (i.e. check // if there are vars we failed to resolve), so we need to call it again here. // Perhaps we could split EvaluateConstErr::HasGenericsOrInfers into HasGenerics and // HasInfers or something, make evaluate_const return that, and make this branch be // based on that, rather than checking `has_non_region_infer`. - if self.resolve_vars_if_possible(alias_const).has_non_region_infer() { + if self.deep_resolve_non_region_vars(alias_const).has_non_region_infer() { self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } else { // We do not instantiate to the `alias_const` passed in, but rather @@ -1602,7 +1602,7 @@ where let external_constraints = self.compute_external_query_constraints(certainty, normalization_nested_goals); let (var_values, mut external_constraints) = - eager_resolve_vars(&**self.delegate, (self.var_values, external_constraints)); + deep_resolve_vars(&**self.delegate, (self.var_values, external_constraints)); // Remove any trivial or duplicated region constraints once we've resolved regions let mut unique = HashSet::default(); @@ -1700,7 +1700,7 @@ where param_env: I::ParamEnv, value: ty::Unnormalized, ) -> Result { - let value = self.delegate.resolve_vars_if_possible(value.skip_normalization()); + let value = self.delegate.deep_resolve_non_region_vars(value.skip_normalization()); if !self.cx().renormalize_rigid_aliases() && !value.has_non_rigid_aliases() { return Ok(value); @@ -1723,7 +1723,7 @@ where } }; - Ok((self.resolve_vars_if_possible(infer_term), normalization_was_ambiguous)) + Ok((self.deep_resolve_non_region_vars(infer_term), normalization_was_ambiguous)) }); value.try_fold_with(&mut folder) } @@ -1856,7 +1856,7 @@ pub(super) fn evaluate_root_goal_for_proof_tree, root_depth: usize, ) -> (Result, NoSolution>, inspect::GoalEvaluation) { let opaque_types = delegate.clone_opaque_types_lookup_table(); - let (goal, opaque_types) = eager_resolve_vars(&**delegate, (goal, opaque_types)); + let (goal, opaque_types) = deep_resolve_vars(&**delegate, (goal, opaque_types)); let typing_mode = delegate.typing_mode_raw().assert_not_erased(); let (orig_values, canonical_goal) = diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 3504882834268..81131a34a3fdc 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -400,7 +400,7 @@ where // types from candidates. self.add_goal(GoalSource::TypeRelating, projection_goal)?; self.try_evaluate_added_goals()?; - Ok(self.resolve_vars_if_possible(normalized_term)) + Ok(self.deep_resolve_non_region_vars(normalized_term)) } else { Ok(term) } diff --git a/compiler/rustc_public/src/unstable/internal_cx/mod.rs b/compiler/rustc_public/src/unstable/internal_cx/mod.rs index f178ced7224c1..6bc553aed89e9 100644 --- a/compiler/rustc_public/src/unstable/internal_cx/mod.rs +++ b/compiler/rustc_public/src/unstable/internal_cx/mod.rs @@ -79,9 +79,9 @@ impl<'tcx> InternalCx<'tcx> for TyCtxt<'tcx> { where I: Iterator, T: ty::CollectAndApply< - ty::BoundVariableKind<'tcx>, - &'tcx List>, - >, + ty::BoundVariableKind<'tcx>, + &'tcx List>, + >, { TyCtxt::mk_bound_variable_kinds_from_iter(self, iter) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 1210a3ef57e32..9079d27de16ec 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -131,7 +131,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let ocx = ObligationCtxt::new(self); let normalized_fn_sig = ocx.normalize(&ObligationCause::dummy(), param_env, fn_sig); if ocx.evaluate_obligations_error_on_ambiguity().no_errors() { - let normalized_fn_sig = self.resolve_vars_if_possible(normalized_fn_sig); + let normalized_fn_sig = self.deep_resolve_non_region_vars(normalized_fn_sig); if !normalized_fn_sig.has_infer() { return normalized_fn_sig; } @@ -159,7 +159,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { where M: FnOnce(String) -> Diag<'a>, { - let actual_ty = self.resolve_vars_if_possible(actual_ty); + let actual_ty = self.deep_resolve_non_region_vars(actual_ty); debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty); let mut err = mk_diag(self.ty_to_string(actual_ty)); @@ -337,7 +337,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span: Some(span), root_ty, } => { - let expected_ty = self.resolve_vars_if_possible(root_ty); + let expected_ty = self.deep_resolve_non_region_vars(root_ty); if !matches!( expected_ty.kind(), ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)) @@ -467,7 +467,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } _ => { // `prior_arm_ty` can be `!`, `expected` will have better info when present. - let t = self.resolve_vars_if_possible(match exp_found { + let t = self.deep_resolve_non_region_vars(match exp_found { Some(ty::error::ExpectedFound { expected, .. }) => expected, _ => prior_arm_ty, }); @@ -1572,7 +1572,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let (expected_found, exp_found, is_simple_error, values, param_env) = match values { None => (None, Mismatch::Fixed("type"), false, None, None), Some(ty::ParamEnvAnd { param_env, value: values }) => { - let mut values = self.resolve_vars_if_possible(values); + let mut values = self.deep_resolve_non_region_vars(values); if self.next_trait_solver() { values = deeply_normalize_for_diagnostics(self, param_env, values); } @@ -1986,7 +1986,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) -> Vec { let mut suggestions = Vec::new(); let span = trace.cause.span; - let values = self.resolve_vars_if_possible(trace.values); + let values = self.deep_resolve_non_region_vars(trace.values); if let Some((expected, found)) = values.ty() { match (expected.kind(), found.kind()) { (ty::Tuple(_), ty::Tuple(_)) => {} @@ -2342,7 +2342,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } ValuePairs::PolySigs(exp_found) => { - let exp_found = self.resolve_vars_if_possible(exp_found); + let exp_found = self.deep_resolve_non_region_vars(exp_found); if exp_found.references_error() { return None; } @@ -2367,7 +2367,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { exp_found: ty::error::ExpectedFound>, long_ty_path: &mut Option, ) -> Option<(DiagStyledString, DiagStyledString)> { - let exp_found = self.resolve_vars_if_possible(exp_found); + let exp_found = self.deep_resolve_non_region_vars(exp_found); if exp_found.references_error() { return None; } @@ -2439,7 +2439,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &self, exp_found: ty::error::ExpectedFound, ) -> Option<(DiagStyledString, DiagStyledString)> { - let exp_found = self.resolve_vars_if_possible(exp_found); + let exp_found = self.deep_resolve_non_region_vars(exp_found); if exp_found.references_error() { return None; } @@ -2465,7 +2465,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { /// FloatVar inference type are compatible with themselves or their concrete types (Int and /// Float types, respectively). When comparing two ADTs, these rules apply recursively. pub fn same_type_modulo_infer>>(&self, a: T, b: T) -> bool { - let (a, b) = self.resolve_vars_if_possible((a, b)); + let (a, b) = self.deep_resolve_non_region_vars((a, b)); SameTypeModuloInfer(self).relate(a, b).is_ok() } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 1a66ddb8e2238..2ca54cd84110d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -88,7 +88,7 @@ impl InferenceDiagnosticsData { "" } else if self.name == "_" { let displayed_ty = infcx - .resolve_vars_if_possible(in_type) + .deep_resolve_non_region_vars(in_type) .fold_with(&mut ClosureEraser { infcx, depth: 0 }); if displayed_ty.is_ty_or_numeric_infer() { "" @@ -308,7 +308,7 @@ fn ty_to_string<'tcx>( called_method_def_id: Option, ) -> String { let mut p = fmt_printer(infcx, Namespace::TypeNS); - let ty = infcx.resolve_vars_if_possible(ty); + let ty = infcx.deep_resolve_non_region_vars(ty); // We use `fn` ptr syntax for closures, but this only works when the closure does not capture // anything. We also remove all type parameters that are fully known to the type system. let ty = ty.fold_with(&mut ClosureEraser { infcx, depth: 0 }); @@ -507,7 +507,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { should_label_span: bool, ty: Option>, ) -> Diag<'a> { - let term = self.resolve_vars_if_possible(term); + let term = self.deep_resolve_non_region_vars(term); let arg_data = self .extract_inference_diagnostics_data(term, ty::print::RegionHighlightMode::default()); @@ -1019,12 +1019,12 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { fn node_args_opt(&self, hir_id: HirId) -> Option> { let args = self.typeck_results.node_args_opt(hir_id); - self.tecx.resolve_vars_if_possible(args) + self.tecx.deep_resolve_non_region_vars(args) } fn opt_node_type(&self, hir_id: HirId) -> Option> { let ty = self.typeck_results.node_type_opt(hir_id); - self.tecx.resolve_vars_if_possible(ty) + self.tecx.deep_resolve_non_region_vars(ty) } // Check whether this generic argument is the inference variable we @@ -1412,7 +1412,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { .iter() .position(|&arg| self.generic_arg_contains_target(arg)) { - let args = self.tecx.resolve_vars_if_possible(args); + let args = self.tecx.deep_resolve_non_region_vars(args); let generic_args = &generics.own_args_no_defaults(tcx, args)[generics.own_counts().lifetimes..]; let span = match expr.kind { @@ -1493,7 +1493,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { { let successor = method_args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo())); - let args = self.tecx.resolve_vars_if_possible(args); + let args = self.tecx.deep_resolve_non_region_vars(args); self.update_infer_source(InferSource { span: path.ident.span, kind: InferSourceKind::FullyQualifiedMethodCall { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs index ee8a4099b21cf..eb686e3c91c3f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs @@ -273,12 +273,12 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { (false, None, None, Some(span), String::new()) }; - let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args( + let expected_trait_ref = self.cx.deep_resolve_non_region_vars(ty::TraitRef::new_from_args( self.cx.tcx, trait_def_id, expected_args, )); - let actual_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args( + let actual_trait_ref = self.cx.deep_resolve_non_region_vars(ty::TraitRef::new_from_args( self.cx.tcx, trait_def_id, actual_args, @@ -402,7 +402,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { // the confusing lifetime-generality error into an actionable hint, e.g.: // |buf| → |buf: &mut [u8]| if self.tcx().is_fn_trait(trait_def_id) { - let actual_self_ty = self.cx.resolve_vars_if_possible( + let actual_self_ty = self.cx.deep_resolve_non_region_vars( ty::TraitRef::new_from_args(self.cx.tcx, trait_def_id, actual_args).self_ty(), ); if let ty::Closure(closure_def_id, _) = *actual_self_ty.kind() diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index c28970829f0a4..66c2d87bb0307 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -991,7 +991,7 @@ fn foo(&self) -> Self::T { String::new() } msg: impl Fn() -> String, is_bound_surely_present: bool, ) -> bool { - // FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting. + // FIXME: we would want to call `deep_resolve_non_region_vars` on `ty` before suggesting. let trait_bounds = bounds.iter().filter_map(|bound| match bound { hir::GenericBound::Trait(ptr) if ptr.modifiers == hir::TraitBoundModifiers::NONE => { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index f92c0e14c8f3a..5d47aba2d9c6d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -430,7 +430,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); self.dcx().create_err(FulfillReqLifetime { span, - ty: self.resolve_vars_if_possible(ty), + ty: self.deep_resolve_non_region_vars(ty), note, }) } @@ -495,7 +495,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); self.dcx().create_err(RefLongerThanData { span, - ty: self.resolve_vars_if_possible(ty), + ty: self.deep_resolve_non_region_vars(ty), notes: pointer_valid.into_iter().chain(data_valid).collect(), }) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index db852701051cf..b031371a7a14d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -48,8 +48,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { second_span: Span, ) -> Option { let remove_semicolon = [ - (first_id, self.resolve_vars_if_possible(second_ty)), - (second_id, self.resolve_vars_if_possible(first_ty)), + (first_id, self.deep_resolve_non_region_vars(second_ty)), + (second_id, self.deep_resolve_non_region_vars(first_ty)), ] .into_iter() .find_map(|(id, ty)| { @@ -926,7 +926,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .as_ref() .and_then(|typeck_results| typeck_results.node_type_opt(*hir_id)) { - let pat_ty = self.resolve_vars_if_possible(pat_ty); + let pat_ty = self.deep_resolve_non_region_vars(pat_ty); if self.same_type_modulo_infer(pat_ty, expected_ty) && !(pat_ty, expected_ty).references_error() && shadowed.insert(ident.name) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index ec855b4debd04..0c9c308bc19d5 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -184,7 +184,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // ambiguous impls. The latter *ought* to be a // coherence violation, so we don't report it here. - let predicate = self.resolve_vars_if_possible(obligation.predicate); + let predicate = self.deep_resolve_non_region_vars(obligation.predicate); let span = obligation.cause.span; let mut long_ty_path = None; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 1897ed8fc84eb..0b73b9c8c682f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -112,7 +112,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => { let leaf_trait_predicate = - self.resolve_vars_if_possible(bound_predicate.rebind(trait_predicate)); + self.deep_resolve_non_region_vars(bound_predicate.rebind(trait_predicate)); // Let's use the root obligation as the main message, when we care about the // most general case ("X doesn't implement Pattern<'_>") over the case that @@ -153,7 +153,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && !self.tcx.is_lang_item(root_pred.def_id(), LangItem::Unsize) { ( - self.resolve_vars_if_possible( + self.deep_resolve_non_region_vars( root_obligation.predicate.kind().rebind(root_pred), ), root_obligation, @@ -699,7 +699,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => { - let ty = self.resolve_vars_if_possible(ty); + let ty = self.deep_resolve_non_region_vars(ty); if self.next_trait_solver() { if let Err(guar) = ty.error_reported() { return guar; @@ -1171,7 +1171,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let noted_missing_impl = self.note_missing_impl_for_question_mark(err, self_ty, found_ty, trait_pred); - let mut prev_ty = self.resolve_vars_if_possible( + let mut prev_ty = self.deep_resolve_non_region_vars( typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)), ); @@ -1203,7 +1203,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expr = rcvr_expr; chain.push((span, prev_ty)); - let next_ty = self.resolve_vars_if_possible( + let next_ty = self.deep_resolve_non_region_vars( typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)), ); @@ -1246,7 +1246,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // The last statement is of a type that can be converted to the return error type && let [.., stmt] = block.stmts && let hir::StmtKind::Semi(expr) = stmt.kind - && let expr_ty = self.resolve_vars_if_possible( + && let expr_ty = self.deep_resolve_non_region_vars( typeck.expr_ty_adjusted_opt(expr) .unwrap_or(Ty::new_misc_error(self.tcx)), ) @@ -1291,7 +1291,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // `expr` is now the "root" expression of the method call chain, which can be any // expression kind, like a method call or a path. If this expression is `Result` as // well, then we also point at it. - prev_ty = self.resolve_vars_if_possible( + prev_ty = self.deep_resolve_non_region_vars( typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)), ); chain.push((expr.span, prev_ty)); @@ -1599,7 +1599,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation: &PredicateObligation<'tcx>, error: &MismatchedProjectionTypes<'tcx>, ) -> ErrorGuaranteed { - let predicate = self.resolve_vars_if_possible(obligation.predicate); + let predicate = self.deep_resolve_non_region_vars(obligation.predicate); if let Err(e) = predicate.error_reported() { return e; @@ -1642,7 +1642,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ( Some(( data.projection_term, - self.resolve_vars_if_possible(normalized_term), + self.deep_resolve_non_region_vars(normalized_term), data.term, )), new_err, @@ -1670,7 +1670,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { with_forced_trimmed_paths!(format!( "type mismatch resolving `{}`", self.tcx - .short_string(self.resolve_vars_if_possible(predicate), &mut file), + .short_string(self.deep_resolve_non_region_vars(predicate), &mut file), )), obligation.cause.span, None, @@ -1804,7 +1804,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { with_forced_trimmed_paths!(Cow::from(format!( "type mismatch resolving `{}`", self.tcx.short_string( - self.resolve_vars_if_possible(predicate), + self.deep_resolve_non_region_vars(predicate), diag.long_ty_path() ), ))), @@ -2212,7 +2212,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return false; } - let impl_trait_ref = self.resolve_vars_if_possible(impl_trait_ref); + let impl_trait_ref = self.deep_resolve_non_region_vars(impl_trait_ref); if impl_trait_ref.references_error() { return false; } @@ -2294,7 +2294,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.highlighted_span_help(self.tcx.def_span(single.impl_def_id), msg); if let [TypeError::Sorts(exp_found)] = &terrs[..] { - let exp_found = self.resolve_vars_if_possible(*exp_found); + let exp_found = self.deep_resolve_non_region_vars(*exp_found); let expected = self.tcx.short_string(exp_found.expected, err.long_ty_path()); let found = self.tcx.short_string(exp_found.found, err.long_ty_path()); @@ -2712,7 +2712,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) -> Option<(Ty<'tcx>, Option)> { match code { ObligationCauseCode::BuiltinDerived(data) => { - let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); + let parent_trait_ref = self.deep_resolve_non_region_vars(data.parent_trait_pred); match self.get_parent_trait_ref(&data.parent_code) { Some(t) => Some(t), None => { @@ -3031,7 +3031,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { cause_code: &ObligationCauseCode<'tcx>, ) -> bool { if let ObligationCauseCode::BuiltinDerived(data) = cause_code { - let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); + let parent_trait_ref = self.deep_resolve_non_region_vars(data.parent_trait_pred); let self_ty = parent_trait_ref.skip_binder().self_ty(); if obligated_types.iter().any(|ot| ot == &self_ty) { return true; @@ -3556,8 +3556,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { found_trait_ref: ty::TraitRef<'tcx>, expected_trait_ref: ty::TraitRef<'tcx>, ) -> Result, ErrorGuaranteed> { - let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref); - let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref); + let found_trait_ref = self.deep_resolve_non_region_vars(found_trait_ref); + let expected_trait_ref = self.deep_resolve_non_region_vars(expected_trait_ref); expected_trait_ref.self_ty().error_reported()?; let found_trait_ty = found_trait_ref.self_ty(); @@ -3872,7 +3872,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx .fn_trait_kind_from_def_id(trait_def_id) .expect("expected to map DefId to ClosureKind"), - ty.rebind(self.resolve_vars_if_possible(var)), + ty.rebind(self.deep_resolve_non_region_vars(var)), )); } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs index da73c3e0d687d..043ade80e33a7 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs @@ -77,7 +77,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut err = match cause { OverflowCause::DeeplyNormalize(alias_term) => { - let alias_term = self.resolve_vars_if_possible(alias_term); + let alias_term = self.deep_resolve_non_region_vars(alias_term); let kind = alias_term.kind.descr(); let alias_str = with_short_path(self.tcx, alias_term); struct_span_code_err!( @@ -88,7 +88,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) } OverflowCause::TraitSolver(predicate) => { - let predicate = self.resolve_vars_if_possible(predicate); + let predicate = self.deep_resolve_non_region_vars(predicate); match predicate.kind().skip_binder() { ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ }) | ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => { @@ -143,7 +143,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { T: Upcast, ty::Predicate<'tcx>> + Clone, { let predicate = obligation.predicate.clone().upcast(self.tcx); - let predicate = self.resolve_vars_if_possible(predicate); + let predicate = self.deep_resolve_non_region_vars(predicate); self.report_overflow_error( OverflowCause::TraitSolver(predicate), obligation.cause.span, @@ -168,7 +168,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { /// we do not suggest increasing the overflow limit, which is not /// going to help). pub fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! { - let cycle = self.resolve_vars_if_possible(cycle.to_owned()); + let cycle = self.deep_resolve_non_region_vars(cycle.to_owned()); assert!(!cycle.is_empty()); debug!(?cycle, "report_overflow_error_cycle"); @@ -186,7 +186,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation: PredicateObligation<'tcx>, suggest_increasing_limit: bool, ) -> ErrorGuaranteed { - let obligation = self.resolve_vars_if_possible(obligation); + let obligation = self.deep_resolve_non_region_vars(obligation); let mut err = self.build_overflow_error( OverflowCause::TraitSolver(obligation.predicate), obligation.cause.span, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 35bedea6c565e..fc02e6a8a5a33 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -82,7 +82,7 @@ impl<'a, 'tcx> CoroutineData<'a, 'tcx> { infer_context.tcx.upvars_mentioned(coroutine_did).and_then(|upvars| { upvars.iter().find_map(|(upvar_id, upvar)| { let upvar_ty = self.0.node_type(*upvar_id); - let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty); + let upvar_ty = infer_context.deep_resolve_non_region_vars(upvar_ty); ty_matches(ty::Binder::dummy(upvar_ty)) .then(|| CoroutineInteriorOrUpvar::Upvar(upvar.span)) }) @@ -328,7 +328,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let Some(base_ty) = typeck_results.expr_ty_opt(base_expr) else { return; }; - let base_ty = self.resolve_vars_if_possible(base_ty); + let base_ty = self.deep_resolve_non_region_vars(base_ty); if base_ty.references_error() { return; } @@ -1329,7 +1329,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.span_label(block.span, "this block is missing a tail expression"); return; }; - let ty = self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(ty)); + let ty = self.resolve_numeric_literals_with_default(self.deep_resolve_non_region_vars(ty)); let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, ty)); let new_obligation = @@ -1354,7 +1354,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: &mut Diag<'_>, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { - let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); + let self_ty = self.deep_resolve_non_region_vars(trait_pred.self_ty()); self.enter_forall(self_ty, |ty: Ty<'_>| { let Some(generics) = self.tcx.hir_get_generics(obligation.cause.body_def_id) else { return false; @@ -2470,7 +2470,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Do not suggest removal of borrow from type arguments. return; } - let trait_pred = self.resolve_vars_if_possible(trait_pred); + let trait_pred = self.deep_resolve_non_region_vars(trait_pred); if trait_pred.has_non_region_infer() { // Do not ICE while trying to find if a reborrow would succeed on a trait with // unresolved bindings. @@ -3871,9 +3871,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } ObligationCauseCode::Coercion { source, target } => { let source = - tcx.short_string(self.resolve_vars_if_possible(source), err.long_ty_path()); + tcx.short_string(self.deep_resolve_non_region_vars(source), err.long_ty_path()); let target = - tcx.short_string(self.resolve_vars_if_possible(target), err.long_ty_path()); + tcx.short_string(self.deep_resolve_non_region_vars(target), err.long_ty_path()); err.note(with_forced_trimmed_paths!(format!( "required for the cast from `{source}` to `{target}`", ))); @@ -4145,7 +4145,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.note("shared static variables must have a type that implements `Sync`"); } ObligationCauseCode::BuiltinDerived(ref data) => { - let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); + let parent_trait_ref = self.deep_resolve_non_region_vars(data.parent_trait_pred); let ty = parent_trait_ref.skip_binder().self_ty(); if parent_trait_ref.references_error() { // NOTE(eddyb) this was `.cancel()`, but `err` @@ -4159,7 +4159,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let is_upvar_tys_infer_tuple = if !matches!(ty.kind(), ty::Tuple(..)) { false } else if let ObligationCauseCode::BuiltinDerived(data) = &*data.parent_code { - let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); + let parent_trait_ref = self.deep_resolve_non_region_vars(data.parent_trait_pred); let nested_ty = parent_trait_ref.skip_binder().self_ty(); matches!(nested_ty.kind(), ty::Coroutine(..)) || matches!(nested_ty.kind(), ty::Closure(..)) @@ -4269,7 +4269,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } ObligationCauseCode::ImplDerived(ref data) => { let mut parent_trait_pred = - self.resolve_vars_if_possible(data.derived.parent_trait_pred); + self.deep_resolve_non_region_vars(data.derived.parent_trait_pred); let parent_def_id = parent_trait_pred.def_id(); if tcx.is_diagnostic_item(sym::FromResidual, parent_def_id) && !tcx.features().enabled(sym::try_trait_v2) @@ -4281,7 +4281,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } if tcx.is_diagnostic_item(sym::PinDerefMutHelper, parent_def_id) { let parent_predicate = - self.resolve_vars_if_possible(data.derived.parent_trait_pred); + self.deep_resolve_non_region_vars(data.derived.parent_trait_pred); // Skip PinDerefMutHelper in suggestions, but still show downstream suggestions. @@ -4399,7 +4399,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // the type `X`", like we would otherwise do in test `supertrait-auto-trait.rs`. while let ObligationCauseCode::BuiltinDerived(derived) = &*data.parent_code { let child_trait_ref = - self.resolve_vars_if_possible(derived.parent_trait_pred); + self.deep_resolve_non_region_vars(derived.parent_trait_pred); let child_def_id = child_trait_ref.def_id(); if seen_requirements.insert(child_def_id) { break; @@ -4412,7 +4412,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { while let ObligationCauseCode::ImplDerived(child) = &*data.parent_code { // Skip redundant recursive obligation notes. See `ui/issue-20413.rs`. let child_trait_pred = - self.resolve_vars_if_possible(child.derived.parent_trait_pred); + self.deep_resolve_non_region_vars(child.derived.parent_trait_pred); let child_def_id = child_trait_pred.def_id(); if seen_requirements.insert(child_def_id) { break; @@ -4450,7 +4450,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } ObligationCauseCode::ImplDerivedHost(ref data) => { let self_ty = tcx.short_string( - self.resolve_vars_if_possible(data.derived.parent_host_clause.self_ty()), + self.deep_resolve_non_region_vars(data.derived.parent_host_clause.self_ty()), err.long_ty_path(), ); let trait_path = tcx.short_string( @@ -4502,7 +4502,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); } ObligationCauseCode::WellFormedDerived(ref data) => { - let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); + let parent_trait_ref = self.deep_resolve_non_region_vars(data.parent_trait_pred); let parent_predicate = parent_trait_ref; self.note_obligation_cause_code( @@ -4673,7 +4673,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) { let future_trait = self.tcx.require_lang_item(LangItem::Future, span); - let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); + let self_ty = self.deep_resolve_non_region_vars(trait_pred.self_ty()); let impls_future = self.type_implements_trait( future_trait, [self.tcx.instantiate_bound_regions_with_erased(self_ty)], @@ -4699,7 +4699,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .normalize(Unnormalized::new_wip(projection_ty)); debug!( - normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty) + normalized_projection_type = ?self.deep_resolve_non_region_vars(projection_ty) ); let try_obligation = self.mk_trait_obligation_with_new_self_ty( obligation.param_env, @@ -5340,7 +5340,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut print_root_expr = true; let mut assocs = vec![]; let mut expr = expr; - let mut prev_ty = self.resolve_vars_if_possible( + let mut prev_ty = self.deep_resolve_non_region_vars( typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx)), ); while let hir::ExprKind::MethodCall(path_segment, rcvr_expr, args, span) = expr.kind { @@ -5350,7 +5350,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expr = rcvr_expr; let assocs_in_this_method = self.probe_assoc_types_at_expr(&type_diffs, span, prev_ty, expr.hir_id, param_env); - prev_ty = self.resolve_vars_if_possible( + prev_ty = self.deep_resolve_non_region_vars( typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx)), ); self.look_for_iterator_item_mistakes( @@ -5379,7 +5379,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } if let hir::Node::Param(param) = parent { // ...and it is an fn argument. - let prev_ty = self.resolve_vars_if_possible( + let prev_ty = self.deep_resolve_non_region_vars( typeck_results .node_type_opt(param.hir_id) .unwrap_or(Ty::new_misc_error(tcx)), @@ -5544,7 +5544,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { projection, )); if ocx.try_evaluate_obligations().no_errors() - && let ty = self.resolve_vars_if_possible(ty) + && let ty = self.deep_resolve_non_region_vars(ty) && !ty.is_ty_var() { assocs_in_this_method.push(Some((span, (def_id, ty)))); @@ -5633,7 +5633,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Resolve what each bound associated type actually is for the returned expression, // and keep only the ones that diverged from the signature. - let expr_ty = self.resolve_vars_if_possible( + let expr_ty = self.deep_resolve_non_region_vars( typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx)), ); let assocs = self.probe_assoc_types_at_expr( @@ -5792,7 +5792,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let hir::ExprKind::MethodCall(segment, rcvr, args, ..) = call.kind else { return }; let Some(typeck) = &self.typeck_results else { return }; let Some(rcvr_ty) = typeck.expr_ty_adjusted_opt(rcvr) else { return }; - let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); + let rcvr_ty = self.deep_resolve_non_region_vars(rcvr_ty); let autoderef = (self.autoderef_steps)(rcvr_ty); for (ty, def_id) in autoderef.iter().filter_map(|(ty, obligations)| { if let ty::Adt(def, _) = ty.kind() diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index f0fb44523d651..8987530d1660b 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -31,13 +31,13 @@ impl<'tcx> InferCtxt<'tcx> { } fn type_is_copy_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { - let ty = self.resolve_vars_if_possible(ty); + let ty = self.deep_resolve_non_region_vars(ty); let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, copy_def_id) } fn type_is_clone_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { - let ty = self.resolve_vars_if_possible(ty); + let ty = self.deep_resolve_non_region_vars(ty); let clone_def_id = self.tcx.require_lang_item(LangItem::Clone, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id) } @@ -47,7 +47,7 @@ impl<'tcx> InferCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, ) -> bool { - let ty = self.resolve_vars_if_possible(ty); + let ty = self.deep_resolve_non_region_vars(ty); let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, use_cloned_def_id) } diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 908b3452fc743..fa418bb8fb371 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -167,7 +167,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< } else if trait_pred.polarity() == ty::PredicatePolarity::Positive { match self.0.tcx.as_lang_item(trait_pred.def_id()) { Some(LangItem::Sized) | Some(LangItem::MetaSized) => { - let predicate = self.resolve_vars_if_possible(goal.predicate); + let predicate = self.deep_resolve_non_region_vars(goal.predicate); if sizedness_fast_path(self.tcx, predicate, goal.param_env) { Outcome::TriviallyHolds } else { @@ -176,7 +176,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< } Some(LangItem::Copy | LangItem::Clone) => { let self_ty = - self.resolve_vars_if_possible(trait_pred.self_ty().skip_binder()); + self.deep_resolve_non_region_vars(trait_pred.self_ty().skip_binder()); // Unlike `Sized` traits, which always prefer the built-in impl, // `Copy`/`Clone` may be shadowed by a param-env candidate which // could force a lifetime error or guide inference. While that's @@ -218,7 +218,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< return Outcome::NoFastPath; } - let ty = self.resolve_vars_if_possible(outlives.0); + let ty = self.deep_resolve_non_region_vars(outlives.0); let mut infer_collector = CollectNonRegionInfer { infers: Default::default(), visited: Default::default(), @@ -446,7 +446,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< | TypingMode::Reflection | TypingMode::PostBorrowck { .. } => false, TypingMode::PostAnalysis | TypingMode::Codegen => { - let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref); + let poly_trait_ref = self.deep_resolve_non_region_vars(goal_trait_ref); !poly_trait_ref.still_further_specializable() } TypingMode::ErasedNotCoherence(MayBeErased) => { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index bb75ae6247e38..52fb5c3e04695 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -121,14 +121,14 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>( span_bug!( root_obligation.cause.span, "did not expect successful goal when collecting ambiguity errors for `{:?}`", - infcx.resolve_vars_if_possible(root_obligation.predicate), + infcx.deep_resolve_non_region_vars(root_obligation.predicate), ) } Err(_) => { span_bug!( root_obligation.cause.span, "did not expect selection error when collecting ambiguity errors for `{:?}`", - infcx.resolve_vars_if_possible(root_obligation.predicate), + infcx.deep_resolve_non_region_vars(root_obligation.predicate), ) } } @@ -162,7 +162,7 @@ fn find_best_leaf_obligation<'tcx>( obligation: &PredicateObligation<'tcx>, consider_ambiguities: bool, ) -> PredicateObligation<'tcx> { - let obligation = infcx.resolve_vars_if_possible(obligation.clone()); + let obligation = infcx.deep_resolve_non_region_vars(obligation.clone()); // FIXME: we use a probe here as the `BestObligation` visitor does not // check whether it uses candidates which get shadowed by where-bounds. // diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index f7d6fe2481b2d..c289b613015c7 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -14,7 +14,7 @@ use std::assert_matches; use rustc_infer::infer::InferCtxt; use rustc_macros::extension; use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, NoSolution, QueryResult}; -use rustc_middle::ty::{TyCtxt, VisitorResult, eager_resolve_vars, try_visit}; +use rustc_middle::ty::{TyCtxt, VisitorResult, deep_resolve_vars, try_visit}; use rustc_middle::{bug, ty}; use rustc_next_trait_solver::canonical::instantiate_canonical_state; use rustc_next_trait_solver::solve::{MaybeCause, MaybeInfo, SolverDelegateEvalExt as _, inspect}; @@ -167,7 +167,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { self.final_state, ); - return eager_resolve_vars(&**infcx, impl_args); + return deep_resolve_vars(&**infcx, impl_args); } inspect::ProbeStep::AddGoal(..) => {} inspect::ProbeStep::MakeCanonicalResponse { .. } @@ -349,7 +349,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { depth, orig_values, prev_universe, - goal: eager_resolve_vars(&**infcx, uncanonicalized_goal), + goal: deep_resolve_vars(&**infcx, uncanonicalized_goal), result, final_revision, source, diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 4e718ed896add..11974025e458d 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -42,7 +42,7 @@ where { let infcx = at.infcx; let value = value.skip_normalization(); - let value = infcx.resolve_vars_if_possible(value); + let value = infcx.deep_resolve_non_region_vars(value); if !infcx.tcx.renormalize_rigid_aliases() && !value.has_non_rigid_aliases() { return Normalized { value, obligations: Default::default() }; @@ -59,7 +59,7 @@ where Ok(result) => result, Err(err) => return Err(err), }; - let normalized = infcx.resolve_vars_if_possible(infer_term); + let normalized = infcx.deep_resolve_non_region_vars(infer_term); let normalization_was_ambiguous = match result.certainty { Certainty::Yes => NormalizationWasAmbiguous::No, Certainty::Maybe { .. } => { diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index c885406f6dcfb..77786fb43b97e 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -336,9 +336,9 @@ impl<'tcx> AutoTraitFinder<'tcx> { continue; } - // Call `infcx.resolve_vars_if_possible` to see if we can + // Call `infcx.deep_resolve_non_region_vars` to see if we can // get rid of any inference variables. - let obligation = infcx.resolve_vars_if_possible(Obligation::new( + let obligation = infcx.deep_resolve_non_region_vars(Obligation::new( tcx, dummy_cause.clone(), new_env, @@ -661,7 +661,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { fresh_preds.insert(self.clean_pred(selcx.infcx, obligation.predicate)); // Resolve any inference variables that we can, to help selection succeed - let predicate = selcx.infcx.resolve_vars_if_possible(obligation.predicate); + let predicate = selcx.infcx.deep_resolve_non_region_vars(obligation.predicate); // We only add a predicate as a user-displayable bound if // it involves a generic parameter, and doesn't contain diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 4ce7841826779..38e745f7f8fac 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -334,7 +334,7 @@ fn overlap<'tcx>( .iter() .any(|c| c.0.involves_placeholders()); - let mut impl_header = infcx.resolve_vars_if_possible(impl1_header); + let mut impl_header = infcx.deep_resolve_non_region_vars(impl1_header); // Deeply normalize the impl header for diagnostics, ignoring any errors if this fails. if infcx.next_trait_solver() { @@ -452,7 +452,7 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>( .filter(|error| { matches!(error.code, FulfillmentErrorCode::Ambiguity { overflow: Some(true) }) }) - .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate)) + .map(|e| infcx.deep_resolve_non_region_vars(e.obligation.predicate)) .collect(), } } else { @@ -541,8 +541,9 @@ fn impl_intersection_has_negative_obligation( // Right above we plug inference variables with placeholders, // this gets us new impl1_header_args with the inference variables actually resolved // to those placeholders. - let impl1_header_args = infcx.resolve_vars_if_possible(impl1_header.impl_args); - // So there are no infer variables left now, except regions which aren't resolved by `resolve_vars_if_possible`. + let impl1_header_args = infcx.deep_resolve_non_region_vars(impl1_header.impl_args); + // So there are no infer variables left now, except regions which aren't resolved by + // `deep_resolve_non_region_vars`. assert!(!impl1_header_args.has_non_region_infer()); let param_env = ty::EarlyBinder::bind(tcx, tcx.param_env(impl1_def_id)) diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 127a46f60b3d9..491b7c88fdf43 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -33,7 +33,7 @@ pub fn evaluate_host_effect_obligation<'tcx>( ); } - let ref obligation = selcx.infcx.resolve_vars_if_possible(obligation.clone()); + let ref obligation = selcx.infcx.deep_resolve_non_region_vars(obligation.clone()); // Force ambiguity for infer self ty. if obligation.predicate.self_ty().is_ty_var() { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index d0452052f10f6..f1b3e8906b3e5 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -145,7 +145,7 @@ where // this helps to reduce duplicate errors, as well as making // debug output much nicer to read and so on. debug_assert!(!obligation.param_env.has_non_region_infer()); - obligation.predicate = infcx.resolve_vars_if_possible(obligation.predicate); + obligation.predicate = infcx.deep_resolve_non_region_vars(obligation.predicate); debug!(?obligation, "register_predicate_obligation"); @@ -236,7 +236,7 @@ where } self.infcx - .resolve_vars_if_possible(pending_obligation.obligation.predicate) + .deep_resolve_non_region_vars(pending_obligation.obligation.predicate) .visit_with(&mut StalledOnCoroutines { stalled_coroutines: self.stalled_coroutines, cache: Default::default(), @@ -387,7 +387,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { debug!(?obligation, "pre-resolve"); if obligation.predicate.has_non_region_infer() { - obligation.predicate = self.selcx.infcx.resolve_vars_if_possible(obligation.predicate); + obligation.predicate = + self.selcx.infcx.deep_resolve_non_region_vars(obligation.predicate); } let obligation = &pending_obligation.obligation; @@ -901,7 +902,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { debug!( "process_predicate: pending obligation {:?} now stalled on {:?}", - infcx.resolve_vars_if_possible(obligation.clone()), + infcx.deep_resolve_non_region_vars(obligation.clone()), stalled_on ); @@ -952,13 +953,13 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { } ProjectAndUnifyResult::Holds(os) => { let input_projection_term = infcx - .resolve_vars_if_possible(project_obligation.predicate) + .deep_resolve_non_region_vars(project_obligation.predicate) .map_bound(|p| p.projection_term); let all_same_projection_term = os.iter().all(|o| { let Some(proj_clause) = o.predicate.as_projection_clause() else { return false; }; - infcx.resolve_vars_if_possible(proj_clause).map_bound(|p| p.projection_term) + infcx.deep_resolve_non_region_vars(proj_clause).map_bound(|p| p.projection_term) == input_projection_term }); if all_same_projection_term { @@ -1027,7 +1028,7 @@ fn args_infer_vars<'tcx>( ) -> impl Iterator { selcx .infcx - .resolve_vars_if_possible(args) + .deep_resolve_non_region_vars(args) .skip_binder() // ok because this check doesn't care about regions .iter() .filter(|arg| arg.has_non_region_infer()) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index e3653bd393c85..411d05510a000 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -227,7 +227,7 @@ fn pred_known_to_hold_modulo_regions<'tcx>( // is not smart enough, so we fall back to fulfillment when we're not certain // that an obligation holds or not. Even still, we must make sure that // the we do no inference in the process of checking this obligation. - let goal = infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env)); + let goal = infcx.deep_resolve_non_region_vars((obligation.predicate, obligation.param_env)); infcx.probe(|_| { let ocx = ObligationCtxt::new(infcx); ocx.register_obligation(obligation); @@ -235,7 +235,7 @@ fn pred_known_to_hold_modulo_regions<'tcx>( let errors = ocx.evaluate_obligations_error_on_ambiguity(); match errors { // Only known to hold if we did no inference. - TraitErrors::NoErrors => infcx.resolve_vars_if_possible(goal) == goal, + TraitErrors::NoErrors => infcx.deep_resolve_non_region_vars(goal) == goal, TraitErrors::HasErrors(errors) => { debug!(?errors); @@ -573,7 +573,7 @@ pub fn try_evaluate_const<'tcx>( param_env: ty::ParamEnv<'tcx>, ) -> Result, EvaluateConstErr> { let tcx = infcx.tcx; - let ct = infcx.resolve_vars_if_possible(ct); + let ct = infcx.deep_resolve_non_region_vars(ct); debug!(?ct); match ct.kind() { diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index f00b300c7e971..b3db37495ec6d 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -78,7 +78,7 @@ impl<'tcx> At<'_, 'tcx> { .normalize(value) .into_value_registering_obligations(self.infcx, &mut *fulfill_cx); let errors = fulfill_cx.evaluate_obligations_error_on_ambiguity(self.infcx); - let value = self.infcx.resolve_vars_if_possible(value); + let value = self.infcx.deep_resolve_non_region_vars(value); match errors { TraitErrors::NoErrors => Ok(value), TraitErrors::HasErrors(errors) => { @@ -171,7 +171,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { } fn fold>>(&mut self, value: T) -> T { - let value = self.selcx.infcx.resolve_vars_if_possible(value); + let value = self.selcx.infcx.deep_resolve_non_region_vars(value); debug!(?value); assert!( diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 84cae1e7bfa0a..a8c8a62ac87d2 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -1,6 +1,6 @@ use rustc_infer::infer::InferOk; use rustc_infer::infer::canonical::QueryRegionConstraint; -use rustc_infer::infer::resolve::OpportunisticRegionResolver; +use rustc_infer::infer::resolve::DeepRegionResolver; use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; use rustc_macros::extension; use rustc_middle::infer::canonical::{OriginalQueryValues, QueryRegionConstraints}; @@ -39,8 +39,8 @@ fn implied_outlives_bounds<'a, 'tcx>( ty: Ty<'tcx>, disable_implied_bounds_hack: bool, ) -> Vec> { - let ty = infcx.resolve_vars_if_possible(ty); - let ty = OpportunisticRegionResolver::new(infcx).fold_ty(ty); + let ty = infcx.deep_resolve_non_region_vars(ty); + let ty = DeepRegionResolver::new(infcx).fold_ty(ty); // We do not expect existential variables in implied bounds. // We may however encounter unconstrained lifetime variables diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 7da8c68ff894a..e80ab5d29f48a 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -7,7 +7,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::DefineOpaqueTypes; -use rustc_infer::infer::resolve::OpportunisticRegionResolver; +use rustc_infer::infer::resolve::DeepRegionResolver; use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; @@ -308,7 +308,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( ) -> Result>, InProgress> { let infcx = selcx.infcx; debug_assert!(!selcx.infcx.next_trait_solver()); - let projection_term = infcx.resolve_vars_if_possible(projection_term); + let projection_term = infcx.deep_resolve_non_region_vars(projection_term); let cache_key = ProjectionCacheKey::new(projection_term, param_env); // FIXME(#20304) For now, I am caching here, which is good, but it @@ -387,7 +387,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( // an impl, where-clause etc) and hence we must // re-normalize it - let projected_term = selcx.infcx.resolve_vars_if_possible(projected_term); + let projected_term = selcx.infcx.deep_resolve_non_region_vars(projected_term); let mut result = if projected_term.has_aliases() { let normalized_ty = normalize_with_depth_to( @@ -578,7 +578,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( tcx.const_of_item(def_id).instantiate(tcx, args).map(Into::into) }; - let term = selcx.infcx.resolve_vars_if_possible(term); + let term = selcx.infcx.deep_resolve_non_region_vars(term); let term = normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, term, obligations); @@ -997,7 +997,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // NOTE(eddyb) inference variables can resolve to parameters, so // assume `poly_trait_ref` isn't monomorphic, if it contains any. let poly_trait_ref = - selcx.infcx.resolve_vars_if_possible(trait_ref); + selcx.infcx.deep_resolve_non_region_vars(trait_ref); !poly_trait_ref.still_further_specializable() } } @@ -1270,7 +1270,7 @@ fn confirm_candidate<'cx, 'tcx>( if let Ok(Projected::Progress(progress)) = &mut result && progress.term.has_infer_regions() { - progress.term = progress.term.fold_with(&mut OpportunisticRegionResolver::new(selcx.infcx)); + progress.term = progress.term.fold_with(&mut DeepRegionResolver::new(selcx.infcx)); } result @@ -2159,7 +2159,7 @@ impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> { // from a specific call to `opt_normalize_projection_type` - if // there's no precise match, the original cache entry is "stranded" // anyway. - infcx.resolve_vars_if_possible(predicate.projection_term), + infcx.deep_resolve_non_region_vars(predicate.projection_term), obligation.param_env, ) }) diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 25385d15e36f4..2b5a30e66921d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -140,7 +140,7 @@ where })?; // Next trait solver performs operations locally, and normalize goals should resolve vars. - let value = infcx.resolve_vars_if_possible(value); + let value = infcx.deep_resolve_non_region_vars(value); let region_obligations = infcx.take_registered_region_obligations(); let region_assumptions = infcx.take_registered_region_assumptions(); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 81cf4ac607074..010ce2c77ba92 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -97,7 +97,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( continue; } - let arg = ocx.infcx.resolve_vars_if_possible(arg); + let arg = ocx.infcx.deep_resolve_non_region_vars(arg); // From the full set of obligations, just filter down to the region relationships. for obligation in wf::unnormalized_obligations(ocx.infcx, param_env, arg, DUMMY_SP, CRATE_DEF_ID) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index db863cb42f63e..f63e947789626 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -38,7 +38,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { param_env: obligation.param_env, cause: obligation.cause.clone(), recursion_depth: obligation.recursion_depth, - predicate: self.infcx.resolve_vars_if_possible(obligation.predicate), + predicate: self.infcx.deep_resolve_non_region_vars(obligation.predicate), }; if obligation.predicate.skip_binder().self_ty().is_ty_var() { @@ -209,7 +209,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } self.infcx.probe(|_| { - let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); + let poly_trait_predicate = + self.infcx.deep_resolve_non_region_vars(obligation.predicate); let placeholder_trait_predicate = self.infcx.enter_forall_and_leak_universe(poly_trait_predicate); @@ -928,7 +929,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } self.infcx.probe(|_snapshot| { - let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); + let poly_trait_predicate = + self.infcx.deep_resolve_non_region_vars(obligation.predicate); self.infcx.enter_forall(poly_trait_predicate, |placeholder_trait_predicate| { let self_ty = placeholder_trait_predicate.self_ty(); let principal_trait_ref = match self_ty.kind() { @@ -1374,7 +1376,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty()); + let self_ty = self.infcx.deep_resolve_non_region_vars(obligation.self_ty()); match self_ty.skip_binder().kind() { ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate), diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 9b4ee13bf1b63..45eca8d2c444d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -384,7 +384,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } if !candidate_set.ambiguous && no_candidates_apply { - let trait_ref = self.infcx.resolve_vars_if_possible( + let trait_ref = self.infcx.deep_resolve_non_region_vars( stack.obligation.predicate.skip_binder().trait_ref, ); if !trait_ref.references_error() { @@ -520,14 +520,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug_assert!(!self.infcx.next_trait_solver()); self.evaluation_probe(|this| { let goal = - this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env)); + this.infcx.deep_resolve_non_region_vars((obligation.predicate, obligation.param_env)); let mut result = this.evaluate_predicate_recursively( TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()), obligation.clone(), )?; // If the predicate has done any inference, then downgrade the // result to ambiguous. - if this.infcx.resolve_vars_if_possible(goal) != goal { + if this.infcx.deep_resolve_non_region_vars(goal) != goal { result = result.max(EvaluatedToAmbig); } Ok(result) @@ -1482,7 +1482,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("is_knowable()"); - let predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); + let predicate = self.infcx.deep_resolve_non_region_vars(obligation.predicate); // Okay to skip binder because of the nature of the // trait-ref-is-knowable check, which does not care about @@ -2505,7 +2505,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { match self.match_impl(impl_def_id, impl_trait_header, obligation) { Ok(args) => args, Err(()) => { - let predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); + let predicate = self.infcx.deep_resolve_non_region_vars(obligation.predicate); bug!("impl {impl_def_id:?} was matchable against {predicate:?} but now is not") } } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index a142d8f40fffe..d8da606d613f6 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -218,7 +218,7 @@ fn fulfill_implication<'tcx>( // Now resolve the *generic parameters* we built for the target earlier, replacing // the inference variables inside with whatever we got from fulfillment. - Ok(infcx.resolve_vars_if_possible(target_args)) + Ok(infcx.deep_resolve_non_region_vars(target_args)) } pub(super) fn specialization_enabled_in(tcx: TyCtxt<'_>, _: LocalCrate) -> bool { diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index 2556c2baffada..6f3e3a4de91b5 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -69,7 +69,7 @@ impl<'tcx> At<'_, 'tcx> { return Err(errors); } - Ok(self.infcx.resolve_vars_if_possible(new_infer)) + Ok(self.infcx.deep_resolve_non_region_vars(new_infer)) } else { Ok(self.normalize(term).into_value_registering_obligations(self.infcx, fulfill_cx)) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 41d2d9adfea74..26aefcf7e3101 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -97,7 +97,7 @@ pub fn unnormalized_obligations<'tcx>( span: Span, body_def_id: LocalDefId, ) -> Option> { - debug_assert_eq!(term, infcx.resolve_vars_if_possible(term)); + debug_assert_eq!(term, infcx.deep_resolve_non_region_vars(term)); // However, if `term` IS an unresolved inference variable, returns `None`, // because we are not able to make any progress at all. This is to prevent diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index e03b67f8e4d39..7890826b6d01a 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -72,7 +72,7 @@ pub(crate) fn codegen_select_candidate<'tcx>( return Err(CodegenObligationError::Unimplemented); } - let impl_source = infcx.resolve_vars_if_possible(impl_source); + let impl_source = infcx.deep_resolve_non_region_vars(impl_source); let impl_source = tcx.erase_and_anonymize_regions(impl_source); if impl_source.has_non_region_infer() { // Unused generic types or consts on an impl get replaced with inference vars, diff --git a/compiler/rustc_traits/src/coroutine_witnesses.rs b/compiler/rustc_traits/src/coroutine_witnesses.rs index 762471eefe4dd..c3e4bfdb45e3a 100644 --- a/compiler/rustc_traits/src/coroutine_witnesses.rs +++ b/compiler/rustc_traits/src/coroutine_witnesses.rs @@ -1,7 +1,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::canonical::QueryRegionConstraint; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; -use rustc_infer::infer::resolve::OpportunisticRegionResolver; +use rustc_infer::infer::resolve::DeepRegionResolver; use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions}; use rustc_span::def_id::DefId; @@ -86,7 +86,7 @@ fn compute_assumptions<'tcx>( region_assumptions, ) .constraints - .fold_with(&mut OpportunisticRegionResolver::new(&infcx)); + .fold_with(&mut DeepRegionResolver::new(&infcx)); tcx.mk_outlives_from_iter( constraints diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 1ba385e86b310..c92bbb7bdb4f1 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -36,7 +36,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable> + Par None, ); - let resolved_value = infcx.resolve_vars_if_possible(normalized_value); + let resolved_value = infcx.deep_resolve_non_region_vars(normalized_value); // It's unclear when `resolve_vars` would have an effect in a // fresh `InferCtxt`. If this assert does trigger, it will give // us a test case. diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index d28851d8de939..b4c0fb1a39a94 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -487,7 +487,7 @@ pub trait InferCtxtLike: Sized { ty: ::Const, ) -> ::Const; - fn resolve_vars_if_possible(&self, value: T) -> T + fn deep_resolve_non_region_vars(&self, value: T) -> T where T: TypeFoldable; @@ -600,20 +600,24 @@ where } } -/// Resolves ty, region, and const vars to their inferred values or their root vars. -pub fn eager_resolve_vars>( +/// Where possible, replaces type/const/region variables in `value` with their final value. +/// If a type/const/region variable has not (yet) been unified, it is left as is. +/// +/// This is an idempotent operation that does not affect inference state in any way, +/// which means it's safe to call this function at will. +pub fn deep_resolve_vars>( infcx: &Infcx, value: T, ) -> T { if value.has_infer() { - let mut folder = EagerResolver::new(infcx); + let mut folder = DeepVariableResolver::new(infcx); value.fold_with(&mut folder) } else { value } } -struct EagerResolver<'a, D, I = ::Interner> +struct DeepVariableResolver<'a, D, I = ::Interner> where D: InferCtxtLike, I: Interner, @@ -624,13 +628,15 @@ where cache: DelayedMap, } -impl<'a, Infcx: InferCtxtLike> EagerResolver<'a, Infcx> { +impl<'a, Infcx: InferCtxtLike> DeepVariableResolver<'a, Infcx> { fn new(delegate: &'a Infcx) -> Self { - EagerResolver { delegate, cache: Default::default() } + DeepVariableResolver { delegate, cache: Default::default() } } } -impl, I: Interner> TypeFolder for EagerResolver<'_, Infcx> { +impl, I: Interner> TypeFolder + for DeepVariableResolver<'_, Infcx> +{ fn cx(&self) -> I { self.delegate.cx() } diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 4c0fe9cd25724..4d207611c75b5 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -243,7 +243,7 @@ where ty::Bivariant => { let has_non_region_infer = |arg: I::GenericArg| { arg.has_non_region_infer() - && infcx.resolve_vars_if_possible(arg).has_non_region_infer() + && infcx.deep_resolve_non_region_vars(arg).has_non_region_infer() }; if has_non_region_infer(a) || has_non_region_infer(b) { has_unconstrained_bivariant_arg = true; diff --git a/compiler/rustc_type_ir/src/universe.rs b/compiler/rustc_type_ir/src/universe.rs index a5a4b2c02be89..05cedf49a400f 100644 --- a/compiler/rustc_type_ir/src/universe.rs +++ b/compiler/rustc_type_ir/src/universe.rs @@ -57,7 +57,7 @@ fn max_universe_inner< let mut visitor = MaxUniverse::<_, _, VISIT_PLACEHOLDER, VISIT_INFER>::new(infcx); // FIXME: make this a debug_assert and let callers resolve vars. Then the input only needs to // be `TypeVisitable`. - let t = infcx.resolve_vars_if_possible(t); + let t = infcx.deep_resolve_non_region_vars(t); t.visit_with(&mut visitor); visitor.max_universe() } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9f972376c11ac..ec4b85f35f544 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1991,7 +1991,7 @@ fn normalize<'tcx>( let normalized = infcx .at(&ObligationCause::dummy(), cx.param_env) .query_normalize(ty) - .map(|resolved| infcx.resolve_vars_if_possible(resolved.value)); + .map(|resolved| infcx.deep_resolve_non_region_vars(resolved.value)); match normalized { Ok(normalized_value) => { debug!("normalized {ty:?} to {normalized_value:?}"); diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6f915a3755ba2..3f59327cca4c1 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -432,7 +432,7 @@ fn generate_item_def_id_path( let ty = infcx .at(&ObligationCause::dummy(), tcx.param_env(def_id)) .query_normalize(ty::Binder::dummy(ty.instantiate_identity().skip_norm_wip())) - .map(|resolved| infcx.resolve_vars_if_possible(resolved.value).skip_binder()) + .map(|resolved| infcx.deep_resolve_non_region_vars(resolved.value).skip_binder()) .unwrap_or(ty.skip_binder()); if let Some(new_def_id) = ty.ty_adt_def().map(|adt| adt.did()) { def_id = new_def_id; From bd5c17be10de9927b32d7ba3077e8ee7b9c04e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 11 Aug 2026 15:01:33 +0200 Subject: [PATCH 7/8] make lifetime methods more consistent --- compiler/rustc_hir_typeck/src/expectation.rs | 4 +++- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 7 ++++++- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 8 ++++++-- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 3 ++- compiler/rustc_infer/src/infer/context.rs | 11 ++++------- .../src/canonical/canonicalizer.rs | 6 +++--- compiler/rustc_next_trait_solver/src/placeholder.rs | 2 +- .../src/solve/eval_ctxt/mod.rs | 6 +++--- .../src/error_reporting/traits/fulfillment_errors.rs | 10 ++++++---- .../src/error_reporting/traits/suggestions.rs | 3 ++- compiler/rustc_trait_selection/src/solve/delegate.rs | 4 ++-- compiler/rustc_type_ir/src/infer_ctxt.rs | 8 ++++---- compiler/rustc_type_ir/src/universe.rs | 6 +++--- 13 files changed, 45 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expectation.rs b/compiler/rustc_hir_typeck/src/expectation.rs index b6d90a13c11c5..fc4433be785fa 100644 --- a/compiler/rustc_hir_typeck/src/expectation.rs +++ b/compiler/rustc_hir_typeck/src/expectation.rs @@ -95,7 +95,9 @@ impl<'a, 'tcx> Expectation<'tcx> { NoExpectation => NoExpectation, ExpectCastableToType(t) => ExpectCastableToType(fcx.deep_resolve_non_region_vars(t)), ExpectHasType(t) => ExpectHasType(fcx.deep_resolve_non_region_vars(t)), - ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.deep_resolve_non_region_vars(t)), + ExpectRvalueLikeUnsized(t) => { + ExpectRvalueLikeUnsized(fcx.deep_resolve_non_region_vars(t)) + } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index a28abd60ed4b7..0b29f32c7955e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -199,7 +199,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[inline] pub(crate) fn write_ty(&self, id: HirId, ty: Ty<'tcx>) { - debug!("write_ty({:?}, {:?}) in fcx {}", id, self.deep_resolve_non_region_vars(ty), self.tag()); + debug!( + "write_ty({:?}, {:?}) in fcx {}", + id, + self.deep_resolve_non_region_vars(ty), + self.tag() + ); let mut typeck = self.typeck_results.borrow_mut(); let mut node_ty = typeck.node_types_mut(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 74e94cf9e8c56..119b5250c981d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1862,7 +1862,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!( "{deps_list} need{} to match the {} type of this parameter", pluralize!((deps.len() != 1) as u32), - self.deep_resolve_non_region_vars(expected_ty).sort_string(self.tcx), + self.deep_resolve_non_region_vars(expected_ty) + .sort_string(self.tcx), ), ); } @@ -3334,7 +3335,10 @@ impl<'a, 'tcx> ArgsCtxt<'a, 'tcx> { .borrow() .expr_ty_adjusted_opt(expr) .unwrap_or_else(|| Ty::new_misc_error(self.call_ctxt.fn_ctxt.tcx)); - (self.call_ctxt.fn_ctxt.deep_resolve_non_region_vars(ty), self.normalize_span(expr.span)) + ( + self.call_ctxt.fn_ctxt.deep_resolve_non_region_vars(ty), + self.normalize_span(expr.span), + ) }) .collect() } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 905aeeb6b4ebd..da1a115d09a08 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -991,7 +991,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - let found = self.resolve_numeric_literals_with_default(self.deep_resolve_non_region_vars(found)); + let found = + self.resolve_numeric_literals_with_default(self.deep_resolve_non_region_vars(found)); // Only suggest changing the return type for methods that // haven't set a return type at all (and aren't `fn main()`, impl or closure). match &fn_decl.output { diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index d7918f1583e39..244507616c9e6 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -87,14 +87,14 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } } - fn universe_of_lt(&self, lt: ty::RegionVid) -> Option { + fn universe_of_region(&self, lt: ty::RegionVid) -> Option { match self.inner.borrow_mut().unwrap_region_constraints().try_resolve_region_var(lt) { Err(universe) => Some(universe), Ok(_) => None, } } - fn universe_of_ct(&self, ct: ty::ConstVid) -> Option { + fn universe_of_const(&self, ct: ty::ConstVid) -> Option { match self.try_resolve_const_var(ct) { Err(universe) => Some(universe), Ok(_) => None, @@ -136,13 +136,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn shallow_resolve_const_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { - match self.try_resolve_const_var(vid) { - Ok(ct) => ct, - Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)), - } + self.shallow_resolve_const_var(vid) } - fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> { + fn shallow_resolve_region_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> { self.inner .borrow_mut() .unwrap_region_constraints() diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 5a30582489e8c..f0d72f826a3f0 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -470,7 +470,7 @@ impl, I: Interner> TypeFolder for Canonicaliz ty::ReVar(vid) => { debug_assert_eq!( - self.delegate.opportunistic_resolve_lt_var(vid), + self.delegate.shallow_resolve_region_var(vid), r, "region vid should have been resolved fully before canonicalization" ); @@ -482,7 +482,7 @@ impl, I: Interner> TypeFolder for Canonicaliz )) } CanonicalizeMode::Response { .. } => { - CanonicalVarKind::Region(self.delegate.universe_of_lt(vid).unwrap()) + CanonicalVarKind::Region(self.delegate.universe_of_region(vid).unwrap()) } } } @@ -525,7 +525,7 @@ impl, I: Interner> TypeFolder for Canonicaliz CanonicalVarKind::Const(ty::UniverseIndex::ROOT) } CanonicalizeMode::Response { .. } => { - CanonicalVarKind::Const(self.delegate.universe_of_ct(vid).unwrap()) + CanonicalVarKind::Const(self.delegate.universe_of_const(vid).unwrap()) } } } diff --git a/compiler/rustc_next_trait_solver/src/placeholder.rs b/compiler/rustc_next_trait_solver/src/placeholder.rs index 83b2eb6ac6295..616e93e331286 100644 --- a/compiler/rustc_next_trait_solver/src/placeholder.rs +++ b/compiler/rustc_next_trait_solver/src/placeholder.rs @@ -248,7 +248,7 @@ where fn fold_region(&mut self, r0: Region) -> Region { let r1 = match r0.kind() { - ty::ReVar(vid) => self.infcx.opportunistic_resolve_lt_var(vid), + ty::ReVar(vid) => self.infcx.shallow_resolve_region_var(vid), _ => r0, }; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 3450f1cfac799..d75a08d76b825 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -1100,7 +1100,7 @@ where } ty::TermKind::Const(ct) => { if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() { - self.delegate.universe_of_ct(vid).unwrap() + self.delegate.universe_of_const(vid).unwrap() } else { return false; } @@ -1167,7 +1167,7 @@ where return ControlFlow::Break(()); } - self.check_nameable(self.delegate.universe_of_ct(vid).unwrap()) + self.check_nameable(self.delegate.universe_of_const(vid).unwrap()) } ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe()), _ => { @@ -1315,7 +1315,7 @@ where pub(super) fn eager_resolve_region(&self, r: Region) -> Region { if let ty::ReVar(vid) = r.kind() { - self.delegate.opportunistic_resolve_lt_var(vid) + self.delegate.shallow_resolve_region_var(vid) } else { r } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 0b73b9c8c682f..fe9a5fda95b38 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -111,8 +111,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let bound_predicate = obligation.predicate.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => { - let leaf_trait_predicate = - self.deep_resolve_non_region_vars(bound_predicate.rebind(trait_predicate)); + let leaf_trait_predicate = self + .deep_resolve_non_region_vars(bound_predicate.rebind(trait_predicate)); // Let's use the root obligation as the main message, when we care about the // most general case ("X doesn't implement Pattern<'_>") over the case that @@ -1669,8 +1669,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ( with_forced_trimmed_paths!(format!( "type mismatch resolving `{}`", - self.tcx - .short_string(self.deep_resolve_non_region_vars(predicate), &mut file), + self.tcx.short_string( + self.deep_resolve_non_region_vars(predicate), + &mut file + ), )), obligation.cause.span, None, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index fc02e6a8a5a33..be3b607f2cf63 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4159,7 +4159,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let is_upvar_tys_infer_tuple = if !matches!(ty.kind(), ty::Tuple(..)) { false } else if let ObligationCauseCode::BuiltinDerived(data) = &*data.parent_code { - let parent_trait_ref = self.deep_resolve_non_region_vars(data.parent_trait_pred); + let parent_trait_ref = + self.deep_resolve_non_region_vars(data.parent_trait_pred); let nested_ty = parent_trait_ref.skip_binder().self_ty(); matches!(nested_ty.kind(), ty::Coroutine(..)) || matches!(nested_ty.kind(), ty::Closure(..)) diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index fa418bb8fb371..7a5e77b298724 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -175,8 +175,8 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< } } Some(LangItem::Copy | LangItem::Clone) => { - let self_ty = - self.deep_resolve_non_region_vars(trait_pred.self_ty().skip_binder()); + let self_ty = self + .deep_resolve_non_region_vars(trait_pred.self_ty().skip_binder()); // Unlike `Sized` traits, which always prefer the built-in impl, // `Copy`/`Clone` may be shadowed by a param-env candidate which // could force a lifetime error or guide inference. While that's diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index b4c0fb1a39a94..d86bbe0707d96 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -402,8 +402,8 @@ pub trait InferCtxtLike: Sized { ); fn universe_of_ty(&self, ty: ty::TyVid) -> Option; - fn universe_of_lt(&self, lt: ty::RegionVid) -> Option; - fn universe_of_ct(&self, ct: ty::ConstVid) -> Option; + fn universe_of_region(&self, lt: ty::RegionVid) -> Option; + fn universe_of_const(&self, ct: ty::ConstVid) -> Option; fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid; fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid; @@ -414,7 +414,7 @@ pub trait InferCtxtLike: Sized { fn shallow_resolve_int_var(&self, vid: ty::IntVid) -> ::Ty; fn shallow_resolve_float_var(&self, vid: ty::FloatVid) -> ::Ty; fn shallow_resolve_const_var(&self, vid: ty::ConstVid) -> ::Const; - fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> Region; + fn shallow_resolve_region_var(&self, vid: ty::RegionVid) -> Region; fn ty_or_const_infer_var_changed(&self, var: TyOrConstInferVar) -> bool; @@ -670,7 +670,7 @@ impl, I: Interner> TypeFolder fn fold_region(&mut self, r: Region) -> Region { match r.kind() { - ty::ReVar(vid) => self.delegate.opportunistic_resolve_lt_var(vid), + ty::ReVar(vid) => self.delegate.shallow_resolve_region_var(vid), _ => r, } } diff --git a/compiler/rustc_type_ir/src/universe.rs b/compiler/rustc_type_ir/src/universe.rs index 05cedf49a400f..e0907df39b534 100644 --- a/compiler/rustc_type_ir/src/universe.rs +++ b/compiler/rustc_type_ir/src/universe.rs @@ -140,7 +140,7 @@ impl< self.max_universe = self.max_universe.max(p.universe) } ConstKind::Infer(rustc_type_ir::InferConst::Var(inf)) if VISIT_INFER => { - let u = self.infcx.universe_of_ct(inf).unwrap(); + let u = self.infcx.universe_of_const(inf).unwrap(); debug!("var {inf:?} in universe {u:?}"); self.max_universe = self.max_universe.max(u); } @@ -154,12 +154,12 @@ impl< self.max_universe = self.max_universe.max(p.universe) } RegionKind::ReVar(var) if VISIT_INFER => { - match self.infcx.opportunistic_resolve_lt_var(var).kind() { + match self.infcx.shallow_resolve_region_var(var).kind() { RegionKind::RePlaceholder(p) if VISIT_PLACEHOLDER => { self.max_universe = self.max_universe.max(p.universe) } RegionKind::ReVar(var) if VISIT_INFER => { - let u = self.infcx.universe_of_lt(var).unwrap(); + let u = self.infcx.universe_of_region(var).unwrap(); debug!("var {var:?} in universe {u:?}"); self.max_universe = self.max_universe.max(u); } From 06dd748b5d67687bdbe35831e476c957db006af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 11 Aug 2026 15:48:17 +0200 Subject: [PATCH 8/8] fixup various sites that use root_{ty,const}_var that can skip it after a shallow_resolve --- compiler/rustc_hir_typeck/src/closure.rs | 29 ++++++---- compiler/rustc_hir_typeck/src/fallback.rs | 4 +- .../src/fn_ctxt/inspect_obligations.rs | 2 +- .../src/infer/canonical/canonicalizer.rs | 2 +- compiler/rustc_infer/src/infer/context.rs | 8 +-- compiler/rustc_infer/src/infer/mod.rs | 58 ++++++++++++++++--- .../src/infer/relate/generalize.rs | 11 ++-- .../src/unstable/internal_cx/mod.rs | 6 +- .../src/traits/select/mod.rs | 5 +- 9 files changed, 87 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index d53f63373904e..2586c5a96ffb4 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -60,9 +60,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // closure sooner rather than later, so first examine the expected // type, and see if can glean a closure kind from there. let (expected_sig, expected_kind) = match expected.to_option(self) { - Some(ty) => { - self.deduce_closure_signature(self.deep_resolve_non_regionvars_with_obligations(ty), closure.kind) - } + Some(ty) => self.deduce_closure_signature( + self.deep_resolve_non_regionvars_with_obligations(ty), + closure.kind, + ), None => (None, None), }; @@ -285,7 +286,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Given the expected type, figures out what it can about this closure we - /// are about to type check: + /// are about to type check. + /// + /// WARNING: `expected_ty` must be resolved, to ensure that tyvars refer to root vids. #[instrument(skip(self), level = "debug", ret)] fn deduce_closure_signature( &self, @@ -312,13 +315,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .and_then(|did| self.tcx.fn_trait_kind_from_def_id(did)); (sig, kind) } - ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates( - Ty::new_var(self.tcx, self.root_var(vid)), - closure_kind, - self.obligations_for_self_ty(vid, UseSubtyping::No) - .into_iter() - .filter_map(|obl| Some((obl.predicate.as_clause()?, obl.cause.span))), - ), + ty::Infer(ty::TyVar(vid)) => { + // assert that the precondition (documented in the doc comments) is maintained. + debug_assert_eq!(self.root_ty_var(vid), vid); + self.deduce_closure_signature_from_predicates( + Ty::new_var(self.tcx, vid), + closure_kind, + self.obligations_for_self_ty(vid, UseSubtyping::No) + .into_iter() + .filter_map(|obl| Some((obl.predicate.as_clause()?, obl.cause.span))), + ) + } ty::FnPtr(sig_tys, hdr) => match closure_kind { hir::ClosureKind::Closure => { let expected_sig = ExpectedSig { cause_span: None, sig: sig_tys.with(hdr) }; diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 44906cb330c0c..0aa374a93203d 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -397,12 +397,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> { /// If `ty` is an unresolved type variable, returns its root vid. fn root_vid(&self, ty: Ty<'tcx>) -> Option { - Some(self.root_var(self.shallow_resolve(ty).ty_vid()?)) + Some(self.shallow_resolve(ty).ty_vid()?) } /// If `ty` is an unresolved float type variable, returns its root vid. pub(crate) fn root_float_vid(&self, ty: Ty<'tcx>) -> Option { - Some(self.root_float_var(self.shallow_resolve(ty).float_vid()?)) + Some(self.shallow_resolve(ty).float_vid()?) } /// Given a set of diverging vids and coercions, walk the HIR to gather a diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 1b3e275e26722..f07bbb7d57ade 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *ty.kind() { ty::Infer(ty::TyVar(found_vid)) => match subtyping { - UseSubtyping::No => self.root_var(expected_vid) == self.root_var(found_vid), + UseSubtyping::No => self.root_ty_var(expected_vid) == found_vid, UseSubtyping::Yes => { self.sub_unification_table_root_var(expected_vid) == self.sub_unification_table_root_var(found_vid) diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 732c68ab84c37..79480a5480a62 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -334,7 +334,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { // 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.unwrap().root_var(vid); + let root_vid = self.infcx.unwrap().root_ty_var(vid); if root_vid != vid { t = Ty::new_var(self.tcx, root_vid); vid = root_vid; diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 244507616c9e6..e111c6ee8ed3e 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -102,7 +102,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid { - self.root_var(var) + self.root_ty_var(var) } fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid { @@ -458,7 +458,7 @@ impl<'a, 'tcx> ty::TypeFolder> for LowerUniverseFolder<'a, 'tcx> { let folded = match t.kind() { ty::Infer(ty::TyVar(vid)) => { - let vid = self.infcx.root_var(*vid); + let vid = self.infcx.root_ty_var(*vid); let probe = self.infcx.inner.borrow_mut().type_variables().probe(vid); match probe { TypeVariableValue::Known { value: u } => u.super_fold_with(self), @@ -490,8 +490,8 @@ impl<'a, 'tcx> ty::TypeFolder> for LowerUniverseFolder<'a, 'tcx> { match c.kind() { ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { - let vid = self.infcx.root_const_var(vid); - let universe = match self.infcx.try_resolve_const_var(vid) { + let (res, vid) = self.infcx.try_resolve_const_var_with_root(vid); + let universe = match res { Ok(value) => return value.fold_with(self), Err(universe) => universe, }; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 06ff8d0942642..c93a8ebf611b8 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1212,8 +1212,29 @@ impl<'tcx> InferCtxt<'tcx> { self.deep_resolve_non_region_vars(t).to_string() } - /// If `TyVar(vid)` resolves to a type, return that type. Else, return the - /// universe index of `TyVar(vid)`. + /// If `TyVar(vid)` resolves to a type, return that type. + /// Else, return the universe index of `TyVar(vid)`. + /// + /// Also return the root `TyVid` of `vid`. + /// This is more efficient than calling [`try_resolve_ty_var`](Self::try_resolve_ty_var) + /// followed by [`root_ty_var`](Self::root_ty_var). + pub fn try_resolve_ty_var_with_root( + &self, + vid: TyVid, + ) -> (Result, ty::UniverseIndex>, TyVid) { + let (root, value) = self.inner.borrow_mut().type_variables().probe_with_root_vid(vid); + + ( + match value { + TypeVariableValue::Known { value } => Ok(self.shallow_resolve_non_recursive(value)), + TypeVariableValue::Unknown { universe } => Err(universe), + }, + root, + ) + } + + /// If `TyVar(vid)` resolves to a type, return that type. + /// Else, return the universe index of `TyVar(vid)`. pub fn try_resolve_ty_var(&self, vid: TyVid) -> Result, ty::UniverseIndex> { let value = self.inner.borrow_mut().type_variables().probe(vid); @@ -1225,12 +1246,8 @@ impl<'tcx> InferCtxt<'tcx> { /// If `vid` resolves to a type, return that type. Otherwise return the root variable id for `vid`. pub fn shallow_resolve_ty_var_or_get_root(&self, vid: TyVid) -> Result, TyVid> { - let (root, value) = self.inner.borrow_mut().type_variables().probe_with_root_vid(vid); - - match value { - TypeVariableValue::Known { value } => Ok(self.shallow_resolve_non_recursive(value)), - TypeVariableValue::Unknown { universe: _ } => Err(root), - } + let (res, root) = self.try_resolve_ty_var_with_root(vid); + res.map_err(|_| root) } /// Resolve a type variable to a type, if known. @@ -1431,7 +1448,7 @@ impl<'tcx> InferCtxt<'tcx> { } } - pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid { + pub fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid { self.inner.borrow_mut().type_variables().root_var(var) } @@ -1514,6 +1531,29 @@ impl<'tcx> InferCtxt<'tcx> { value.fold_with(&mut r) } + /// If `ConstVar(vid)` resolves to a const, return that const. + /// Else, return the universe index of `ConstVar(vid)`. + /// + /// Also return the root `ConstVid` of `vid`. + /// This is more efficient than calling [`try_resolve_const_var`](Self::try_resolve_const_var) + /// followed by [`root_const_var`](Self::root_const_var). + pub fn try_resolve_const_var_with_root( + &self, + vid: ty::ConstVid, + ) -> (Result, ty::UniverseIndex>, ty::ConstVid) { + let (root, value) = + self.inner.borrow_mut().const_unification_table().inlined_probe_key_value(vid); + ( + match value { + ConstVariableValue::Known { value } => Ok(value), + ConstVariableValue::Unknown { origin: _, universe } => Err(universe), + }, + root.vid, + ) + } + + /// If `ConstVar(vid)` resolves to a const, return that const. + /// Else, return the universe index of `ConstVar(vid)`. pub fn try_resolve_const_var( &self, vid: ty::ConstVid, diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 0e4ebdfb90085..4547a87f279cc 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -287,12 +287,13 @@ impl<'tcx> InferCtxt<'tcx> { assert!(!source_term.has_escaping_bound_vars()); let (for_universe, root_vid) = match target_vid { TermVid::Ty(ty_vid) => { - (self.try_resolve_ty_var(ty_vid).unwrap_err(), TermVid::Ty(self.root_var(ty_vid))) + let (res, root) = self.try_resolve_ty_var_with_root(ty_vid); + (res.unwrap_err(), TermVid::Ty(root)) + } + TermVid::Const(ct_vid) => { + let (res, root) = self.try_resolve_const_var_with_root(ct_vid); + (res.unwrap_err(), TermVid::Const(root)) } - TermVid::Const(ct_vid) => ( - self.try_resolve_const_var(ct_vid).unwrap_err(), - TermVid::Const(self.inner.borrow_mut().const_unification_table().find(ct_vid).vid), - ), }; let mut generalizer = Generalizer { diff --git a/compiler/rustc_public/src/unstable/internal_cx/mod.rs b/compiler/rustc_public/src/unstable/internal_cx/mod.rs index 6bc553aed89e9..f178ced7224c1 100644 --- a/compiler/rustc_public/src/unstable/internal_cx/mod.rs +++ b/compiler/rustc_public/src/unstable/internal_cx/mod.rs @@ -79,9 +79,9 @@ impl<'tcx> InternalCx<'tcx> for TyCtxt<'tcx> { where I: Iterator, T: ty::CollectAndApply< - ty::BoundVariableKind<'tcx>, - &'tcx List>, - >, + ty::BoundVariableKind<'tcx>, + &'tcx List>, + >, { TyCtxt::mk_bound_variable_kinds_from_iter(self, iter) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 45eca8d2c444d..09fbd69f97463 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -519,8 +519,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result { debug_assert!(!self.infcx.next_trait_solver()); self.evaluation_probe(|this| { - let goal = - this.infcx.deep_resolve_non_region_vars((obligation.predicate, obligation.param_env)); + let goal = this + .infcx + .deep_resolve_non_region_vars((obligation.predicate, obligation.param_env)); let mut result = this.evaluate_predicate_recursively( TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()), obligation.clone(),