summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer/src/infer/mod.rs')
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs114
1 files changed, 68 insertions, 46 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index aeb3177af..4ee897ffe 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -6,7 +6,9 @@ pub use self::RegionVariableOrigin::*;
pub use self::SubregionOrigin::*;
pub use self::ValuePairs::*;
pub use combine::ObligationEmittingRelation;
+use rustc_data_structures::captures::Captures;
use rustc_data_structures::undo_log::UndoLogs;
+use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
use self::opaque_types::OpaqueTypeStorage;
pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
@@ -36,11 +38,10 @@ use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtx
use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid};
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef};
use rustc_span::symbol::Symbol;
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
use std::cell::{Cell, RefCell};
use std::fmt;
-use std::marker::PhantomData;
use self::combine::CombineFields;
use self::error_reporting::TypeErrCtxt;
@@ -85,7 +86,7 @@ pub struct InferOk<'tcx, T> {
pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
-pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result"
+pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
pub(crate) type UnificationTable<'a, 'tcx, T> = ut::UnificationTable<
ut::InPlace<T, &'a mut ut::UnificationStorage<T>, &'a mut InferCtxtUndoLogs<'tcx>>,
@@ -108,7 +109,7 @@ pub struct InferCtxtInner<'tcx> {
type_variable_storage: type_variable::TypeVariableStorage<'tcx>,
/// Map from const parameter variable to the kind of const it represents.
- const_unification_storage: ut::UnificationTableStorage<ty::ConstVid<'tcx>>,
+ const_unification_storage: ut::UnificationTableStorage<ConstVidKey<'tcx>>,
/// Map from integral variable to the kind of integer it represents.
int_unification_storage: ut::UnificationTableStorage<ty::IntVid>,
@@ -117,7 +118,7 @@ pub struct InferCtxtInner<'tcx> {
float_unification_storage: ut::UnificationTableStorage<ty::FloatVid>,
/// Map from effect variable to the effect param it represents.
- effect_unification_storage: ut::UnificationTableStorage<ty::EffectVid<'tcx>>,
+ effect_unification_storage: ut::UnificationTableStorage<EffectVidKey<'tcx>>,
/// Tracks the set of region variables and the constraints between them.
///
@@ -224,11 +225,11 @@ impl<'tcx> InferCtxtInner<'tcx> {
}
#[inline]
- fn const_unification_table(&mut self) -> UnificationTable<'_, 'tcx, ty::ConstVid<'tcx>> {
+ fn const_unification_table(&mut self) -> UnificationTable<'_, 'tcx, ConstVidKey<'tcx>> {
self.const_unification_storage.with_log(&mut self.undo_log)
}
- fn effect_unification_table(&mut self) -> UnificationTable<'_, 'tcx, ty::EffectVid<'tcx>> {
+ fn effect_unification_table(&mut self) -> UnificationTable<'_, 'tcx, EffectVidKey<'tcx>> {
self.effect_unification_storage.with_log(&mut self.undo_log)
}
@@ -341,7 +342,9 @@ pub struct InferCtxt<'tcx> {
next_trait_solver: bool,
}
-impl<'tcx> ty::InferCtxtLike<TyCtxt<'tcx>> for InferCtxt<'tcx> {
+impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
+ type Interner = TyCtxt<'tcx>;
+
fn universe_of_ty(&self, ty: ty::InferTy) -> Option<ty::UniverseIndex> {
use InferTy::*;
match ty {
@@ -357,7 +360,7 @@ impl<'tcx> ty::InferCtxtLike<TyCtxt<'tcx>> for InferCtxt<'tcx> {
}
}
- fn universe_of_ct(&self, ct: ty::InferConst<'tcx>) -> Option<ty::UniverseIndex> {
+ fn universe_of_ct(&self, ct: ty::InferConst) -> Option<ty::UniverseIndex> {
use ty::InferConst::*;
match ct {
// Same issue as with `universe_of_ty`
@@ -546,11 +549,11 @@ pub enum NllRegionVariableOrigin {
// FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`.
#[derive(Copy, Clone, Debug)]
-pub enum FixupError<'tcx> {
+pub enum FixupError {
UnresolvedIntTy(IntVid),
UnresolvedFloatTy(FloatVid),
UnresolvedTy(TyVid),
- UnresolvedConst(ConstVid<'tcx>),
+ UnresolvedConst(ConstVid),
}
/// See the `region_obligations` field for more information.
@@ -561,7 +564,7 @@ pub struct RegionObligation<'tcx> {
pub origin: SubregionOrigin<'tcx>,
}
-impl<'tcx> fmt::Display for FixupError<'tcx> {
+impl fmt::Display for FixupError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::FixupError::*;
@@ -792,7 +795,7 @@ impl<'tcx> InferCtxt<'tcx> {
let mut table = inner.effect_unification_table();
(0..table.len())
- .map(|i| ty::EffectVid { index: i as u32, phantom: PhantomData })
+ .map(|i| ty::EffectVid::from_usize(i))
.filter(|&vid| table.probe_value(vid).is_none())
.map(|v| {
ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v), self.tcx.types.bool)
@@ -1070,15 +1073,20 @@ impl<'tcx> InferCtxt<'tcx> {
.inner
.borrow_mut()
.const_unification_table()
- .new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } });
+ .new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } })
+ .vid;
ty::Const::new_var(self.tcx, vid, ty)
}
- pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx> {
- self.inner.borrow_mut().const_unification_table().new_key(ConstVarValue {
- origin,
- val: ConstVariableValue::Unknown { universe: self.universe() },
- })
+ pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid {
+ self.inner
+ .borrow_mut()
+ .const_unification_table()
+ .new_key(ConstVarValue {
+ origin,
+ val: ConstVariableValue::Unknown { universe: self.universe() },
+ })
+ .vid
}
fn next_int_var_id(&self) -> IntVid {
@@ -1192,11 +1200,15 @@ impl<'tcx> InferCtxt<'tcx> {
),
span,
};
- let const_var_id =
- self.inner.borrow_mut().const_unification_table().new_key(ConstVarValue {
+ let const_var_id = self
+ .inner
+ .borrow_mut()
+ .const_unification_table()
+ .new_key(ConstVarValue {
origin,
val: ConstVariableValue::Unknown { universe: self.universe() },
- });
+ })
+ .vid;
ty::Const::new_var(
self.tcx,
const_var_id,
@@ -1211,7 +1223,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
pub fn var_for_effect(&self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
- let effect_vid = self.inner.borrow_mut().effect_unification_table().new_key(None);
+ let effect_vid = self.inner.borrow_mut().effect_unification_table().new_key(None).vid;
let ty = self
.tcx
.type_of(param.def_id)
@@ -1331,12 +1343,12 @@ impl<'tcx> InferCtxt<'tcx> {
self.inner.borrow_mut().type_variables().root_var(var)
}
- pub fn root_const_var(&self, var: ty::ConstVid<'tcx>) -> ty::ConstVid<'tcx> {
- self.inner.borrow_mut().const_unification_table().find(var)
+ pub fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
+ self.inner.borrow_mut().const_unification_table().find(var).vid
}
- pub fn root_effect_var(&self, var: ty::EffectVid<'tcx>) -> ty::EffectVid<'tcx> {
- self.inner.borrow_mut().effect_unification_table().find(var)
+ pub fn root_effect_var(&self, var: ty::EffectVid) -> ty::EffectVid {
+ self.inner.borrow_mut().effect_unification_table().find(var).vid
}
/// Resolves an int var to a rigid int type, if it was constrained to one,
@@ -1400,17 +1412,14 @@ impl<'tcx> InferCtxt<'tcx> {
value.visit_with(&mut resolve::UnresolvedTypeOrConstFinder::new(self)).break_value()
}
- pub fn probe_const_var(
- &self,
- vid: ty::ConstVid<'tcx>,
- ) -> Result<ty::Const<'tcx>, ty::UniverseIndex> {
+ pub fn probe_const_var(&self, vid: ty::ConstVid) -> Result<ty::Const<'tcx>, ty::UniverseIndex> {
match self.inner.borrow_mut().const_unification_table().probe_value(vid).val {
ConstVariableValue::Known { value } => Ok(value),
ConstVariableValue::Unknown { universe } => Err(universe),
}
}
- pub fn probe_effect_var(&self, vid: EffectVid<'tcx>) -> Option<EffectVarValue<'tcx>> {
+ pub fn probe_effect_var(&self, vid: EffectVid) -> Option<EffectVarValue<'tcx>> {
self.inner.borrow_mut().effect_unification_table().probe_value(vid)
}
@@ -1421,13 +1430,26 @@ impl<'tcx> InferCtxt<'tcx> {
///
/// This method is idempotent, but it not typically not invoked
/// except during the writeback phase.
- pub fn fully_resolve<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> FixupResult<'tcx, T> {
- let value = resolve::fully_resolve(self, value);
- assert!(
- value.as_ref().map_or(true, |value| !value.has_infer()),
- "`{value:?}` is not fully resolved"
- );
- value
+ pub fn fully_resolve<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> FixupResult<T> {
+ match resolve::fully_resolve(self, value) {
+ Ok(value) => {
+ if value.has_non_region_infer() {
+ bug!("`{value:?}` is not fully resolved");
+ }
+ if value.has_infer_regions() {
+ let guar = self
+ .tcx
+ .sess
+ .delay_span_bug(DUMMY_SP, format!("`{value:?}` is not fully resolved"));
+ Ok(self.tcx.fold_regions(value, |re, _| {
+ if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re }
+ }))
+ } else {
+ Ok(value)
+ }
+ }
+ Err(e) => Err(e),
+ }
}
// Instantiates the bound variables in a given binder with fresh inference
@@ -1632,11 +1654,11 @@ impl<'tcx> InferCtxt<'tcx> {
#[inline]
pub fn is_ty_infer_var_definitely_unchanged<'a>(
&'a self,
- ) -> (impl Fn(TyOrConstInferVar<'tcx>) -> bool + 'a) {
+ ) -> (impl Fn(TyOrConstInferVar) -> bool + Captures<'tcx> + 'a) {
// This hoists the borrow/release out of the loop body.
let inner = self.inner.try_borrow();
- return move |infer_var: TyOrConstInferVar<'tcx>| match (infer_var, &inner) {
+ return move |infer_var: TyOrConstInferVar| match (infer_var, &inner) {
(TyOrConstInferVar::Ty(ty_var), Ok(inner)) => {
use self::type_variable::TypeVariableValue;
@@ -1659,7 +1681,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// inference variables), and it handles both `Ty` and `ty::Const` without
/// having to resort to storing full `GenericArg`s in `stalled_on`.
#[inline(always)]
- pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar<'tcx>) -> bool {
+ pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar) -> bool {
match infer_var {
TyOrConstInferVar::Ty(v) => {
use self::type_variable::TypeVariableValue;
@@ -1766,7 +1788,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// Helper for [InferCtxt::ty_or_const_infer_var_changed] (see comment on that), currently
/// used only for `traits::fulfill`'s list of `stalled_on` inference variables.
#[derive(Copy, Clone, Debug)]
-pub enum TyOrConstInferVar<'tcx> {
+pub enum TyOrConstInferVar {
/// Equivalent to `ty::Infer(ty::TyVar(_))`.
Ty(TyVid),
/// Equivalent to `ty::Infer(ty::IntVar(_))`.
@@ -1775,12 +1797,12 @@ pub enum TyOrConstInferVar<'tcx> {
TyFloat(FloatVid),
/// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`.
- Const(ConstVid<'tcx>),
+ Const(ConstVid),
/// Equivalent to `ty::ConstKind::Infer(ty::InferConst::EffectVar(_))`.
- Effect(EffectVid<'tcx>),
+ Effect(EffectVid),
}
-impl<'tcx> TyOrConstInferVar<'tcx> {
+impl<'tcx> TyOrConstInferVar {
/// Tries to extract an inference variable from a type or a constant, returns `None`
/// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and
/// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).