diff options
Diffstat (limited to 'compiler/rustc_infer/src/infer/mod.rs')
-rw-r--r-- | compiler/rustc_infer/src/infer/mod.rs | 92 |
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, } } } |