Rollup merge of #120670 - lcnr:effect-var-storage, r=fee1-dead
cleanup effect var handling r? types
This commit is contained in:
commit
cee621203e
7 changed files with 52 additions and 71 deletions
|
@ -481,7 +481,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
ty::ConstKind::Infer(InferConst::EffectVar(vid)) => {
|
ty::ConstKind::Infer(InferConst::EffectVar(vid)) => {
|
||||||
match self.infcx.unwrap().probe_effect_var(vid) {
|
match self.infcx.unwrap().probe_effect_var(vid) {
|
||||||
Some(value) => return self.fold_const(value.as_const(self.tcx)),
|
Some(value) => return self.fold_const(value),
|
||||||
None => {
|
None => {
|
||||||
return self.canonicalize_const_var(
|
return self.canonicalize_const_var(
|
||||||
CanonicalVarInfo { kind: CanonicalVarKind::Effect },
|
CanonicalVarInfo { kind: CanonicalVarKind::Effect },
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind};
|
use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||||
use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind};
|
use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
|
use rustc_middle::infer::unify_key::EffectVarValue;
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::GenericArg;
|
use rustc_middle::ty::GenericArg;
|
||||||
use rustc_middle::ty::{self, List, Ty, TyCtxt};
|
use rustc_middle::ty::{self, List, Ty, TyCtxt};
|
||||||
|
@ -152,7 +153,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
CanonicalVarKind::Effect => {
|
CanonicalVarKind::Effect => {
|
||||||
let vid = self.inner.borrow_mut().effect_unification_table().new_key(None).vid;
|
let vid = self
|
||||||
|
.inner
|
||||||
|
.borrow_mut()
|
||||||
|
.effect_unification_table()
|
||||||
|
.new_key(EffectVarValue::Unknown)
|
||||||
|
.vid;
|
||||||
ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid), self.tcx.types.bool)
|
ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid), self.tcx.types.bool)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,13 +151,8 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
|
||||||
self.freshen_const(opt_ct, ty::InferConst::Var(v), ty::InferConst::Fresh, ct.ty())
|
self.freshen_const(opt_ct, ty::InferConst::Var(v), ty::InferConst::Fresh, ct.ty())
|
||||||
}
|
}
|
||||||
ty::ConstKind::Infer(ty::InferConst::EffectVar(v)) => {
|
ty::ConstKind::Infer(ty::InferConst::EffectVar(v)) => {
|
||||||
let opt_ct = self
|
let opt_ct =
|
||||||
.infcx
|
self.infcx.inner.borrow_mut().effect_unification_table().probe_value(v).known();
|
||||||
.inner
|
|
||||||
.borrow_mut()
|
|
||||||
.effect_unification_table()
|
|
||||||
.probe_value(v)
|
|
||||||
.map(|effect| effect.as_const(self.infcx.tcx));
|
|
||||||
self.freshen_const(
|
self.freshen_const(
|
||||||
opt_ct,
|
opt_ct,
|
||||||
ty::InferConst::EffectVar(v),
|
ty::InferConst::EffectVar(v),
|
||||||
|
|
|
@ -8,6 +8,7 @@ pub use self::ValuePairs::*;
|
||||||
pub use relate::combine::ObligationEmittingRelation;
|
pub use relate::combine::ObligationEmittingRelation;
|
||||||
use rustc_data_structures::captures::Captures;
|
use rustc_data_structures::captures::Captures;
|
||||||
use rustc_data_structures::undo_log::UndoLogs;
|
use rustc_data_structures::undo_log::UndoLogs;
|
||||||
|
use rustc_middle::infer::unify_key::EffectVarValue;
|
||||||
use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
|
use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
|
||||||
|
|
||||||
use self::opaque_types::OpaqueTypeStorage;
|
use self::opaque_types::OpaqueTypeStorage;
|
||||||
|
@ -25,8 +26,8 @@ use rustc_data_structures::unify as ut;
|
||||||
use rustc_errors::{DiagCtxt, DiagnosticBuilder, ErrorGuaranteed};
|
use rustc_errors::{DiagCtxt, DiagnosticBuilder, ErrorGuaranteed};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
|
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
|
||||||
|
use rustc_middle::infer::unify_key::ConstVariableValue;
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
|
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableValue, EffectVarValue};
|
|
||||||
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
|
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
|
||||||
use rustc_middle::mir::ConstraintCategory;
|
use rustc_middle::mir::ConstraintCategory;
|
||||||
use rustc_middle::traits::{select, DefiningAnchor};
|
use rustc_middle::traits::{select, DefiningAnchor};
|
||||||
|
@ -818,7 +819,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
|
|
||||||
(0..table.len())
|
(0..table.len())
|
||||||
.map(|i| ty::EffectVid::from_usize(i))
|
.map(|i| ty::EffectVid::from_usize(i))
|
||||||
.filter(|&vid| table.probe_value(vid).is_none())
|
.filter(|&vid| table.probe_value(vid).is_unknown())
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v), self.tcx.types.bool)
|
ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v), self.tcx.types.bool)
|
||||||
})
|
})
|
||||||
|
@ -1236,7 +1237,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn var_for_effect(&self, param: &ty::GenericParamDef) -> GenericArg<'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).vid;
|
let effect_vid =
|
||||||
|
self.inner.borrow_mut().effect_unification_table().new_key(EffectVarValue::Unknown).vid;
|
||||||
let ty = self
|
let ty = self
|
||||||
.tcx
|
.tcx
|
||||||
.type_of(param.def_id)
|
.type_of(param.def_id)
|
||||||
|
@ -1416,8 +1418,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn probe_effect_var(&self, vid: EffectVid) -> Option<EffectVarValue<'tcx>> {
|
pub fn probe_effect_var(&self, vid: EffectVid) -> Option<ty::Const<'tcx>> {
|
||||||
self.inner.borrow_mut().effect_unification_table().probe_value(vid)
|
self.inner.borrow_mut().effect_unification_table().probe_value(vid).known()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to resolve all type/region/const variables in
|
/// Attempts to resolve all type/region/const variables in
|
||||||
|
@ -1897,7 +1899,8 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ShallowResolver<'a, 'tcx> {
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.effect_unification_table()
|
.effect_unification_table()
|
||||||
.probe_value(vid)
|
.probe_value(vid)
|
||||||
.map_or(ct, |val| val.as_const(self.infcx.tcx)),
|
.known()
|
||||||
|
.unwrap_or(ct),
|
||||||
_ => ct,
|
_ => ct,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,11 +202,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
ty::ConstKind::Infer(InferConst::EffectVar(a_vid)),
|
ty::ConstKind::Infer(InferConst::EffectVar(a_vid)),
|
||||||
ty::ConstKind::Infer(InferConst::EffectVar(b_vid)),
|
ty::ConstKind::Infer(InferConst::EffectVar(b_vid)),
|
||||||
) => {
|
) => {
|
||||||
self.inner
|
self.inner.borrow_mut().effect_unification_table().union(a_vid, b_vid);
|
||||||
.borrow_mut()
|
|
||||||
.effect_unification_table()
|
|
||||||
.unify_var_var(a_vid, b_vid)
|
|
||||||
.map_err(|a| effect_unification_error(self.tcx, relation.a_is_expected(), a))?;
|
|
||||||
return Ok(a);
|
return Ok(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,19 +229,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
(ty::ConstKind::Infer(InferConst::EffectVar(vid)), _) => {
|
(ty::ConstKind::Infer(InferConst::EffectVar(vid)), _) => {
|
||||||
return self.unify_effect_variable(
|
return Ok(self.unify_effect_variable(vid, b));
|
||||||
relation.a_is_expected(),
|
|
||||||
vid,
|
|
||||||
EffectVarValue::Const(b),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(_, ty::ConstKind::Infer(InferConst::EffectVar(vid))) => {
|
(_, ty::ConstKind::Infer(InferConst::EffectVar(vid))) => {
|
||||||
return self.unify_effect_variable(
|
return Ok(self.unify_effect_variable(vid, a));
|
||||||
!relation.a_is_expected(),
|
|
||||||
vid,
|
|
||||||
EffectVarValue::Const(a),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
|
(ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
|
||||||
|
@ -366,18 +354,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
Ok(Ty::new_float(self.tcx, val))
|
Ok(Ty::new_float(self.tcx, val))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unify_effect_variable(
|
fn unify_effect_variable(&self, vid: ty::EffectVid, val: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
&self,
|
|
||||||
vid_is_expected: bool,
|
|
||||||
vid: ty::EffectVid,
|
|
||||||
val: EffectVarValue<'tcx>,
|
|
||||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
|
||||||
self.inner
|
self.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.effect_unification_table()
|
.effect_unification_table()
|
||||||
.unify_var_value(vid, Some(val))
|
.union_value(vid, EffectVarValue::Known(val));
|
||||||
.map_err(|e| effect_unification_error(self.tcx, vid_is_expected, e))?;
|
val
|
||||||
Ok(val.as_const(self.tcx))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,11 +561,3 @@ fn float_unification_error<'tcx>(
|
||||||
let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
|
let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
|
||||||
TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b))
|
TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn effect_unification_error<'tcx>(
|
|
||||||
_tcx: TyCtxt<'tcx>,
|
|
||||||
_a_is_expected: bool,
|
|
||||||
(_a, _b): (EffectVarValue<'tcx>, EffectVarValue<'tcx>),
|
|
||||||
) -> TypeError<'tcx> {
|
|
||||||
bug!("unexpected effect unification error")
|
|
||||||
}
|
|
||||||
|
|
|
@ -237,14 +237,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerResolver<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
|
ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
|
||||||
debug_assert_eq!(c.ty(), self.infcx.tcx.types.bool);
|
debug_assert_eq!(c.ty(), self.infcx.tcx.types.bool);
|
||||||
match self.infcx.probe_effect_var(vid) {
|
self.infcx.probe_effect_var(vid).unwrap_or_else(|| {
|
||||||
Some(c) => c.as_const(self.infcx.tcx),
|
ty::Const::new_infer(
|
||||||
None => ty::Const::new_infer(
|
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
ty::InferConst::EffectVar(self.infcx.root_effect_var(vid)),
|
ty::InferConst::EffectVar(self.infcx.root_effect_var(vid)),
|
||||||
self.infcx.tcx.types.bool,
|
self.infcx.tcx.types.bool,
|
||||||
),
|
)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if c.has_infer() {
|
if c.has_infer() {
|
||||||
|
|
|
@ -194,33 +194,37 @@ impl<'tcx> UnifyValue for ConstVariableValue<'tcx> {
|
||||||
/// values for the effect inference variable
|
/// values for the effect inference variable
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum EffectVarValue<'tcx> {
|
pub enum EffectVarValue<'tcx> {
|
||||||
/// The host effect is on, enabling access to syscalls, filesystem access, etc.
|
Unknown,
|
||||||
Host,
|
Known(ty::Const<'tcx>),
|
||||||
/// The host effect is off. Execution is restricted to const operations only.
|
|
||||||
NoHost,
|
|
||||||
Const(ty::Const<'tcx>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> EffectVarValue<'tcx> {
|
impl<'tcx> EffectVarValue<'tcx> {
|
||||||
pub fn as_const(self, tcx: TyCtxt<'tcx>) -> ty::Const<'tcx> {
|
pub fn known(self) -> Option<ty::Const<'tcx>> {
|
||||||
match self {
|
match self {
|
||||||
EffectVarValue::Host => tcx.consts.true_,
|
EffectVarValue::Unknown => None,
|
||||||
EffectVarValue::NoHost => tcx.consts.false_,
|
EffectVarValue::Known(value) => Some(value),
|
||||||
EffectVarValue::Const(c) => c,
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_unknown(self) -> bool {
|
||||||
|
match self {
|
||||||
|
EffectVarValue::Unknown => true,
|
||||||
|
EffectVarValue::Known(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> UnifyValue for EffectVarValue<'tcx> {
|
impl<'tcx> UnifyValue for EffectVarValue<'tcx> {
|
||||||
type Error = (EffectVarValue<'tcx>, EffectVarValue<'tcx>);
|
type Error = NoError;
|
||||||
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
|
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
|
||||||
match (value1, value2) {
|
match (*value1, *value2) {
|
||||||
(EffectVarValue::Host, EffectVarValue::Host) => Ok(EffectVarValue::Host),
|
(EffectVarValue::Unknown, EffectVarValue::Unknown) => Ok(EffectVarValue::Unknown),
|
||||||
(EffectVarValue::NoHost, EffectVarValue::NoHost) => Ok(EffectVarValue::NoHost),
|
(EffectVarValue::Unknown, EffectVarValue::Known(val))
|
||||||
(EffectVarValue::NoHost | EffectVarValue::Host, _)
|
| (EffectVarValue::Known(val), EffectVarValue::Unknown) => {
|
||||||
| (_, EffectVarValue::NoHost | EffectVarValue::Host) => Err((*value1, *value2)),
|
Ok(EffectVarValue::Known(val))
|
||||||
(EffectVarValue::Const(_), EffectVarValue::Const(_)) => {
|
}
|
||||||
bug!("equating two const variables, both of which have known values")
|
(EffectVarValue::Known(_), EffectVarValue::Known(_)) => {
|
||||||
|
bug!("equating known inference variables: {value1:?} {value2:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +233,7 @@ impl<'tcx> UnifyValue for EffectVarValue<'tcx> {
|
||||||
#[derive(PartialEq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Copy, Clone, Debug)]
|
||||||
pub struct EffectVidKey<'tcx> {
|
pub struct EffectVidKey<'tcx> {
|
||||||
pub vid: ty::EffectVid,
|
pub vid: ty::EffectVid,
|
||||||
pub phantom: PhantomData<EffectVarValue<'tcx>>,
|
pub phantom: PhantomData<ty::Const<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> From<ty::EffectVid> for EffectVidKey<'tcx> {
|
impl<'tcx> From<ty::EffectVid> for EffectVidKey<'tcx> {
|
||||||
|
@ -239,7 +243,7 @@ impl<'tcx> From<ty::EffectVid> for EffectVidKey<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> UnifyKey for EffectVidKey<'tcx> {
|
impl<'tcx> UnifyKey for EffectVidKey<'tcx> {
|
||||||
type Value = Option<EffectVarValue<'tcx>>;
|
type Value = EffectVarValue<'tcx>;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self) -> u32 {
|
fn index(&self) -> u32 {
|
||||||
self.vid.as_u32()
|
self.vid.as_u32()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue