Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/infer/mod.rs')
-rw-r--r--crates/hir-ty/src/next_solver/infer/mod.rs202
1 files changed, 88 insertions, 114 deletions
diff --git a/crates/hir-ty/src/next_solver/infer/mod.rs b/crates/hir-ty/src/next_solver/infer/mod.rs
index 1eacc295c9..f038c47a8b 100644
--- a/crates/hir-ty/src/next_solver/infer/mod.rs
+++ b/crates/hir-ty/src/next_solver/infer/mod.rs
@@ -28,16 +28,18 @@ use rustc_type_ir::{
use snapshot::undo_log::InferCtxtUndoLogs;
use tracing::{debug, instrument};
use traits::{ObligationCause, PredicateObligations};
-use type_variable::TypeVariableOrigin;
-use unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey};
+use unify_key::{ConstVariableValue, ConstVidKey};
pub use crate::next_solver::infer::traits::ObligationInspector;
-use crate::next_solver::{
- ArgOutlivesPredicate, BoundConst, BoundRegion, BoundTy, BoundVariableKind, Goal, Predicate,
- SolverContext,
- fold::BoundVarReplacerDelegate,
- infer::{at::ToTrace, select::EvaluationResult, traits::PredicateObligation},
- obligation_ctxt::ObligationCtxt,
+use crate::{
+ Span,
+ next_solver::{
+ ArgOutlivesPredicate, BoundConst, BoundRegion, BoundTy, BoundVariableKind, Goal, Predicate,
+ SolverContext,
+ fold::BoundVarReplacerDelegate,
+ infer::{at::ToTrace, select::EvaluationResult, traits::PredicateObligation},
+ obligation_ctxt::ObligationCtxt,
+ },
};
use super::{
@@ -364,13 +366,14 @@ impl<'db> InferCtxtBuilder<'db> {
/// (in other words, `S(C) = V`).
pub fn build_with_canonical<T>(
mut self,
+ span: Span,
input: &CanonicalQueryInput<'db, T>,
) -> (InferCtxt<'db>, T, CanonicalVarValues<'db>)
where
T: TypeFoldable<DbInterner<'db>>,
{
let infcx = self.build(input.typing_mode.0);
- let (value, args) = infcx.instantiate_canonical(&input.canonical);
+ let (value, args) = infcx.instantiate_canonical(span, &input.canonical);
(infcx, value, args)
}
@@ -427,12 +430,13 @@ impl<'db> InferCtxt<'db> {
))
}
- pub(crate) fn insert_type_vars<T>(&self, ty: T) -> T
+ pub(crate) fn insert_type_vars<T>(&self, ty: T, span: Span) -> T
where
T: TypeFoldable<DbInterner<'db>>,
{
struct Folder<'a, 'db> {
infcx: &'a InferCtxt<'db>,
+ span: Span,
}
impl<'db> TypeFolder<DbInterner<'db>> for Folder<'_, 'db> {
fn cx(&self) -> DbInterner<'db> {
@@ -444,7 +448,11 @@ impl<'db> InferCtxt<'db> {
return ty;
}
- if ty.is_ty_error() { self.infcx.next_ty_var() } else { ty.super_fold_with(self) }
+ if ty.is_ty_error() {
+ self.infcx.next_ty_var(self.span)
+ } else {
+ ty.super_fold_with(self)
+ }
}
fn fold_const(&mut self, ct: Const<'db>) -> Const<'db> {
@@ -453,18 +461,18 @@ impl<'db> InferCtxt<'db> {
}
if ct.is_ct_error() {
- self.infcx.next_const_var()
+ self.infcx.next_const_var(self.span)
} else {
ct.super_fold_with(self)
}
}
fn fold_region(&mut self, r: Region<'db>) -> Region<'db> {
- if r.is_error() { self.infcx.next_region_var() } else { r }
+ if r.is_error() { self.infcx.next_region_var(self.span) } else { r }
}
}
- ty.fold_with(&mut Folder { infcx: self })
+ ty.fold_with(&mut Folder { infcx: self, span })
}
/// Evaluates whether the predicate can be satisfied in the given
@@ -737,80 +745,49 @@ impl<'db> InferCtxt<'db> {
self.inner.borrow_mut().type_variables().num_vars()
}
- pub fn next_var_for_param(&self, id: GenericParamId) -> GenericArg<'db> {
- match id {
- GenericParamId::TypeParamId(_) => self.next_ty_var().into(),
- GenericParamId::ConstParamId(_) => self.next_const_var().into(),
- GenericParamId::LifetimeParamId(_) => self.next_region_var().into(),
- }
+ pub fn next_ty_var(&self, span: Span) -> Ty<'db> {
+ let vid = self.next_ty_vid(span);
+ Ty::new_var(self.interner, vid)
}
- pub fn next_ty_var(&self) -> Ty<'db> {
- self.next_ty_var_with_origin(TypeVariableOrigin { param_def_id: None })
+ pub fn next_ty_vid(&self, span: Span) -> TyVid {
+ self.next_ty_var_id_in_universe(self.universe(), span)
}
- pub fn next_ty_vid(&self) -> TyVid {
- self.inner
- .borrow_mut()
- .type_variables()
- .new_var(self.universe(), TypeVariableOrigin { param_def_id: None })
+ pub fn next_ty_var_id_in_universe(&self, universe: UniverseIndex, span: Span) -> TyVid {
+ self.inner.borrow_mut().type_variables().new_var(universe, span)
}
- pub fn next_ty_var_with_origin(&self, origin: TypeVariableOrigin) -> Ty<'db> {
- let vid = self.inner.borrow_mut().type_variables().new_var(self.universe(), origin);
+ pub fn next_ty_var_in_universe(&self, universe: UniverseIndex, span: Span) -> Ty<'db> {
+ let vid = self.next_ty_var_id_in_universe(universe, span);
Ty::new_var(self.interner, vid)
}
- pub fn next_ty_var_id_in_universe(&self, universe: UniverseIndex) -> TyVid {
- let origin = TypeVariableOrigin { param_def_id: None };
- self.inner.borrow_mut().type_variables().new_var(universe, origin)
- }
-
- pub fn next_ty_var_in_universe(&self, universe: UniverseIndex) -> Ty<'db> {
- let vid = self.next_ty_var_id_in_universe(universe);
- Ty::new_var(self.interner, vid)
+ pub fn next_const_var(&self, span: Span) -> Const<'db> {
+ let vid = self.next_const_vid(span);
+ Const::new_var(self.interner, vid)
}
- pub fn next_const_var(&self) -> Const<'db> {
- self.next_const_var_with_origin(ConstVariableOrigin {})
+ pub fn next_const_vid(&self, span: Span) -> ConstVid {
+ self.next_const_vid_in_universe(self.universe(), span)
}
- pub fn next_const_vid(&self) -> ConstVid {
+ pub fn next_const_vid_in_universe(&self, universe: UniverseIndex, span: Span) -> ConstVid {
self.inner
.borrow_mut()
.const_unification_table()
- .new_key(ConstVariableValue::Unknown {
- origin: ConstVariableOrigin {},
- universe: self.universe(),
- })
+ .new_key(ConstVariableValue::Unknown { span, universe })
.vid
}
- pub fn next_const_var_with_origin(&self, origin: ConstVariableOrigin) -> Const<'db> {
- let vid = self
- .inner
- .borrow_mut()
- .const_unification_table()
- .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
- .vid;
- Const::new_var(self.interner, vid)
- }
-
- pub fn next_const_var_in_universe(&self, universe: UniverseIndex) -> Const<'db> {
- let origin = ConstVariableOrigin {};
- let vid = self
- .inner
- .borrow_mut()
- .const_unification_table()
- .new_key(ConstVariableValue::Unknown { origin, universe })
- .vid;
+ pub fn next_const_var_in_universe(&self, universe: UniverseIndex, span: Span) -> Const<'db> {
+ let vid = self.next_const_vid_in_universe(universe, span);
Const::new_var(self.interner, vid)
}
pub fn next_int_var(&self) -> Ty<'db> {
- let next_int_var_id =
- self.inner.borrow_mut().int_unification_table().new_key(IntVarValue::Unknown);
- Ty::new_int_var(self.interner, next_int_var_id)
+ let vid = self.next_int_vid();
+ Ty::new_int_var(self.interner, vid)
}
pub fn next_int_vid(&self) -> IntVid {
@@ -828,27 +805,27 @@ impl<'db> InferCtxt<'db> {
/// Creates a fresh region variable with the next available index.
/// The variable will be created in the maximum universe created
/// thus far, allowing it to name any region created thus far.
- pub fn next_region_var(&self) -> Region<'db> {
- self.next_region_var_in_universe(self.universe())
+ pub fn next_region_var(&self, span: Span) -> Region<'db> {
+ self.next_region_var_in_universe(self.universe(), span)
}
- pub fn next_region_vid(&self) -> RegionVid {
- self.inner.borrow_mut().unwrap_region_constraints().new_region_var(self.universe())
+ pub fn next_region_vid(&self, span: Span) -> RegionVid {
+ self.inner.borrow_mut().unwrap_region_constraints().new_region_var(self.universe(), span)
}
/// Creates a fresh region variable with the next available index
/// in the given universe; typically, you can use
/// `next_region_var` and just use the maximal universe.
- pub fn next_region_var_in_universe(&self, universe: UniverseIndex) -> Region<'db> {
+ pub fn next_region_var_in_universe(&self, universe: UniverseIndex, span: Span) -> Region<'db> {
let region_var =
- self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe);
+ self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe, span);
Region::new_var(self.interner, region_var)
}
- pub fn next_term_var_of_kind(&self, term: Term<'db>) -> Term<'db> {
+ pub fn next_term_var_of_kind(&self, term: Term<'db>, span: Span) -> Term<'db> {
match term.kind() {
- TermKind::Ty(_) => self.next_ty_var().into(),
- TermKind::Const(_) => self.next_const_var().into(),
+ TermKind::Ty(_) => self.next_ty_var(span).into(),
+ TermKind::Const(_) => self.next_const_var(span).into(),
}
}
@@ -866,24 +843,12 @@ impl<'db> InferCtxt<'db> {
self.inner.borrow_mut().unwrap_region_constraints().num_region_vars()
}
- /// Just a convenient wrapper of `next_region_var` for using during NLL.
- #[instrument(skip(self), level = "debug")]
- pub fn next_nll_region_var(&self) -> Region<'db> {
- self.next_region_var()
- }
-
- /// Just a convenient wrapper of `next_region_var` for using during NLL.
- #[instrument(skip(self), level = "debug")]
- pub fn next_nll_region_var_in_universe(&self, universe: UniverseIndex) -> Region<'db> {
- self.next_region_var_in_universe(universe)
- }
-
- fn var_for_def(&self, id: GenericParamId) -> GenericArg<'db> {
+ pub fn var_for_def(&self, id: GenericParamId, span: Span) -> GenericArg<'db> {
match id {
GenericParamId::LifetimeParamId(_) => {
// Create a region inference variable for the given
// region parameter definition.
- self.next_region_var().into()
+ self.next_region_var(span).into()
}
GenericParamId::TypeParamId(_) => {
// Create a type inference variable for the given
@@ -894,41 +859,27 @@ impl<'db> InferCtxt<'db> {
// used in a path such as `Foo::<T, U>::new()` will
// use an inference variable for `C` with `[T, U]`
// as the generic parameters for the default, `(T, U)`.
- let ty_var_id = self
- .inner
- .borrow_mut()
- .type_variables()
- .new_var(self.universe(), TypeVariableOrigin { param_def_id: None });
-
- Ty::new_var(self.interner, ty_var_id).into()
- }
- GenericParamId::ConstParamId(_) => {
- let origin = ConstVariableOrigin {};
- let const_var_id = self
- .inner
- .borrow_mut()
- .const_unification_table()
- .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
- .vid;
- Const::new_var(self.interner, const_var_id).into()
+ self.next_ty_var(span).into()
}
+ GenericParamId::ConstParamId(_) => self.next_const_var(span).into(),
}
}
/// Given a set of generics defined on a type or impl, returns the generic parameters mapping
/// each type/region parameter to a fresh inference variable.
- pub fn fresh_args_for_item(&self, def_id: SolverDefId) -> GenericArgs<'db> {
- GenericArgs::for_item(self.interner, def_id, |_index, kind, _| self.var_for_def(kind))
+ pub fn fresh_args_for_item(&self, span: Span, def_id: SolverDefId) -> GenericArgs<'db> {
+ GenericArgs::for_item(self.interner, def_id, |_index, kind, _| self.var_for_def(kind, span))
}
/// Like `fresh_args_for_item()`, but first uses the args from `first`.
pub fn fill_rest_fresh_args(
&self,
+ span: Span,
def_id: SolverDefId,
first: impl IntoIterator<Item = GenericArg<'db>>,
) -> GenericArgs<'db> {
GenericArgs::fill_rest(self.interner, def_id, first, |_index, kind, _| {
- self.var_for_def(kind)
+ self.var_for_def(kind, span)
})
}
@@ -995,8 +946,8 @@ impl<'db> InferCtxt<'db> {
use self::type_variable::TypeVariableValue;
match self.inner.borrow_mut().type_variables().probe(vid) {
- TypeVariableValue::Known { value } => Ok(value),
- TypeVariableValue::Unknown { universe } => Err(universe),
+ TypeVariableValue::Known { value, .. } => Ok(value),
+ TypeVariableValue::Unknown { universe, .. } => Err(universe),
}
}
@@ -1064,6 +1015,13 @@ impl<'db> InferCtxt<'db> {
}
}
+ pub fn shallow_resolve_term(&self, term: Term<'db>) -> Term<'db> {
+ match term.kind() {
+ TermKind::Ty(ty) => self.shallow_resolve(ty).into(),
+ TermKind::Const(ct) => self.shallow_resolve_const(ct).into(),
+ }
+ }
+
pub fn root_var(&self, var: TyVid) -> TyVid {
self.inner.borrow_mut().type_variables().root_var(var)
}
@@ -1141,7 +1099,22 @@ impl<'db> InferCtxt<'db> {
pub fn probe_const_var(&self, vid: ConstVid) -> Result<Const<'db>, UniverseIndex> {
match self.inner.borrow_mut().const_unification_table().probe_value(vid) {
ConstVariableValue::Known { value } => Ok(value),
- ConstVariableValue::Unknown { origin: _, universe } => Err(universe),
+ ConstVariableValue::Unknown { span: _, universe } => Err(universe),
+ }
+ }
+
+ /// Returns the span of the type variable identified by `vid`.
+ ///
+ /// No attempt is made to resolve `vid` to its root variable.
+ pub fn type_var_span(&self, vid: TyVid) -> Span {
+ self.inner.borrow_mut().type_variables().var_span(vid)
+ }
+
+ /// Returns the span of the const variable identified by `vid`
+ pub fn const_var_span(&self, vid: ConstVid) -> Option<Span> {
+ match self.inner.borrow_mut().const_unification_table().probe_value(vid) {
+ ConstVariableValue::Known { .. } => None,
+ ConstVariableValue::Unknown { span, .. } => Some(span),
}
}
@@ -1154,6 +1127,7 @@ impl<'db> InferCtxt<'db> {
// use [`InferCtxt::enter_forall`] instead.
pub fn instantiate_binder_with_fresh_vars<T>(
&self,
+ span: Span,
_lbrct: BoundRegionConversionTime,
value: Binder<'db, T>,
) -> T
@@ -1169,9 +1143,9 @@ impl<'db> InferCtxt<'db> {
for bound_var_kind in bound_vars {
let arg: GenericArg<'db> = match bound_var_kind {
- BoundVariableKind::Ty(_) => self.next_ty_var().into(),
- BoundVariableKind::Region(_) => self.next_region_var().into(),
- BoundVariableKind::Const => self.next_const_var().into(),
+ BoundVariableKind::Ty(_) => self.next_ty_var(span).into(),
+ BoundVariableKind::Region(_) => self.next_region_var(span).into(),
+ BoundVariableKind::Const => self.next_const_var(span).into(),
};
args.push(arg);
}