summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer/src/infer/mod.rs')
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs92
1 files changed, 79 insertions, 13 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index aaabf1482..aeb3177af 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -21,7 +21,7 @@ use rustc_data_structures::unify as ut;
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
-use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
+use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVarValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
use rustc_middle::mir::ConstraintCategory;
@@ -33,13 +33,14 @@ use rustc_middle::ty::relate::RelateResult;
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
pub use rustc_middle::ty::IntVarValue;
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt};
-use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
+use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid};
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef};
use rustc_span::symbol::Symbol;
use rustc_span::Span;
use std::cell::{Cell, RefCell};
use std::fmt;
+use std::marker::PhantomData;
use self::combine::CombineFields;
use self::error_reporting::TypeErrCtxt;
@@ -115,6 +116,9 @@ pub struct InferCtxtInner<'tcx> {
/// Map from floating variable to the kind of float it represents.
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>>,
+
/// Tracks the set of region variables and the constraints between them.
///
/// This is initially `Some(_)` but when
@@ -172,6 +176,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
const_unification_storage: ut::UnificationTableStorage::new(),
int_unification_storage: ut::UnificationTableStorage::new(),
float_unification_storage: ut::UnificationTableStorage::new(),
+ effect_unification_storage: ut::UnificationTableStorage::new(),
region_constraint_storage: Some(RegionConstraintStorage::new()),
region_obligations: vec![],
opaque_type_storage: Default::default(),
@@ -223,6 +228,10 @@ impl<'tcx> InferCtxtInner<'tcx> {
self.const_unification_storage.with_log(&mut self.undo_log)
}
+ fn effect_unification_table(&mut self) -> UnificationTable<'_, 'tcx, ty::EffectVid<'tcx>> {
+ self.effect_unification_storage.with_log(&mut self.undo_log)
+ }
+
#[inline]
pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'_, 'tcx> {
self.region_constraint_storage
@@ -356,6 +365,7 @@ impl<'tcx> ty::InferCtxtLike<TyCtxt<'tcx>> for InferCtxt<'tcx> {
Err(universe) => Some(universe),
Ok(_) => None,
},
+ EffectVar(_) => None,
Fresh(_) => None,
}
}
@@ -373,7 +383,7 @@ pub enum ValuePairs<'tcx> {
Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
- Sigs(ExpectedFound<ty::FnSig<'tcx>>),
+ PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
ExistentialProjection(ExpectedFound<ty::PolyExistentialProjection<'tcx>>),
}
@@ -764,19 +774,32 @@ impl<'tcx> InferCtxt<'tcx> {
.collect();
vars.extend(
(0..inner.int_unification_table().len())
- .map(|i| ty::IntVid { index: i as u32 })
+ .map(|i| ty::IntVid::from_u32(i as u32))
.filter(|&vid| inner.int_unification_table().probe_value(vid).is_none())
.map(|v| Ty::new_int_var(self.tcx, v)),
);
vars.extend(
(0..inner.float_unification_table().len())
- .map(|i| ty::FloatVid { index: i as u32 })
+ .map(|i| ty::FloatVid::from_u32(i as u32))
.filter(|&vid| inner.float_unification_table().probe_value(vid).is_none())
.map(|v| Ty::new_float_var(self.tcx, v)),
);
vars
}
+ pub fn unsolved_effects(&self) -> Vec<ty::Const<'tcx>> {
+ let mut inner = self.inner.borrow_mut();
+ let mut table = inner.effect_unification_table();
+
+ (0..table.len())
+ .map(|i| ty::EffectVid { index: i as u32, phantom: PhantomData })
+ .filter(|&vid| table.probe_value(vid).is_none())
+ .map(|v| {
+ ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v), self.tcx.types.bool)
+ })
+ .collect()
+ }
+
fn combine_fields<'a>(
&'a self,
trace: TypeTrace<'tcx>,
@@ -1158,7 +1181,10 @@ impl<'tcx> InferCtxt<'tcx> {
Ty::new_var(self.tcx, ty_var_id).into()
}
- GenericParamDefKind::Const { .. } => {
+ GenericParamDefKind::Const { is_host_effect, .. } => {
+ if is_host_effect {
+ return self.var_for_effect(param);
+ }
let origin = ConstVariableOrigin {
kind: ConstVariableOriginKind::ConstParameterDefinition(
param.name,
@@ -1184,6 +1210,17 @@ impl<'tcx> InferCtxt<'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);
+ let ty = self
+ .tcx
+ .type_of(param.def_id)
+ .no_bound_vars()
+ .expect("const parameter types cannot be generic");
+ debug_assert_eq!(self.tcx.types.bool, ty);
+ ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid), ty).into()
+ }
+
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
/// type/region parameter to a fresh inference variable.
pub fn fresh_args_for_item(&self, span: Span, def_id: DefId) -> GenericArgsRef<'tcx> {
@@ -1298,6 +1335,10 @@ impl<'tcx> InferCtxt<'tcx> {
self.inner.borrow_mut().const_unification_table().find(var)
}
+ pub fn root_effect_var(&self, var: ty::EffectVid<'tcx>) -> ty::EffectVid<'tcx> {
+ self.inner.borrow_mut().effect_unification_table().find(var)
+ }
+
/// Resolves an int var to a rigid int type, if it was constrained to one,
/// or else the root int var in the unification table.
pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
@@ -1369,6 +1410,10 @@ impl<'tcx> InferCtxt<'tcx> {
}
}
+ pub fn probe_effect_var(&self, vid: EffectVid<'tcx>) -> Option<EffectVarValue<'tcx>> {
+ self.inner.borrow_mut().effect_unification_table().probe_value(vid)
+ }
+
/// Attempts to resolve all type/region/const variables in
/// `value`. Region inference must have been run already (e.g.,
/// by calling `resolve_regions_and_report_errors`). If some
@@ -1555,9 +1600,12 @@ impl<'tcx> InferCtxt<'tcx> {
if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? {
let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args));
if let Err(e) = ct.error_reported() {
- return Err(ErrorHandled::Reported(e.into()));
+ return Err(ErrorHandled::Reported(
+ e.into(),
+ span.unwrap_or(rustc_span::DUMMY_SP),
+ ));
} else if ct.has_non_region_infer() || ct.has_non_region_param() {
- return Err(ErrorHandled::TooGeneric);
+ return Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP)));
} else {
args = replace_param_and_infer_args_with_placeholder(tcx, args);
}
@@ -1649,6 +1697,14 @@ impl<'tcx> InferCtxt<'tcx> {
ConstVariableValue::Known { .. } => true,
}
}
+
+ TyOrConstInferVar::Effect(v) => {
+ // If `probe_value` returns `Some`, it never equals
+ // `ty::ConstKind::Infer(ty::InferConst::Effect(v))`.
+ //
+ // Not `inlined_probe_value(v)` because this call site is colder.
+ self.probe_effect_var(v).is_some()
+ }
}
}
}
@@ -1720,6 +1776,8 @@ pub enum TyOrConstInferVar<'tcx> {
/// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`.
Const(ConstVid<'tcx>),
+ /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::EffectVar(_))`.
+ Effect(EffectVid<'tcx>),
}
impl<'tcx> TyOrConstInferVar<'tcx> {
@@ -1750,6 +1808,7 @@ impl<'tcx> TyOrConstInferVar<'tcx> {
fn maybe_from_const(ct: ty::Const<'tcx>) -> Option<Self> {
match ct.kind() {
ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)),
+ ty::ConstKind::Infer(InferConst::EffectVar(v)) => Some(TyOrConstInferVar::Effect(v)),
_ => None,
}
}
@@ -1793,17 +1852,24 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ShallowResolver<'a, 'tcx> {
}
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
- if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() {
- self.infcx
+ match ct.kind() {
+ ty::ConstKind::Infer(InferConst::Var(vid)) => self
+ .infcx
.inner
.borrow_mut()
.const_unification_table()
.probe_value(vid)
.val
.known()
- .unwrap_or(ct)
- } else {
- ct
+ .unwrap_or(ct),
+ ty::ConstKind::Infer(InferConst::EffectVar(vid)) => self
+ .infcx
+ .inner
+ .borrow_mut()
+ .effect_unification_table()
+ .probe_value(vid)
+ .map_or(ct, |val| val.as_const(self.infcx.tcx)),
+ _ => ct,
}
}
}