Auto merge of #117139 - compiler-errors:vid-lifetimes, r=BoxyUwU
Get rid of `'tcx` lifetime on `ConstVid`, `EffectVid` These are simply newtyped numbers, so don't really have a reason (per se) to have a lifetime -- `TyVid` and `RegionVid` do not, for example. The only consequence of this is that we need to use a new key type for `UnifyKey` that mentions `'tcx`. This is already done for `RegionVid`, with `RegionVidKey<'tcx>`, but this `UnifyKey` trait implementation may have been the original reason to give `ConstVid` a lifetime. See the changes to `compiler/rustc_middle/src/infer/unify_key.rs` specifically. I consider the code cleaner this way, though -- we removed quite a few unnecessary `'tcx` in the process. This also makes it easier to uplift these two ids to `rustc_type_ir`, which I plan on doing in a follow-up PR. r? `@BoxyUwU`
This commit is contained in:
commit
2e4e2a8f28
@ -152,7 +152,7 @@ pub fn instantiate_canonical_var(
|
||||
)
|
||||
.into(),
|
||||
CanonicalVarKind::Effect => {
|
||||
let vid = self.inner.borrow_mut().effect_unification_table().new_key(None);
|
||||
let vid = self.inner.borrow_mut().effect_unification_table().new_key(None).vid;
|
||||
ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid), self.tcx.types.bool)
|
||||
.into()
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ pub fn super_combine_consts<R>(
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn unify_const_variable(
|
||||
&self,
|
||||
target_vid: ty::ConstVid<'tcx>,
|
||||
target_vid: ty::ConstVid,
|
||||
ct: ty::Const<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
||||
@ -381,7 +381,7 @@ fn unify_float_variable(
|
||||
fn unify_effect_variable(
|
||||
&self,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::EffectVid<'tcx>,
|
||||
vid: ty::EffectVid,
|
||||
val: EffectVarValue<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
||||
self.inner
|
||||
|
@ -42,7 +42,7 @@ pub struct TypeFreshener<'a, 'tcx> {
|
||||
ty_freshen_count: u32,
|
||||
const_freshen_count: u32,
|
||||
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
|
||||
const_freshen_map: FxHashMap<ty::InferConst<'tcx>, ty::Const<'tcx>>,
|
||||
const_freshen_map: FxHashMap<ty::InferConst, ty::Const<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
|
||||
@ -79,12 +79,12 @@ fn freshen_ty<F>(&mut self, opt_ty: Option<Ty<'tcx>>, key: ty::InferTy, mk_fresh
|
||||
fn freshen_const<F>(
|
||||
&mut self,
|
||||
opt_ct: Option<ty::Const<'tcx>>,
|
||||
key: ty::InferConst<'tcx>,
|
||||
key: ty::InferConst,
|
||||
freshener: F,
|
||||
ty: Ty<'tcx>,
|
||||
) -> ty::Const<'tcx>
|
||||
where
|
||||
F: FnOnce(u32) -> ty::InferConst<'tcx>,
|
||||
F: FnOnce(u32) -> ty::InferConst,
|
||||
{
|
||||
if let Some(ct) = opt_ct {
|
||||
return ct.fold_with(self);
|
||||
|
@ -1,3 +1,4 @@
|
||||
use rustc_middle::infer::unify_key::ConstVidKey;
|
||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
|
||||
|
||||
@ -23,14 +24,14 @@ fn vars_since_snapshot<'tcx, T>(
|
||||
}
|
||||
|
||||
fn const_vars_since_snapshot<'tcx>(
|
||||
table: &mut UnificationTable<'_, 'tcx, ConstVid<'tcx>>,
|
||||
table: &mut UnificationTable<'_, 'tcx, ConstVidKey<'tcx>>,
|
||||
snapshot_var_len: usize,
|
||||
) -> (Range<ConstVid<'tcx>>, Vec<ConstVariableOrigin>) {
|
||||
) -> (Range<ConstVid>, Vec<ConstVariableOrigin>) {
|
||||
let range = vars_since_snapshot(table, snapshot_var_len);
|
||||
(
|
||||
range.start..range.end,
|
||||
(range.start.index..range.end.index)
|
||||
.map(|index| table.probe_value(ConstVid::from_index(index)).origin)
|
||||
range.start.vid..range.end.vid,
|
||||
(range.start.index()..range.end.index())
|
||||
.map(|index| table.probe_value(ConstVid::from_u32(index)).origin)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
@ -172,7 +173,7 @@ pub struct InferenceFudger<'a, 'tcx> {
|
||||
int_vars: Range<IntVid>,
|
||||
float_vars: Range<FloatVid>,
|
||||
region_vars: (Range<RegionVid>, Vec<RegionVariableOrigin>),
|
||||
const_vars: (Range<ConstVid<'tcx>>, Vec<ConstVariableOrigin>),
|
||||
const_vars: (Range<ConstVid>, Vec<ConstVariableOrigin>),
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> {
|
||||
@ -235,7 +236,7 @@ fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
if self.const_vars.0.contains(&vid) {
|
||||
// This variable was created during the fudging.
|
||||
// Recreate it with a fresh variable here.
|
||||
let idx = (vid.index - self.const_vars.0.start.index) as usize;
|
||||
let idx = (vid.index() - self.const_vars.0.start.index()) as usize;
|
||||
let origin = self.const_vars.1[idx];
|
||||
self.infcx.next_const_var(ct.ty(), origin)
|
||||
} else {
|
||||
|
@ -17,7 +17,7 @@ pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>>
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
delegate: &mut D,
|
||||
term: T,
|
||||
for_vid: impl Into<ty::TermVid<'tcx>>,
|
||||
for_vid: impl Into<ty::TermVid>,
|
||||
ambient_variance: ty::Variance,
|
||||
) -> RelateResult<'tcx, Generalization<T>> {
|
||||
let (for_universe, root_vid) = match for_vid.into() {
|
||||
@ -27,7 +27,7 @@ pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>>
|
||||
),
|
||||
ty::TermVid::Const(ct_vid) => (
|
||||
infcx.probe_const_var(ct_vid).unwrap_err(),
|
||||
ty::TermVid::Const(infcx.inner.borrow_mut().const_unification_table().find(ct_vid)),
|
||||
ty::TermVid::Const(infcx.inner.borrow_mut().const_unification_table().find(ct_vid).vid),
|
||||
),
|
||||
};
|
||||
|
||||
@ -127,7 +127,7 @@ struct Generalizer<'me, 'tcx, D> {
|
||||
/// The vid of the type variable that is in the process of being
|
||||
/// instantiated. If we find this within the value we are folding,
|
||||
/// that means we would have created a cyclic value.
|
||||
root_vid: ty::TermVid<'tcx>,
|
||||
root_vid: ty::TermVid,
|
||||
|
||||
/// The universe of the type variable that is in the process of being
|
||||
/// instantiated. If we find anything that this universe cannot name,
|
||||
@ -376,7 +376,7 @@ fn consts(
|
||||
// `vid` are related and we'd be inferring an infinitely
|
||||
// deep const.
|
||||
if ty::TermVid::Const(
|
||||
self.infcx.inner.borrow_mut().const_unification_table().find(vid),
|
||||
self.infcx.inner.borrow_mut().const_unification_table().find(vid).vid,
|
||||
) == self.root_vid
|
||||
{
|
||||
return Err(self.cyclic_term_error());
|
||||
@ -394,10 +394,14 @@ fn consts(
|
||||
if self.for_universe.can_name(universe) {
|
||||
Ok(c)
|
||||
} else {
|
||||
let new_var_id = variable_table.new_key(ConstVarValue {
|
||||
origin: var_value.origin,
|
||||
val: ConstVariableValue::Unknown { universe: self.for_universe },
|
||||
});
|
||||
let new_var_id = variable_table
|
||||
.new_key(ConstVarValue {
|
||||
origin: var_value.origin,
|
||||
val: ConstVariableValue::Unknown {
|
||||
universe: self.for_universe,
|
||||
},
|
||||
})
|
||||
.vid;
|
||||
Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty()))
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,9 @@
|
||||
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};
|
||||
@ -40,7 +42,6 @@
|
||||
|
||||
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 @@ fn float_unification_table(&mut self) -> UnificationTable<'_, 'tcx, ty::FloatVid
|
||||
}
|
||||
|
||||
#[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)
|
||||
}
|
||||
|
||||
@ -359,7 +360,7 @@ fn universe_of_ty(&self, ty: ty::InferTy) -> Option<ty::UniverseIndex> {
|
||||
}
|
||||
}
|
||||
|
||||
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`
|
||||
@ -548,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.
|
||||
@ -563,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::*;
|
||||
|
||||
@ -794,7 +795,7 @@ pub fn unsolved_effects(&self) -> Vec<ty::Const<'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)
|
||||
@ -1072,15 +1073,20 @@ pub fn next_const_var_in_universe(
|
||||
.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 {
|
||||
@ -1194,11 +1200,15 @@ pub fn var_for_def(&self, span: Span, param: &ty::GenericParamDef) -> GenericArg
|
||||
),
|
||||
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,
|
||||
@ -1213,7 +1223,7 @@ pub fn var_for_def(&self, span: Span, param: &ty::GenericParamDef) -> GenericArg
|
||||
}
|
||||
|
||||
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)
|
||||
@ -1333,12 +1343,12 @@ pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
|
||||
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,
|
||||
@ -1402,17 +1412,14 @@ pub fn first_unresolved_const_or_ty_var<T>(
|
||||
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)
|
||||
}
|
||||
|
||||
@ -1423,7 +1430,7 @@ pub fn probe_effect_var(&self, vid: EffectVid<'tcx>) -> Option<EffectVarValue<'t
|
||||
///
|
||||
/// 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> {
|
||||
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() {
|
||||
@ -1647,11 +1654,11 @@ pub fn const_eval_resolve(
|
||||
#[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;
|
||||
|
||||
@ -1674,7 +1681,7 @@ pub fn is_ty_infer_var_definitely_unchanged<'a>(
|
||||
/// 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;
|
||||
@ -1781,7 +1788,7 @@ pub fn report_mismatched_consts(
|
||||
/// 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(_))`.
|
||||
@ -1790,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`).
|
||||
|
@ -192,7 +192,7 @@ fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
/// Full type resolution replaces all type and region variables with
|
||||
/// their concrete results. If any variable cannot be replaced (never unified, etc)
|
||||
/// then an `Err` result is returned.
|
||||
pub fn fully_resolve<'tcx, T>(infcx: &InferCtxt<'tcx>, value: T) -> FixupResult<'tcx, T>
|
||||
pub fn fully_resolve<'tcx, T>(infcx: &InferCtxt<'tcx>, value: T) -> FixupResult<T>
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
@ -206,7 +206,7 @@ struct FullTypeResolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> {
|
||||
type Error = FixupError<'tcx>;
|
||||
type Error = FixupError;
|
||||
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
|
@ -3,7 +3,7 @@
|
||||
use rustc_data_structures::snapshot_vec as sv;
|
||||
use rustc_data_structures::undo_log::{Rollback, UndoLogs};
|
||||
use rustc_data_structures::unify as ut;
|
||||
use rustc_middle::infer::unify_key::RegionVidKey;
|
||||
use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey, RegionVidKey};
|
||||
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey};
|
||||
|
||||
use crate::{
|
||||
@ -21,10 +21,10 @@ pub struct Snapshot<'tcx> {
|
||||
pub(crate) enum UndoLog<'tcx> {
|
||||
OpaqueTypes(OpaqueTypeKey<'tcx>, Option<OpaqueHiddenType<'tcx>>),
|
||||
TypeVariables(type_variable::UndoLog<'tcx>),
|
||||
ConstUnificationTable(sv::UndoLog<ut::Delegate<ty::ConstVid<'tcx>>>),
|
||||
ConstUnificationTable(sv::UndoLog<ut::Delegate<ConstVidKey<'tcx>>>),
|
||||
IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),
|
||||
FloatUnificationTable(sv::UndoLog<ut::Delegate<ty::FloatVid>>),
|
||||
EffectUnificationTable(sv::UndoLog<ut::Delegate<ty::EffectVid<'tcx>>>),
|
||||
EffectUnificationTable(sv::UndoLog<ut::Delegate<EffectVidKey<'tcx>>>),
|
||||
RegionConstraintCollector(region_constraints::UndoLog<'tcx>),
|
||||
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
|
||||
ProjectionCache(traits::UndoLog<'tcx>),
|
||||
@ -56,9 +56,9 @@ fn from(x: $ty) -> Self {
|
||||
IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),
|
||||
|
||||
FloatUnificationTable(sv::UndoLog<ut::Delegate<ty::FloatVid>>),
|
||||
EffectUnificationTable(sv::UndoLog<ut::Delegate<ty::EffectVid<'tcx>>>),
|
||||
EffectUnificationTable(sv::UndoLog<ut::Delegate<EffectVidKey<'tcx>>>),
|
||||
|
||||
ConstUnificationTable(sv::UndoLog<ut::Delegate<ty::ConstVid<'tcx>>>),
|
||||
ConstUnificationTable(sv::UndoLog<ut::Delegate<ConstVidKey<'tcx>>>),
|
||||
|
||||
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
|
||||
ProjectionCache(traits::UndoLog<'tcx>),
|
||||
|
@ -141,18 +141,30 @@ pub struct ConstVarValue<'tcx> {
|
||||
pub val: ConstVariableValue<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> UnifyKey for ty::ConstVid<'tcx> {
|
||||
#[derive(PartialEq, Copy, Clone, Debug)]
|
||||
pub struct ConstVidKey<'tcx> {
|
||||
pub vid: ty::ConstVid,
|
||||
pub phantom: PhantomData<ty::Const<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> From<ty::ConstVid> for ConstVidKey<'tcx> {
|
||||
fn from(vid: ty::ConstVid) -> Self {
|
||||
ConstVidKey { vid, phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UnifyKey for ConstVidKey<'tcx> {
|
||||
type Value = ConstVarValue<'tcx>;
|
||||
#[inline]
|
||||
fn index(&self) -> u32 {
|
||||
self.index
|
||||
self.vid.as_u32()
|
||||
}
|
||||
#[inline]
|
||||
fn from_index(i: u32) -> Self {
|
||||
ty::ConstVid { index: i, phantom: PhantomData }
|
||||
ConstVidKey::from(ty::ConstVid::from_u32(i))
|
||||
}
|
||||
fn tag() -> &'static str {
|
||||
"ConstVid"
|
||||
"ConstVidKey"
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,17 +236,29 @@ fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UnifyKey for ty::EffectVid<'tcx> {
|
||||
#[derive(PartialEq, Copy, Clone, Debug)]
|
||||
pub struct EffectVidKey<'tcx> {
|
||||
pub vid: ty::EffectVid,
|
||||
pub phantom: PhantomData<EffectVarValue<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> From<ty::EffectVid> for EffectVidKey<'tcx> {
|
||||
fn from(vid: ty::EffectVid) -> Self {
|
||||
EffectVidKey { vid, phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UnifyKey for EffectVidKey<'tcx> {
|
||||
type Value = Option<EffectVarValue<'tcx>>;
|
||||
#[inline]
|
||||
fn index(&self) -> u32 {
|
||||
self.index
|
||||
self.vid.as_u32()
|
||||
}
|
||||
#[inline]
|
||||
fn from_index(i: u32) -> Self {
|
||||
ty::EffectVid { index: i, phantom: PhantomData }
|
||||
EffectVidKey::from(ty::EffectVid::from_u32(i))
|
||||
}
|
||||
fn tag() -> &'static str {
|
||||
"EffectVid"
|
||||
"EffectVidKey"
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ pub fn new_param(tcx: TyCtxt<'tcx>, param: ty::ParamConst, ty: Ty<'tcx>) -> Cons
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_var(tcx: TyCtxt<'tcx>, infer: ty::ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
pub fn new_var(tcx: TyCtxt<'tcx>, infer: ty::ConstVid, ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Var(infer)), ty)
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ pub fn new_fresh(tcx: TyCtxt<'tcx>, fresh: u32, ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst, ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
Const::new(tcx, ty::ConstKind::Infer(infer), ty)
|
||||
}
|
||||
|
||||
|
@ -80,19 +80,19 @@ pub enum Expr<'tcx> {
|
||||
|
||||
/// An inference variable for a const, for use in const generics.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
|
||||
pub enum InferConst<'tcx> {
|
||||
pub enum InferConst {
|
||||
/// Infer the value of the const.
|
||||
Var(ty::ConstVid<'tcx>),
|
||||
Var(ty::ConstVid),
|
||||
/// Infer the value of the effect.
|
||||
///
|
||||
/// For why this is separate from the `Var` variant above, see the
|
||||
/// documentation on `EffectVid`.
|
||||
EffectVar(ty::EffectVid<'tcx>),
|
||||
EffectVar(ty::EffectVid),
|
||||
/// A fresh const variable. See `infer::freshen` for more details.
|
||||
Fresh(u32),
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for InferConst<'_> {
|
||||
impl<CTX> HashStable<CTX> for InferConst {
|
||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||
match self {
|
||||
InferConst::Var(_) | InferConst::EffectVar(_) => {
|
||||
|
@ -100,7 +100,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type PolyFnSig = PolyFnSig<'tcx>;
|
||||
type AllocId = crate::mir::interpret::AllocId;
|
||||
type Const = ty::Const<'tcx>;
|
||||
type InferConst = ty::InferConst<'tcx>;
|
||||
type InferConst = ty::InferConst;
|
||||
type AliasConst = ty::UnevaluatedConst<'tcx>;
|
||||
type PlaceholderConst = ty::PlaceholderConst<'tcx>;
|
||||
type ParamConst = ty::ParamConst;
|
||||
|
@ -1084,19 +1084,19 @@ pub fn index(self) -> usize {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub enum TermVid<'tcx> {
|
||||
pub enum TermVid {
|
||||
Ty(ty::TyVid),
|
||||
Const(ty::ConstVid<'tcx>),
|
||||
Const(ty::ConstVid),
|
||||
}
|
||||
|
||||
impl From<ty::TyVid> for TermVid<'_> {
|
||||
impl From<ty::TyVid> for TermVid {
|
||||
fn from(value: ty::TyVid) -> Self {
|
||||
TermVid::Ty(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> From<ty::ConstVid<'tcx>> for TermVid<'tcx> {
|
||||
fn from(value: ty::ConstVid<'tcx>) -> Self {
|
||||
impl From<ty::ConstVid> for TermVid {
|
||||
fn from(value: ty::ConstVid) -> Self {
|
||||
TermVid::Const(value)
|
||||
}
|
||||
}
|
||||
|
@ -1194,7 +1194,7 @@ fn ty_infer_name(&self, _: ty::TyVid) -> Option<Symbol> {
|
||||
None
|
||||
}
|
||||
|
||||
fn const_infer_name(&self, _: ty::ConstVid<'tcx>) -> Option<Symbol> {
|
||||
fn const_infer_name(&self, _: ty::ConstVid) -> Option<Symbol> {
|
||||
None
|
||||
}
|
||||
|
||||
@ -1742,7 +1742,7 @@ pub struct FmtPrinterData<'a, 'tcx> {
|
||||
pub region_highlight_mode: RegionHighlightMode<'tcx>,
|
||||
|
||||
pub ty_infer_name_resolver: Option<Box<dyn Fn(ty::TyVid) -> Option<Symbol> + 'a>>,
|
||||
pub const_infer_name_resolver: Option<Box<dyn Fn(ty::ConstVid<'tcx>) -> Option<Symbol> + 'a>>,
|
||||
pub const_infer_name_resolver: Option<Box<dyn Fn(ty::ConstVid) -> Option<Symbol> + 'a>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Deref for FmtPrinter<'a, 'tcx> {
|
||||
@ -2082,7 +2082,7 @@ fn reset_type_limit(&mut self) {
|
||||
self.printed_type_count = 0;
|
||||
}
|
||||
|
||||
fn const_infer_name(&self, id: ty::ConstVid<'tcx>) -> Option<Symbol> {
|
||||
fn const_infer_name(&self, id: ty::ConstVid) -> Option<Symbol> {
|
||||
self.0.const_infer_name_resolver.as_ref().and_then(|func| func(id))
|
||||
}
|
||||
|
||||
|
@ -128,18 +128,6 @@ fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "?{}c", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::EffectVid<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "?{}e", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
with_no_trimmed_paths!(fmt::Display::fmt(self, f))
|
||||
@ -251,7 +239,7 @@ fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::InferConst<'tcx> {
|
||||
impl fmt::Debug for ty::InferConst {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
InferConst::Var(var) => write!(f, "{var:?}"),
|
||||
@ -260,7 +248,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::InferConst<'tcx> {
|
||||
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::InferConst {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
f: &mut core::fmt::Formatter<'_>,
|
||||
@ -269,8 +257,8 @@ fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
match this.infcx.universe_of_ct(*this.data) {
|
||||
None => write!(f, "{:?}", this.data),
|
||||
Some(universe) => match *this.data {
|
||||
Var(vid) => write!(f, "?{}_{}c", vid.index, universe.index()),
|
||||
EffectVar(vid) => write!(f, "?{}_{}e", vid.index, universe.index()),
|
||||
Var(vid) => write!(f, "?{}_{}c", vid.index(), universe.index()),
|
||||
EffectVar(vid) => write!(f, "?{}_{}e", vid.index(), universe.index()),
|
||||
Fresh(_) => {
|
||||
unreachable!()
|
||||
}
|
||||
@ -862,7 +850,7 @@ fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for InferConst<'tcx> {
|
||||
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for InferConst {
|
||||
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
|
||||
self,
|
||||
_folder: &mut F,
|
||||
@ -871,7 +859,7 @@ fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst<'tcx> {
|
||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst {
|
||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
|
||||
&self,
|
||||
_visitor: &mut V,
|
||||
|
@ -29,7 +29,6 @@
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{ControlFlow, Deref, Range};
|
||||
use ty::util::IntTypeExt;
|
||||
|
||||
@ -1583,26 +1582,22 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
/// A **`const`** **v**ariable **ID**.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(HashStable, TyEncodable, TyDecodable)]
|
||||
pub struct ConstVid<'tcx> {
|
||||
pub index: u32,
|
||||
pub phantom: PhantomData<&'tcx ()>,
|
||||
rustc_index::newtype_index! {
|
||||
/// A **`const`** **v**ariable **ID**.
|
||||
#[debug_format = "?{}c"]
|
||||
pub struct ConstVid {}
|
||||
}
|
||||
|
||||
/// An **effect** **v**ariable **ID**.
|
||||
///
|
||||
/// Handling effect infer variables happens separately from const infer variables
|
||||
/// because we do not want to reuse any of the const infer machinery. If we try to
|
||||
/// relate an effect variable with a normal one, we would ICE, which can catch bugs
|
||||
/// where we are not correctly using the effect var for an effect param. Fallback
|
||||
/// is also implemented on top of having separate effect and normal const variables.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
pub struct EffectVid<'tcx> {
|
||||
pub index: u32,
|
||||
pub phantom: PhantomData<&'tcx ()>,
|
||||
rustc_index::newtype_index! {
|
||||
/// An **effect** **v**ariable **ID**.
|
||||
///
|
||||
/// Handling effect infer variables happens separately from const infer variables
|
||||
/// because we do not want to reuse any of the const infer machinery. If we try to
|
||||
/// relate an effect variable with a normal one, we would ICE, which can catch bugs
|
||||
/// where we are not correctly using the effect var for an effect param. Fallback
|
||||
/// is also implemented on top of having separate effect and normal const variables.
|
||||
#[debug_format = "?{}e"]
|
||||
pub struct EffectVid {}
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::infer::{InferCtxt, TyOrConstInferVar};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::obligation_forest::ProcessResult;
|
||||
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
|
||||
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
|
||||
@ -68,7 +69,7 @@ pub struct PendingPredicateObligation<'tcx> {
|
||||
// should mostly optimize for reading speed, while modifying is not as relevant.
|
||||
//
|
||||
// For whatever reason using a boxed slice is slower than using a `Vec` here.
|
||||
pub stalled_on: Vec<TyOrConstInferVar<'tcx>>,
|
||||
pub stalled_on: Vec<TyOrConstInferVar>,
|
||||
}
|
||||
|
||||
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
@ -669,7 +670,7 @@ fn process_trait_obligation(
|
||||
&mut self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_obligation: PolyTraitObligation<'tcx>,
|
||||
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
|
||||
stalled_on: &mut Vec<TyOrConstInferVar>,
|
||||
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
|
||||
let infcx = self.selcx.infcx;
|
||||
if obligation.predicate.is_global() && !self.selcx.is_intercrate() {
|
||||
@ -722,7 +723,7 @@ fn process_projection_obligation(
|
||||
&mut self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
project_obligation: PolyProjectionObligation<'tcx>,
|
||||
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
|
||||
stalled_on: &mut Vec<TyOrConstInferVar>,
|
||||
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
|
||||
let tcx = self.selcx.tcx();
|
||||
|
||||
@ -775,7 +776,7 @@ fn process_projection_obligation(
|
||||
fn args_infer_vars<'a, 'tcx>(
|
||||
selcx: &SelectionContext<'a, 'tcx>,
|
||||
args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
|
||||
) -> impl Iterator<Item = TyOrConstInferVar<'tcx>> {
|
||||
) -> impl Iterator<Item = TyOrConstInferVar> + Captures<'tcx> {
|
||||
selcx
|
||||
.infcx
|
||||
.resolve_vars_if_possible(args)
|
||||
|
Loading…
Reference in New Issue
Block a user