use super::lub::Lub;
use super::sub::Sub;
use super::type_variable::TypeVariableValue;
-use super::const_variable::ConstVariableValue;
+use super::unify_key::{ConstVarValue, ConstVariableValue, ConstVariableOrigin};
use crate::hir::def_id::DefId;
use crate::mir::interpret::ConstValue;
use crate::traits::{Obligation, PredicateObligations};
use syntax::ast;
-use syntax_pos::Span;
+use syntax_pos::{Span, DUMMY_SP};
#[derive(Clone)]
pub struct CombineFields<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
) -> RelateResult<'tcx, &'tcx LazyConst<'tcx>> {
self.const_unification_table
.borrow_mut()
- .unify_var_value(vid, ConstVariableValue::Known { value })
+ .unify_var_value(vid, ConstVarValue {
+ origin: ConstVariableOrigin::ConstInference(DUMMY_SP),
+ val: ConstVariableValue::Known { value },
+ })
.map_err(|e| const_unification_error(vid_is_expected, e))?;
Ok(value)
}
..
}) => {
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
- match variable_table.probe(*vid).known() {
+ match variable_table.probe_value(*vid).val.known() {
Some(u) => {
self.relate(&u, &u)
}
+++ /dev/null
-use crate::mir::interpret::ConstValue;
-use syntax::symbol::InternedString;
-use syntax_pos::Span;
-use crate::ty::{self, InferConst};
-
-use std::cmp;
-use std::marker::PhantomData;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::snapshot_vec as sv;
-use rustc_data_structures::unify as ut;
-
-pub struct ConstVariableTable<'tcx> {
- values: sv::SnapshotVec<Delegate<'tcx>>,
-
- relations: ut::UnificationTable<ut::InPlace<ty::ConstVid<'tcx>>>,
-}
-
-/// Reasons to create a const inference variable
-#[derive(Copy, Clone, Debug)]
-pub enum ConstVariableOrigin {
- MiscVariable(Span),
- ConstInference(Span),
- ConstParameterDefinition(Span, InternedString),
- SubstitutionPlaceholder(Span),
-}
-
-pub type ConstVariableMap<'tcx> = FxHashMap<ty::ConstVid<'tcx>, ConstVariableOrigin>;
-
-struct ConstVariableData {
- origin: ConstVariableOrigin,
-}
-
-#[derive(Copy, Clone, Debug)]
-pub enum ConstVariableValue<'tcx> {
- Known { value: &'tcx ty::LazyConst<'tcx> },
- Unknown { universe: ty::UniverseIndex },
-}
-
-impl<'tcx> ConstVariableValue<'tcx> {
- /// If this value is known, returns the const it is known to be.
- /// Otherwise, `None`.
- pub fn known(&self) -> Option<&'tcx ty::LazyConst<'tcx>> {
- match *self {
- ConstVariableValue::Unknown { .. } => None,
- ConstVariableValue::Known { value } => Some(value),
- }
- }
-
- pub fn is_unknown(&self) -> bool {
- match *self {
- ConstVariableValue::Unknown { .. } => true,
- ConstVariableValue::Known { .. } => false,
- }
- }
-}
-
-pub struct Snapshot<'tcx> {
- snapshot: sv::Snapshot,
- relation_snapshot: ut::Snapshot<ut::InPlace<ty::ConstVid<'tcx>>>,
-}
-
-struct Instantiate<'tcx> {
- _vid: ty::ConstVid<'tcx>,
-}
-
-struct Delegate<'tcx> {
- pub phantom: PhantomData<&'tcx ()>,
-}
-
-impl<'tcx> ConstVariableTable<'tcx> {
- pub fn new() -> ConstVariableTable<'tcx> {
- ConstVariableTable {
- values: sv::SnapshotVec::new(),
- relations: ut::UnificationTable::new(),
- }
- }
-
- /// Returns the origin that was given when `vid` was created.
- ///
- /// Note that this function does not return care whether
- /// `vid` has been unified with something else or not.
- pub fn var_origin(&self, vid: ty::ConstVid<'tcx>) -> &ConstVariableOrigin {
- &self.values[vid.index as usize].origin
- }
-
- pub fn unify_var_var(
- &mut self,
- a_id: ty::ConstVid<'tcx>,
- b_id: ty::ConstVid<'tcx>,
- ) -> Result<(), (&'tcx ty::LazyConst<'tcx>, &'tcx ty::LazyConst<'tcx>)> {
- self.relations.unify_var_var(a_id, b_id)
- }
-
- pub fn unify_var_value(
- &mut self,
- a_id: ty::ConstVid<'tcx>,
- b: ConstVariableValue<'tcx>,
- ) -> Result<(), (&'tcx ty::LazyConst<'tcx>, &'tcx ty::LazyConst<'tcx>)> {
- self.relations.unify_var_value(a_id, b)
- }
-
- /// Creates a new const variable.
- ///
- /// - `origin`: indicates *why* the const variable was created.
- /// The code in this module doesn't care, but it can be useful
- /// for improving error messages.
- pub fn new_var(
- &mut self,
- universe: ty::UniverseIndex,
- origin: ConstVariableOrigin,
- ) -> ty::ConstVid<'tcx> {
- let vid = self.relations.new_key(ConstVariableValue::Unknown{ universe });
-
- let index = self.values.push(ConstVariableData {
- origin,
- });
- assert_eq!(vid.index, index as u32);
-
- debug!("new_var(index={:?}, origin={:?}", vid, origin);
-
- vid
- }
-
- /// Retrieves the type to which `vid` has been instantiated, if
- /// any.
- pub fn probe(
- &mut self,
- vid: ty::ConstVid<'tcx>
- ) -> ConstVariableValue<'tcx> {
- self.relations.probe_value(vid)
- }
-
- /// If `t` is a type-inference variable, and it has been
- /// instantiated, then return the with which it was
- /// instantiated. Otherwise, returns `t`.
- pub fn replace_if_possible(
- &mut self,
- c: &'tcx ty::LazyConst<'tcx>
- ) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(InferConst::Var(vid)),
- ..
- }) = c {
- match self.probe(*vid).known() {
- Some(c) => c,
- None => c,
- }
- } else {
- c
- }
- }
-
- /// Creates a snapshot of the type variable state. This snapshot
- /// must later be committed (`commit()`) or rolled back
- /// (`rollback_to()`). Nested snapshots are permitted, but must
- /// be processed in a stack-like fashion.
- pub fn snapshot(&mut self) -> Snapshot<'tcx> {
- Snapshot {
- snapshot: self.values.start_snapshot(),
- relation_snapshot: self.relations.snapshot(),
- }
- }
-
- /// Undoes all changes since the snapshot was created. Any
- /// snapshots created since that point must already have been
- /// committed or rolled back.
- pub fn rollback_to(&mut self, s: Snapshot<'tcx>) {
- debug!("rollback_to{:?}", {
- for action in self.values.actions_since_snapshot(&s.snapshot) {
- if let sv::UndoLog::NewElem(index) = *action {
- debug!("inference variable _#{}t popped", index)
- }
- }
- });
-
- let Snapshot { snapshot, relation_snapshot } = s;
- self.values.rollback_to(snapshot);
- self.relations.rollback_to(relation_snapshot);
- }
-
- /// Commits all changes since the snapshot was created, making
- /// them permanent (unless this snapshot was created within
- /// another snapshot). Any snapshots created since that point
- /// must already have been committed or rolled back.
- pub fn commit(&mut self, s: Snapshot<'tcx>) {
- let Snapshot { snapshot, relation_snapshot } = s;
- self.values.commit(snapshot);
- self.relations.commit(relation_snapshot);
- }
-
- /// Returns a map `{V1 -> V2}`, where the keys `{V1}` are
- /// const-variables created during the snapshot, and the values
- /// `{V2}` are the root variables that they were unified with,
- /// along with their origin.
- pub fn consts_created_since_snapshot(
- &mut self,
- s: &Snapshot<'tcx>
- ) -> ConstVariableMap<'tcx> {
- let actions_since_snapshot = self.values.actions_since_snapshot(&s.snapshot);
-
- actions_since_snapshot
- .iter()
- .filter_map(|action| match action {
- &sv::UndoLog::NewElem(index) => Some(ty::ConstVid {
- index: index as u32,
- phantom: PhantomData,
- }),
- _ => None,
- })
- .map(|vid| {
- let origin = self.values.get(vid.index as usize).origin.clone();
- (vid, origin)
- })
- .collect()
- }
-}
-
-impl<'tcx> ut::UnifyKey for ty::ConstVid<'tcx> {
- type Value = ConstVariableValue<'tcx>;
- fn index(&self) -> u32 { self.index }
- fn from_index(i: u32) -> Self { ty::ConstVid { index: i, phantom: PhantomData } }
- fn tag() -> &'static str { "ConstVid" }
-}
-
-impl<'tcx> ut::UnifyValue for ConstVariableValue<'tcx> {
- type Error = (&'tcx ty::LazyConst<'tcx>, &'tcx ty::LazyConst<'tcx>);
-
- fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
- match (value1, value2) {
- (
- &ConstVariableValue::Known { value: value1 },
- &ConstVariableValue::Known { value: value2 }
- ) => {
- match <&'tcx ty::LazyConst<'tcx>>::unify_values(&value1, &value2) {
- Ok(value) => Ok(ConstVariableValue::Known { value }),
- Err(err) => Err(err),
- }
- }
-
- // If one side is known, prefer that one.
- (&ConstVariableValue::Known { .. }, &ConstVariableValue::Unknown { .. }) => Ok(*value1),
- (&ConstVariableValue::Unknown { .. }, &ConstVariableValue::Known { .. }) => Ok(*value2),
-
- // If both sides are *unknown*, it hardly matters, does it?
- (&ConstVariableValue::Unknown { universe: universe1 },
- &ConstVariableValue::Unknown { universe: universe2 }) => {
- // If we unify two unbound variables, ?T and ?U, then whatever
- // value they wind up taking (which must be the same value) must
- // be nameable by both universes. Therefore, the resulting
- // universe is the minimum of the two universes, because that is
- // the one which contains the fewest names in scope.
- let universe = cmp::min(universe1, universe2);
- Ok(ConstVariableValue::Unknown { universe })
- }
- }
- }
-}
-
-impl<'tcx> ut::EqUnifyValue for &'tcx ty::LazyConst<'tcx> {}
-
-impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
- type Value = ConstVariableData;
- type Undo = Instantiate<'tcx>;
-
- fn reverse(_values: &mut Vec<ConstVariableData>, _action: Instantiate<'tcx>) {
- // We don't actually have to *do* anything to reverse an
- // instantiation; the value for a variable is stored in the
- // `relations` and hence its rollback code will handle
- // it.
- }
-}
use crate::ty::subst::SubstsRef;
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
use crate::mir::interpret::ConstValue;
+use crate::infer::unify_key::replace_if_possible;
/// Ensures `a` is made equal to `b`. Returns `a` on success.
pub struct Equate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
if a == b { return Ok(a); }
let infcx = self.fields.infcx;
- let a = infcx.const_unification_table.borrow_mut().replace_if_possible(a);
- let b = infcx.const_unification_table.borrow_mut().replace_if_possible(b);
+ let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a);
+ let b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b);
let a_is_expected = self.a_is_expected();
if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) {
match (a_eval.val, b_eval.val) {
ConstValue::Infer(ty::InferConst::Var(v)) => {
let opt_ct = self.infcx.const_unification_table
.borrow_mut()
- .probe(*v)
+ .probe_value(*v)
+ .val
.known();
return self.freshen_const(
opt_ct,
val: ConstValue::Infer(ty::InferConst::Var(vid)),
ty,
}) = *ct {
- match self.const_variables.get(&vid) {
- None => {
- // This variable was created before the
- // "fudging". Since we refresh all
- // variables to their binding anyhow, we know
- // that it is unbound, so we can just return
- // it.
- debug_assert!(
- self.infcx.const_unification_table.borrow_mut()
- .probe(vid)
- .is_unknown()
- );
- ct
- }
- Some(&origin) => {
- // This variable was created during the
- // fudging. Recreate it with a fresh variable
- // here.
- self.infcx.next_const_var(ty, origin)
- }
+ if self.const_variables.contains(&vid) {
+ // This variable was created during the
+ // fudging. Recreate it with a fresh variable
+ // here.
+ let origin = self.infcx.const_unification_table.borrow_mut()
+ .probe_value(vid)
+ .origin;
+ self.infcx.next_const_var(ty, origin)
+ } else {
+ ct
}
} else {
ct.super_fold_with(self)
use super::combine::CombineFields;
use super::{HigherRankedType, InferCtxt, PlaceholderMap};
-use crate::infer::{CombinedSnapshot, ConstVariableOrigin};
+use crate::infer::CombinedSnapshot;
use crate::ty::relate::{Relate, RelateResult, TypeRelation};
use crate::ty::{self, Binder, TypeFoldable};
-
-use syntax_pos::DUMMY_SP;
+use crate::mir::interpret::ConstValue;
impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
pub fn higher_ranked_sub<T>(
}))
};
- let fld_c = |_: ty::BoundVar, ty| {
- self.next_const_var_in_universe(
- ty,
- // FIXME(const_generics): do we want a placeholder const?
- ConstVariableOrigin::MiscVariable(DUMMY_SP),
- next_universe,
- )
+ let fld_c = |bound_var: ty::BoundVar, ty| {
+ self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ ty::Const {
+ val: ConstValue::Placeholder(ty::PlaceholderConst {
+ universe: next_universe,
+ name: bound_var,
+ }),
+ ty,
+ }
+ ))
};
let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c);
use crate::hir;
use crate::hir::def_id::DefId;
use crate::infer::canonical::{Canonical, CanonicalVarValues};
+use crate::infer::unify_key::{ConstVarValue, ConstVariableValue};
use crate::middle::free_region::RegionRelations;
use crate::middle::lang_items;
use crate::middle::region;
use syntax_pos::Span;
use self::combine::CombineFields;
-use self::const_variable::ConstVariableOrigin;
use self::lexical_region_resolve::LexicalRegionResolutions;
use self::outlives::env::OutlivesEnvironment;
use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, VerifyBound};
use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
use self::type_variable::TypeVariableOrigin;
-use self::unify_key::ToType;
+use self::unify_key::{ToType, ConstVariableOrigin};
pub mod at;
pub mod canonical;
pub mod resolve;
mod sub;
pub mod type_variable;
-pub mod const_variable;
pub mod unify_key;
#[must_use]
pub type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
/// Map from const parameter variable to the kind of const it represents.
- const_unification_table: RefCell<const_variable::ConstVariableTable<'tcx>>,
+ const_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::ConstVid<'tcx>>>>,
/// Map from integral variable to the kind of integer it represents.
int_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::IntVid>>>,
in_progress_tables,
projection_cache: Default::default(),
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
- const_unification_table: RefCell::new(const_variable::ConstVariableTable::new()),
+ const_unification_table: RefCell::new(ut::UnificationTable::new()),
int_unification_table: RefCell::new(ut::UnificationTable::new()),
float_unification_table: RefCell::new(ut::UnificationTable::new()),
region_constraints: RefCell::new(Some(RegionConstraintCollector::new())),
pub struct CombinedSnapshot<'a, 'tcx: 'a> {
projection_cache_snapshot: traits::ProjectionCacheSnapshot,
type_snapshot: type_variable::Snapshot<'tcx>,
- const_snapshot: const_variable::Snapshot<'tcx>,
+ const_snapshot: ut::Snapshot<ut::InPlace<ty::ConstVid<'tcx>>>,
int_snapshot: ut::Snapshot<ut::InPlace<ty::IntVid>>,
float_snapshot: ut::Snapshot<ut::InPlace<ty::FloatVid>>,
region_constraints_snapshot: RegionSnapshot,
) -> &'tcx ty::LazyConst<'tcx> {
let vid = self.const_unification_table
.borrow_mut()
- .new_var(universe, origin);
+ .new_key(ConstVarValue {
+ origin,
+ val: ConstVariableValue::Unknown { universe },
+ });
self.tcx.mk_const_var(vid, ty)
}
pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx> {
self.const_unification_table
.borrow_mut()
- .new_var(self.universe(), origin)
+ .new_key(ConstVarValue {
+ origin,
+ val: ConstVariableValue::Unknown { universe: self.universe() },
+ })
}
fn next_int_var_id(&self) -> IntVid {
self.tcx.mk_ty_var(ty_var_id).into()
}
GenericParamDefKind::Const { .. } => {
+ let origin = ConstVariableOrigin::ConstParameterDefinition(span, param.name);
let const_var_id =
self.const_unification_table
.borrow_mut()
- .new_var(
- self.universe(),
- ConstVariableOrigin::ConstParameterDefinition(span, param.name),
- );
+ .new_key(ConstVarValue {
+ origin,
+ val: ConstVariableValue::Unknown { universe: self.universe() },
+ });
self.tcx.mk_const_var(const_var_id, self.tcx.type_of(param.def_id)).into()
}
}
&self,
vid: ty::ConstVid<'tcx>
) -> Result<&'tcx ty::LazyConst<'tcx>, ty::UniverseIndex> {
- use self::const_variable::ConstVariableValue;
+ use self::unify_key::ConstVariableValue;
- match self.const_unification_table.borrow_mut().probe(vid) {
+ match self.const_unification_table.borrow_mut().probe_value(vid).val {
ConstVariableValue::Known { value } => Ok(value),
ConstVariableValue::Unknown { universe } => Err(universe),
}
}) = ct {
self.const_unification_table
.borrow_mut()
- .probe(*v)
+ .probe_value(*v)
+ .val
.known()
.map(|c| self.resolve_const_var(c))
.unwrap_or(ct)
}) => {
self.const_unification_table
.borrow_mut()
- .probe(*vid)
+ .probe_value(*vid)
+ .val
.known()
.map(|c| self.shallow_resolve_const(c))
.unwrap_or(ct)
use crate::ty::TyVar;
use crate::ty::fold::TypeFoldable;
use crate::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
+use crate::infer::unify_key::replace_if_possible;
use crate::mir::interpret::ConstValue;
use std::mem;
if a == b { return Ok(a); }
let infcx = self.fields.infcx;
- let a = infcx.const_unification_table.borrow_mut().replace_if_possible(a);
- let b = infcx.const_unification_table.borrow_mut().replace_if_possible(b);
+ let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a);
+ let b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b);
// Consts can only be equal or unequal to each other: there's no subtyping
// relation, so we're just going to perform equating here instead.
-use crate::ty::{self, FloatVarValue, IntVarValue, Ty, TyCtxt};
-use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue};
+use crate::ty::{self, FloatVarValue, IntVarValue, Ty, TyCtxt, InferConst};
+use crate::mir::interpret::ConstValue;
+use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue, UnificationTable};
+use rustc_data_structures::unify::InPlace;
+use syntax_pos::{Span, DUMMY_SP};
+use syntax::symbol::InternedString;
+
+use std::cmp;
+use std::marker::PhantomData;
+use std::cell::RefMut;
pub trait ToType {
fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx>;
tcx.mk_mach_float(self.0)
}
}
+
+// Generic consts.
+
+/// Reasons to create a const inference variable
+#[derive(Copy, Clone, Debug)]
+pub enum ConstVariableOrigin {
+ MiscVariable(Span),
+ ConstInference(Span),
+ ConstParameterDefinition(Span, InternedString),
+ SubstitutionPlaceholder(Span),
+}
+
+#[derive(Copy, Clone, Debug)]
+pub enum ConstVariableValue<'tcx> {
+ Known { value: &'tcx ty::LazyConst<'tcx> },
+ Unknown { universe: ty::UniverseIndex },
+}
+
+impl<'tcx> ConstVariableValue<'tcx> {
+ /// If this value is known, returns the const it is known to be.
+ /// Otherwise, `None`.
+ pub fn known(&self) -> Option<&'tcx ty::LazyConst<'tcx>> {
+ match *self {
+ ConstVariableValue::Unknown { .. } => None,
+ ConstVariableValue::Known { value } => Some(value),
+ }
+ }
+
+ pub fn is_unknown(&self) -> bool {
+ match *self {
+ ConstVariableValue::Unknown { .. } => true,
+ ConstVariableValue::Known { .. } => false,
+ }
+ }
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct ConstVarValue<'tcx> {
+ pub origin: ConstVariableOrigin,
+ pub val: ConstVariableValue<'tcx>,
+}
+
+impl<'tcx> UnifyKey for ty::ConstVid<'tcx> {
+ type Value = ConstVarValue<'tcx>;
+ fn index(&self) -> u32 { self.index }
+ fn from_index(i: u32) -> Self { ty::ConstVid { index: i, phantom: PhantomData } }
+ fn tag() -> &'static str { "ConstVid" }
+}
+
+impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
+ type Error = (&'tcx ty::LazyConst<'tcx>, &'tcx ty::LazyConst<'tcx>);
+
+ fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
+ let val = match (value1.val, value2.val) {
+ (
+ ConstVariableValue::Known { value: value1 },
+ ConstVariableValue::Known { value: value2 }
+ ) => {
+ match <&'tcx ty::LazyConst<'tcx>>::unify_values(&value1, &value2) {
+ Ok(value) => Ok(ConstVariableValue::Known { value }),
+ Err(err) => Err(err),
+ }
+ }
+
+ // If one side is known, prefer that one.
+ (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => {
+ Ok(value1.val)
+ }
+ (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => {
+ Ok(value2.val)
+ }
+
+ // If both sides are *unknown*, it hardly matters, does it?
+ (ConstVariableValue::Unknown { universe: universe1 },
+ ConstVariableValue::Unknown { universe: universe2 }) => {
+ // If we unify two unbound variables, ?T and ?U, then whatever
+ // value they wind up taking (which must be the same value) must
+ // be nameable by both universes. Therefore, the resulting
+ // universe is the minimum of the two universes, because that is
+ // the one which contains the fewest names in scope.
+ let universe = cmp::min(universe1, universe2);
+ Ok(ConstVariableValue::Unknown { universe })
+ }
+ }?;
+
+ Ok(ConstVarValue {
+ origin: ConstVariableOrigin::ConstInference(DUMMY_SP),
+ val,
+ })
+ }
+}
+
+impl<'tcx> EqUnifyValue for &'tcx ty::LazyConst<'tcx> {}
+
+pub fn replace_if_possible(
+ mut table: RefMut<'_, UnificationTable<InPlace<ty::ConstVid<'tcx>>>>,
+ c: &'tcx ty::LazyConst<'tcx>
+) -> &'tcx ty::LazyConst<'tcx> {
+ if let ty::LazyConst::Evaluated(ty::Const {
+ val: ConstValue::Infer(InferConst::Var(vid)),
+ ..
+ }) = c {
+ match table.probe_value(*vid).val.known() {
+ Some(c) => c,
+ None => c,
+ }
+ } else {
+ c
+ }
+}