Rollup merge of #115727 - fee1-dead-contrib:effect-fallback, r=oli-obk
Implement fallback for effect param r? `@oli-obk` or `@lcnr` tracking issue for this ongoing work: https://github.com/rust-lang/rust/issues/110395
This commit is contained in:
@@ -184,6 +184,7 @@ impl<'tcx> CanonicalVarInfo<'tcx> {
|
||||
CanonicalVarKind::PlaceholderRegion(..) => false,
|
||||
CanonicalVarKind::Const(..) => true,
|
||||
CanonicalVarKind::PlaceholderConst(_, _) => false,
|
||||
CanonicalVarKind::Effect => true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +194,8 @@ impl<'tcx> CanonicalVarInfo<'tcx> {
|
||||
CanonicalVarKind::Ty(_)
|
||||
| CanonicalVarKind::PlaceholderTy(_)
|
||||
| CanonicalVarKind::Const(_, _)
|
||||
| CanonicalVarKind::PlaceholderConst(_, _) => false,
|
||||
| CanonicalVarKind::PlaceholderConst(_, _)
|
||||
| CanonicalVarKind::Effect => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +203,8 @@ impl<'tcx> CanonicalVarInfo<'tcx> {
|
||||
match self.kind {
|
||||
CanonicalVarKind::Ty(_)
|
||||
| CanonicalVarKind::Region(_)
|
||||
| CanonicalVarKind::Const(_, _) => bug!("expected placeholder: {self:?}"),
|
||||
| CanonicalVarKind::Const(_, _)
|
||||
| CanonicalVarKind::Effect => bug!("expected placeholder: {self:?}"),
|
||||
|
||||
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.bound.var.as_usize(),
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.bound.var.as_usize(),
|
||||
@@ -233,6 +236,9 @@ pub enum CanonicalVarKind<'tcx> {
|
||||
/// Some kind of const inference variable.
|
||||
Const(ty::UniverseIndex, Ty<'tcx>),
|
||||
|
||||
/// Effect variable `'?E`.
|
||||
Effect,
|
||||
|
||||
/// A "placeholder" that represents "any const".
|
||||
PlaceholderConst(ty::PlaceholderConst<'tcx>, Ty<'tcx>),
|
||||
}
|
||||
@@ -240,11 +246,11 @@ pub enum CanonicalVarKind<'tcx> {
|
||||
impl<'tcx> CanonicalVarKind<'tcx> {
|
||||
pub fn universe(self) -> ty::UniverseIndex {
|
||||
match self {
|
||||
CanonicalVarKind::Ty(kind) => match kind {
|
||||
CanonicalTyVarKind::General(ui) => ui,
|
||||
CanonicalTyVarKind::Float | CanonicalTyVarKind::Int => ty::UniverseIndex::ROOT,
|
||||
},
|
||||
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => ui,
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => {
|
||||
ty::UniverseIndex::ROOT
|
||||
}
|
||||
CanonicalVarKind::Effect => ty::UniverseIndex::ROOT,
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe,
|
||||
CanonicalVarKind::Region(ui) => ui,
|
||||
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe,
|
||||
@@ -259,15 +265,14 @@ impl<'tcx> CanonicalVarKind<'tcx> {
|
||||
/// the updated universe is not the root.
|
||||
pub fn with_updated_universe(self, ui: ty::UniverseIndex) -> CanonicalVarKind<'tcx> {
|
||||
match self {
|
||||
CanonicalVarKind::Ty(kind) => match kind {
|
||||
CanonicalTyVarKind::General(_) => {
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
|
||||
}
|
||||
CanonicalTyVarKind::Int | CanonicalTyVarKind::Float => {
|
||||
assert_eq!(ui, ty::UniverseIndex::ROOT);
|
||||
CanonicalVarKind::Ty(kind)
|
||||
}
|
||||
},
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(_)) => {
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
|
||||
}
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float)
|
||||
| CanonicalVarKind::Effect => {
|
||||
assert_eq!(ui, ty::UniverseIndex::ROOT);
|
||||
self
|
||||
}
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderTy(ty::Placeholder { universe: ui, ..placeholder })
|
||||
}
|
||||
@@ -454,6 +459,13 @@ impl<'tcx> CanonicalVarValues<'tcx> {
|
||||
};
|
||||
ty::Region::new_late_bound(tcx, ty::INNERMOST, br).into()
|
||||
}
|
||||
CanonicalVarKind::Effect => ty::Const::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundVar::from_usize(i),
|
||||
tcx.types.bool,
|
||||
)
|
||||
.into(),
|
||||
CanonicalVarKind::Const(_, ty)
|
||||
| CanonicalVarKind::PlaceholderConst(_, ty) => ty::Const::new_bound(
|
||||
tcx,
|
||||
|
||||
@@ -188,3 +188,53 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// values for the effect inference variable
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum EffectVarValue<'tcx> {
|
||||
/// The host effect is on, enabling access to syscalls, filesystem access, etc.
|
||||
Host,
|
||||
/// The host effect is off. Execution is restricted to const operations only.
|
||||
NoHost,
|
||||
Const(ty::Const<'tcx>),
|
||||
}
|
||||
|
||||
impl<'tcx> EffectVarValue<'tcx> {
|
||||
pub fn as_const(self, tcx: TyCtxt<'tcx>) -> ty::Const<'tcx> {
|
||||
match self {
|
||||
EffectVarValue::Host => tcx.consts.true_,
|
||||
EffectVarValue::NoHost => tcx.consts.false_,
|
||||
EffectVarValue::Const(c) => c,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UnifyValue for EffectVarValue<'tcx> {
|
||||
type Error = (EffectVarValue<'tcx>, EffectVarValue<'tcx>);
|
||||
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
|
||||
match (value1, value2) {
|
||||
(EffectVarValue::Host, EffectVarValue::Host) => Ok(EffectVarValue::Host),
|
||||
(EffectVarValue::NoHost, EffectVarValue::NoHost) => Ok(EffectVarValue::NoHost),
|
||||
(EffectVarValue::NoHost | EffectVarValue::Host, _)
|
||||
| (_, EffectVarValue::NoHost | EffectVarValue::Host) => Err((*value1, *value2)),
|
||||
(EffectVarValue::Const(_), EffectVarValue::Const(_)) => {
|
||||
bug!("equating two const variables, both of which have known values")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UnifyKey for ty::EffectVid<'tcx> {
|
||||
type Value = Option<EffectVarValue<'tcx>>;
|
||||
#[inline]
|
||||
fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
#[inline]
|
||||
fn from_index(i: u32) -> Self {
|
||||
ty::EffectVid { index: i, phantom: PhantomData }
|
||||
}
|
||||
fn tag() -> &'static str {
|
||||
"EffectVid"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user