1
Fork 0

Rollup merge of #120670 - lcnr:effect-var-storage, r=fee1-dead

cleanup effect var handling

r? types
This commit is contained in:
Matthias Krüger 2024-02-06 19:40:09 +01:00 committed by GitHub
commit cee621203e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 52 additions and 71 deletions

View file

@ -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 },

View file

@ -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()
} }

View file

@ -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),

View file

@ -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,
} }
} }

View file

@ -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")
}

View file

@ -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() {

View file

@ -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()