Rollup merge of #120021 - lcnr:const-var-value, r=compiler-errors
don't store const var origins for known vars r? types
This commit is contained in:
commit
b185606961
@ -13,7 +13,9 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
|||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
|
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
use rustc_middle::infer::unify_key::{
|
||||||
|
ConstVariableOrigin, ConstVariableOriginKind, ConstVariableValue,
|
||||||
|
};
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
||||||
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
|
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
|
||||||
use rustc_middle::ty::{self, InferConst};
|
use rustc_middle::ty::{self, InferConst};
|
||||||
@ -178,17 +180,23 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
printer.ty_infer_name_resolver = Some(Box::new(ty_getter));
|
printer.ty_infer_name_resolver = Some(Box::new(ty_getter));
|
||||||
let const_getter = move |ct_vid| {
|
let const_getter = move |ct_vid| match infcx
|
||||||
if infcx.probe_const_var(ct_vid).is_ok() {
|
.inner
|
||||||
|
.borrow_mut()
|
||||||
|
.const_unification_table()
|
||||||
|
.probe_value(ct_vid)
|
||||||
|
{
|
||||||
|
ConstVariableValue::Known { value: _ } => {
|
||||||
warn!("resolved const var in error message");
|
warn!("resolved const var in error message");
|
||||||
}
|
|
||||||
if let ConstVariableOriginKind::ConstParameterDefinition(name, _) =
|
|
||||||
infcx.inner.borrow_mut().const_unification_table().probe_value(ct_vid).origin.kind
|
|
||||||
{
|
|
||||||
return Some(name);
|
|
||||||
} else {
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
ConstVariableValue::Unknown { origin, universe: _ } => {
|
||||||
|
if let ConstVariableOriginKind::ConstParameterDefinition(name, _) = origin.kind {
|
||||||
|
return Some(name);
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
printer.const_infer_name_resolver = Some(Box::new(const_getter));
|
printer.const_infer_name_resolver = Some(Box::new(const_getter));
|
||||||
printer
|
printer
|
||||||
@ -303,7 +311,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
GenericArgKind::Const(ct) => {
|
GenericArgKind::Const(ct) => {
|
||||||
if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() {
|
if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() {
|
||||||
let origin =
|
let origin =
|
||||||
self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
|
match self.inner.borrow_mut().const_unification_table().probe_value(vid) {
|
||||||
|
ConstVariableValue::Known { value } => {
|
||||||
|
bug!("resolved infer var: {vid:?} {value}")
|
||||||
|
}
|
||||||
|
ConstVariableValue::Unknown { origin, universe: _ } => origin,
|
||||||
|
};
|
||||||
if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
|
if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
|
||||||
origin.kind
|
origin.kind
|
||||||
{
|
{
|
||||||
|
@ -146,14 +146,8 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
|
|||||||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
match ct.kind() {
|
match ct.kind() {
|
||||||
ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
|
ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
|
||||||
let opt_ct = self
|
let opt_ct =
|
||||||
.infcx
|
self.infcx.inner.borrow_mut().const_unification_table().probe_value(v).known();
|
||||||
.inner
|
|
||||||
.borrow_mut()
|
|
||||||
.const_unification_table()
|
|
||||||
.probe_value(v)
|
|
||||||
.val
|
|
||||||
.known();
|
|
||||||
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)) => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use rustc_middle::infer::unify_key::ConstVidKey;
|
use rustc_middle::infer::unify_key::{ConstVariableOriginKind, ConstVariableValue, ConstVidKey};
|
||||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||||
use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
|
use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
|
||||||
|
|
||||||
@ -28,10 +28,17 @@ fn const_vars_since_snapshot<'tcx>(
|
|||||||
snapshot_var_len: usize,
|
snapshot_var_len: usize,
|
||||||
) -> (Range<ConstVid>, Vec<ConstVariableOrigin>) {
|
) -> (Range<ConstVid>, Vec<ConstVariableOrigin>) {
|
||||||
let range = vars_since_snapshot(table, snapshot_var_len);
|
let range = vars_since_snapshot(table, snapshot_var_len);
|
||||||
|
|
||||||
(
|
(
|
||||||
range.start.vid..range.end.vid,
|
range.start.vid..range.end.vid,
|
||||||
(range.start.index()..range.end.index())
|
(range.start.index()..range.end.index())
|
||||||
.map(|index| table.probe_value(ConstVid::from_u32(index)).origin)
|
.map(|index| match table.probe_value(ConstVid::from_u32(index)) {
|
||||||
|
ConstVariableValue::Known { value: _ } => ConstVariableOrigin {
|
||||||
|
kind: ConstVariableOriginKind::MiscVariable,
|
||||||
|
span: rustc_span::DUMMY_SP,
|
||||||
|
},
|
||||||
|
ConstVariableValue::Unknown { origin, universe: _ } => origin,
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,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::{ConstVarValue, ConstVariableValue, EffectVarValue};
|
|
||||||
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};
|
||||||
@ -1086,7 +1086,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.const_unification_table()
|
.const_unification_table()
|
||||||
.new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } })
|
.new_key(ConstVariableValue::Unknown { origin, universe })
|
||||||
.vid;
|
.vid;
|
||||||
ty::Const::new_var(self.tcx, vid, ty)
|
ty::Const::new_var(self.tcx, vid, ty)
|
||||||
}
|
}
|
||||||
@ -1095,10 +1095,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
self.inner
|
self.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.const_unification_table()
|
.const_unification_table()
|
||||||
.new_key(ConstVarValue {
|
.new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
|
||||||
origin,
|
|
||||||
val: ConstVariableValue::Unknown { universe: self.universe() },
|
|
||||||
})
|
|
||||||
.vid
|
.vid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1217,10 +1214,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.const_unification_table()
|
.const_unification_table()
|
||||||
.new_key(ConstVarValue {
|
.new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
|
||||||
origin,
|
|
||||||
val: ConstVariableValue::Unknown { universe: self.universe() },
|
|
||||||
})
|
|
||||||
.vid;
|
.vid;
|
||||||
ty::Const::new_var(
|
ty::Const::new_var(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
@ -1410,9 +1404,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn probe_const_var(&self, vid: ty::ConstVid) -> Result<ty::Const<'tcx>, ty::UniverseIndex> {
|
pub fn probe_const_var(&self, vid: ty::ConstVid) -> Result<ty::Const<'tcx>, ty::UniverseIndex> {
|
||||||
match self.inner.borrow_mut().const_unification_table().probe_value(vid).val {
|
match self.inner.borrow_mut().const_unification_table().probe_value(vid) {
|
||||||
ConstVariableValue::Known { value } => Ok(value),
|
ConstVariableValue::Known { value } => Ok(value),
|
||||||
ConstVariableValue::Unknown { universe } => Err(universe),
|
ConstVariableValue::Unknown { origin: _, universe } => Err(universe),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1709,7 +1703,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
// `ty::ConstKind::Infer(ty::InferConst::Var(v))`.
|
// `ty::ConstKind::Infer(ty::InferConst::Var(v))`.
|
||||||
//
|
//
|
||||||
// Not `inlined_probe_value(v)` because this call site is colder.
|
// Not `inlined_probe_value(v)` because this call site is colder.
|
||||||
match self.inner.borrow_mut().const_unification_table().probe_value(v).val {
|
match self.inner.borrow_mut().const_unification_table().probe_value(v) {
|
||||||
ConstVariableValue::Unknown { .. } => false,
|
ConstVariableValue::Unknown { .. } => false,
|
||||||
ConstVariableValue::Known { .. } => true,
|
ConstVariableValue::Known { .. } => true,
|
||||||
}
|
}
|
||||||
@ -1876,7 +1870,6 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ShallowResolver<'a, 'tcx> {
|
|||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.const_unification_table()
|
.const_unification_table()
|
||||||
.probe_value(vid)
|
.probe_value(vid)
|
||||||
.val
|
|
||||||
.known()
|
.known()
|
||||||
.unwrap_or(ct),
|
.unwrap_or(ct),
|
||||||
ty::ConstKind::Infer(InferConst::EffectVar(vid)) => self
|
ty::ConstKind::Infer(InferConst::EffectVar(vid)) => self
|
||||||
|
@ -30,14 +30,12 @@ use super::sub::Sub;
|
|||||||
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
|
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
|
||||||
use crate::traits::{Obligation, PredicateObligations};
|
use crate::traits::{Obligation, PredicateObligations};
|
||||||
use rustc_middle::infer::canonical::OriginalQueryValues;
|
use rustc_middle::infer::canonical::OriginalQueryValues;
|
||||||
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVarValue};
|
use rustc_middle::infer::unify_key::{ConstVariableValue, EffectVarValue};
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
|
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
|
||||||
use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_middle::ty::{AliasRelationDirection, TyVar};
|
use rustc_middle::ty::{AliasRelationDirection, TyVar};
|
||||||
use rustc_middle::ty::{IntType, UintType};
|
use rustc_middle::ty::{IntType, UintType};
|
||||||
use rustc_span::DUMMY_SP;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CombineFields<'infcx, 'tcx> {
|
pub struct CombineFields<'infcx, 'tcx> {
|
||||||
@ -328,8 +326,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
ct: ty::Const<'tcx>,
|
ct: ty::Const<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
||||||
let span =
|
let span = match self.inner.borrow_mut().const_unification_table().probe_value(target_vid) {
|
||||||
self.inner.borrow_mut().const_unification_table().probe_value(target_vid).origin.span;
|
ConstVariableValue::Known { value } => {
|
||||||
|
bug!("instantiating a known const var: {target_vid:?} {value} {ct}")
|
||||||
|
}
|
||||||
|
ConstVariableValue::Unknown { origin, universe: _ } => origin.span,
|
||||||
|
};
|
||||||
// FIXME(generic_const_exprs): Occurs check failures for unevaluated
|
// FIXME(generic_const_exprs): Occurs check failures for unevaluated
|
||||||
// constants and generic expressions are not yet handled correctly.
|
// constants and generic expressions are not yet handled correctly.
|
||||||
let Generalization { value_may_be_infer: value, needs_wf: _ } = generalize::generalize(
|
let Generalization { value_may_be_infer: value, needs_wf: _ } = generalize::generalize(
|
||||||
@ -340,16 +342,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
ty::Variance::Invariant,
|
ty::Variance::Invariant,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.inner.borrow_mut().const_unification_table().union_value(
|
self.inner
|
||||||
target_vid,
|
.borrow_mut()
|
||||||
ConstVarValue {
|
.const_unification_table()
|
||||||
origin: ConstVariableOrigin {
|
.union_value(target_vid, ConstVariableValue::Known { value });
|
||||||
kind: ConstVariableOriginKind::ConstInference,
|
|
||||||
span: DUMMY_SP,
|
|
||||||
},
|
|
||||||
val: ConstVariableValue::Known { value },
|
|
||||||
},
|
|
||||||
);
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use std::mem;
|
|||||||
use rustc_data_structures::sso::SsoHashMap;
|
use rustc_data_structures::sso::SsoHashMap;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
|
use rustc_middle::infer::unify_key::ConstVariableValue;
|
||||||
use rustc_middle::ty::error::TypeError;
|
use rustc_middle::ty::error::TypeError;
|
||||||
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||||
use rustc_middle::ty::visit::MaxUniverse;
|
use rustc_middle::ty::visit::MaxUniverse;
|
||||||
@ -431,22 +431,19 @@ where
|
|||||||
|
|
||||||
let mut inner = self.infcx.inner.borrow_mut();
|
let mut inner = self.infcx.inner.borrow_mut();
|
||||||
let variable_table = &mut inner.const_unification_table();
|
let variable_table = &mut inner.const_unification_table();
|
||||||
let var_value = variable_table.probe_value(vid);
|
match variable_table.probe_value(vid) {
|
||||||
match var_value.val {
|
|
||||||
ConstVariableValue::Known { value: u } => {
|
ConstVariableValue::Known { value: u } => {
|
||||||
drop(inner);
|
drop(inner);
|
||||||
self.relate(u, u)
|
self.relate(u, u)
|
||||||
}
|
}
|
||||||
ConstVariableValue::Unknown { universe } => {
|
ConstVariableValue::Unknown { origin, universe } => {
|
||||||
if self.for_universe.can_name(universe) {
|
if self.for_universe.can_name(universe) {
|
||||||
Ok(c)
|
Ok(c)
|
||||||
} else {
|
} else {
|
||||||
let new_var_id = variable_table
|
let new_var_id = variable_table
|
||||||
.new_key(ConstVarValue {
|
.new_key(ConstVariableValue::Unknown {
|
||||||
origin: var_value.origin,
|
origin,
|
||||||
val: ConstVariableValue::Unknown {
|
universe: self.for_universe,
|
||||||
universe: self.for_universe,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
.vid;
|
.vid;
|
||||||
Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty()))
|
Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty()))
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use super::{FixupError, FixupResult, InferCtxt};
|
||||||
use super::{FixupError, FixupResult, InferCtxt, Span};
|
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
|
||||||
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
|
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
|
||||||
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitableExt, TypeVisitor};
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// OPPORTUNISTIC VAR RESOLVER
|
// OPPORTUNISTIC VAR RESOLVER
|
||||||
|
|
||||||
@ -104,88 +100,6 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticRegionResolver<'a, 'tcx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// UNRESOLVED TYPE FINDER
|
|
||||||
|
|
||||||
/// The unresolved type **finder** walks a type searching for
|
|
||||||
/// type variables that don't yet have a value. The first unresolved type is stored.
|
|
||||||
/// It does not construct the fully resolved type (which might
|
|
||||||
/// involve some hashing and so forth).
|
|
||||||
pub struct UnresolvedTypeOrConstFinder<'a, 'tcx> {
|
|
||||||
infcx: &'a InferCtxt<'tcx>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> UnresolvedTypeOrConstFinder<'a, 'tcx> {
|
|
||||||
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
|
|
||||||
UnresolvedTypeOrConstFinder { infcx }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for UnresolvedTypeOrConstFinder<'a, 'tcx> {
|
|
||||||
type BreakTy = (ty::Term<'tcx>, Option<Span>);
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
let t = self.infcx.shallow_resolve(t);
|
|
||||||
if let ty::Infer(infer_ty) = *t.kind() {
|
|
||||||
// Since we called `shallow_resolve` above, this must
|
|
||||||
// be an (as yet...) unresolved inference variable.
|
|
||||||
let ty_var_span = if let ty::TyVar(ty_vid) = infer_ty {
|
|
||||||
let mut inner = self.infcx.inner.borrow_mut();
|
|
||||||
let ty_vars = &inner.type_variables();
|
|
||||||
if let TypeVariableOrigin {
|
|
||||||
kind: TypeVariableOriginKind::TypeParameterDefinition(_, _),
|
|
||||||
span,
|
|
||||||
} = ty_vars.var_origin(ty_vid)
|
|
||||||
{
|
|
||||||
Some(span)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
ControlFlow::Break((t.into(), ty_var_span))
|
|
||||||
} else if !t.has_non_region_infer() {
|
|
||||||
// All const/type variables in inference types must already be resolved,
|
|
||||||
// no need to visit the contents.
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
} else {
|
|
||||||
// Otherwise, keep visiting.
|
|
||||||
t.super_visit_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
let ct = self.infcx.shallow_resolve(ct);
|
|
||||||
if let ty::ConstKind::Infer(i) = ct.kind() {
|
|
||||||
// Since we called `shallow_resolve` above, this must
|
|
||||||
// be an (as yet...) unresolved inference variable.
|
|
||||||
let ct_var_span = if let ty::InferConst::Var(vid) = i {
|
|
||||||
let mut inner = self.infcx.inner.borrow_mut();
|
|
||||||
let ct_vars = &mut inner.const_unification_table();
|
|
||||||
if let ConstVariableOrigin {
|
|
||||||
span,
|
|
||||||
kind: ConstVariableOriginKind::ConstParameterDefinition(_, _),
|
|
||||||
} = ct_vars.probe_value(vid).origin
|
|
||||||
{
|
|
||||||
Some(span)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
ControlFlow::Break((ct.into(), ct_var_span))
|
|
||||||
} else if !ct.has_non_region_infer() {
|
|
||||||
// All const/type variables in inference types must already be resolved,
|
|
||||||
// no need to visit the contents.
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
} else {
|
|
||||||
// Otherwise, keep visiting.
|
|
||||||
ct.super_visit_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// FULL TYPE RESOLUTION
|
// FULL TYPE RESOLUTION
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ pub enum ConstVariableOriginKind {
|
|||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum ConstVariableValue<'tcx> {
|
pub enum ConstVariableValue<'tcx> {
|
||||||
Known { value: ty::Const<'tcx> },
|
Known { value: ty::Const<'tcx> },
|
||||||
Unknown { universe: ty::UniverseIndex },
|
Unknown { origin: ConstVariableOrigin, universe: ty::UniverseIndex },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ConstVariableValue<'tcx> {
|
impl<'tcx> ConstVariableValue<'tcx> {
|
||||||
@ -134,12 +134,6 @@ impl<'tcx> ConstVariableValue<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct ConstVarValue<'tcx> {
|
|
||||||
pub origin: ConstVariableOrigin,
|
|
||||||
pub val: ConstVariableValue<'tcx>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Copy, Clone, Debug)]
|
||||||
pub struct ConstVidKey<'tcx> {
|
pub struct ConstVidKey<'tcx> {
|
||||||
pub vid: ty::ConstVid,
|
pub vid: ty::ConstVid,
|
||||||
@ -153,7 +147,7 @@ impl<'tcx> From<ty::ConstVid> for ConstVidKey<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> UnifyKey for ConstVidKey<'tcx> {
|
impl<'tcx> UnifyKey for ConstVidKey<'tcx> {
|
||||||
type Value = ConstVarValue<'tcx>;
|
type Value = ConstVariableValue<'tcx>;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self) -> u32 {
|
fn index(&self) -> u32 {
|
||||||
self.vid.as_u32()
|
self.vid.as_u32()
|
||||||
@ -167,23 +161,23 @@ impl<'tcx> UnifyKey for ConstVidKey<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
|
impl<'tcx> UnifyValue for ConstVariableValue<'tcx> {
|
||||||
type Error = NoError;
|
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> {
|
||||||
Ok(match (value1.val, value2.val) {
|
match (value1, value2) {
|
||||||
(ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => {
|
(ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => {
|
||||||
bug!("equating two const variables, both of which have known values")
|
bug!("equating two const variables, both of which have known values")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If one side is known, prefer that one.
|
// If one side is known, prefer that one.
|
||||||
(ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => value1,
|
(ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => Ok(value1),
|
||||||
(ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => value2,
|
(ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => Ok(value2),
|
||||||
|
|
||||||
// If both sides are *unknown*, it hardly matters, does it?
|
// If both sides are *unknown*, it hardly matters, does it?
|
||||||
(
|
(
|
||||||
ConstVariableValue::Unknown { universe: universe1 },
|
ConstVariableValue::Unknown { origin, universe: universe1 },
|
||||||
ConstVariableValue::Unknown { universe: universe2 },
|
ConstVariableValue::Unknown { origin: _, universe: universe2 },
|
||||||
) => {
|
) => {
|
||||||
// If we unify two unbound variables, ?T and ?U, then whatever
|
// If we unify two unbound variables, ?T and ?U, then whatever
|
||||||
// value they wind up taking (which must be the same value) must
|
// value they wind up taking (which must be the same value) must
|
||||||
@ -191,12 +185,9 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
|
|||||||
// universe is the minimum of the two universes, because that is
|
// universe is the minimum of the two universes, because that is
|
||||||
// the one which contains the fewest names in scope.
|
// the one which contains the fewest names in scope.
|
||||||
let universe = cmp::min(universe1, universe2);
|
let universe = cmp::min(universe1, universe2);
|
||||||
ConstVarValue {
|
Ok(ConstVariableValue::Unknown { origin, universe })
|
||||||
val: ConstVariableValue::Unknown { universe },
|
|
||||||
origin: value1.origin,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user