summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/infer')
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs67
-rw-r--r--compiler/rustc_middle/src/infer/mod.rs2
-rw-r--r--compiler/rustc_middle/src/infer/unify_key.rs50
3 files changed, 96 insertions, 23 deletions
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 81823118a..41beca072 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -27,19 +27,30 @@ use crate::ty::GenericArg;
use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt};
use rustc_macros::HashStable;
use smallvec::SmallVec;
+use std::fmt::Display;
use std::ops::Index;
/// A "canonicalized" type `V` is one where all free inference
/// variables have been rewritten to "canonical vars". These are
/// numbered starting from 0 in order of first appearance.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
+#[derive(HashStable, TypeFoldable, TypeVisitable)]
pub struct Canonical<'tcx, V> {
pub value: V,
pub max_universe: ty::UniverseIndex,
pub variables: CanonicalVarInfos<'tcx>,
}
+impl<'tcx, V: Display> std::fmt::Display for Canonical<'tcx, V> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(
+ f,
+ "Canonical {{ value: {}, max_universe: {:?}, variables: {:?} }}",
+ self.value, self.max_universe, self.variables
+ )
+ }
+}
+
pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>;
impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> {
@@ -61,7 +72,7 @@ impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> {
/// variables. You will need to supply it later to instantiate the
/// canonicalized query response.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
+#[derive(HashStable, TypeFoldable, TypeVisitable)]
pub struct CanonicalVarValues<'tcx> {
pub var_values: ty::GenericArgsRef<'tcx>,
}
@@ -173,6 +184,7 @@ impl<'tcx> CanonicalVarInfo<'tcx> {
CanonicalVarKind::PlaceholderRegion(..) => false,
CanonicalVarKind::Const(..) => true,
CanonicalVarKind::PlaceholderConst(_, _) => false,
+ CanonicalVarKind::Effect => true,
}
}
@@ -182,7 +194,8 @@ impl<'tcx> CanonicalVarInfo<'tcx> {
CanonicalVarKind::Ty(_)
| CanonicalVarKind::PlaceholderTy(_)
| CanonicalVarKind::Const(_, _)
- | CanonicalVarKind::PlaceholderConst(_, _) => false,
+ | CanonicalVarKind::PlaceholderConst(_, _)
+ | CanonicalVarKind::Effect => false,
}
}
@@ -190,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(),
@@ -222,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>),
}
@@ -229,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,
@@ -248,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 })
}
@@ -295,7 +311,7 @@ pub enum CanonicalTyVarKind {
/// After we execute a query with a canonicalized key, we get back a
/// `Canonical<QueryResponse<..>>`. You can use
/// `instantiate_query_result` to access the data in this result.
-#[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)]
+#[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable)]
pub struct QueryResponse<'tcx, R> {
pub var_values: CanonicalVarValues<'tcx>,
pub region_constraints: QueryRegionConstraints<'tcx>,
@@ -310,7 +326,7 @@ pub struct QueryResponse<'tcx, R> {
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
-#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
+#[derive(HashStable, TypeFoldable, TypeVisitable)]
pub struct QueryRegionConstraints<'tcx> {
pub outlives: Vec<QueryOutlivesConstraint<'tcx>>,
pub member_constraints: Vec<MemberConstraint<'tcx>>,
@@ -416,7 +432,7 @@ impl<'tcx, V> Canonical<'tcx, V> {
pub type QueryOutlivesConstraint<'tcx> =
(ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>, ConstraintCategory<'tcx>);
-TrivialTypeTraversalAndLiftImpls! {
+TrivialTypeTraversalImpls! {
crate::infer::canonical::Certainty,
crate::infer::canonical::CanonicalTyVarKind,
}
@@ -439,10 +455,17 @@ impl<'tcx> CanonicalVarValues<'tcx> {
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => {
let br = ty::BoundRegion {
var: ty::BoundVar::from_usize(i),
- kind: ty::BrAnon(None),
+ kind: ty::BrAnon,
};
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,
diff --git a/compiler/rustc_middle/src/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs
index 493bb8a68..1384611e1 100644
--- a/compiler/rustc_middle/src/infer/mod.rs
+++ b/compiler/rustc_middle/src/infer/mod.rs
@@ -13,7 +13,7 @@ use rustc_span::Span;
/// R0 member of [O1..On]
/// ```
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
+#[derive(HashStable, TypeFoldable, TypeVisitable)]
pub struct MemberConstraint<'tcx> {
/// The `DefId` and args of the opaque type causing this constraint.
/// Used for error reporting.
diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs
index 85fb9214d..7ca964759 100644
--- a/compiler/rustc_middle/src/infer/unify_key.rs
+++ b/compiler/rustc_middle/src/infer/unify_key.rs
@@ -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"
+ }
+}