Skip to content

Commit

Permalink
const generics check subst in generalize
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Jun 23, 2020
1 parent 1557fb0 commit 710192d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
25 changes: 22 additions & 3 deletions src/librustc_infer/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
for_vid: ty::TyVid,
dir: RelationDir,
) -> RelateResult<'tcx, Generalization<'tcx>> {
debug!("generalize(ty={:?}, for_vid={:?}, dir={:?}", ty, for_vid, dir);
debug!("generalize(ty={:?}, for_vid={:?}, dir={:?})", ty, for_vid, dir);
// Determine the ambient variance within which `ty` appears.
// The surrounding equation is:
//
Expand Down Expand Up @@ -649,13 +649,17 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==

debug!("generalize: consts c={:?}", c);
match c.val {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
let mut inner = self.infcx.inner.borrow_mut();
let variable_table = &mut inner.const_unification_table();
let var_value = variable_table.probe_value(vid);
match var_value.val {
ConstVariableValue::Known { value: u } => self.relate(&u, &u),
ConstVariableValue::Known { value: u } => {
drop(inner);
self.relate(&u, &u)
}
ConstVariableValue::Unknown { universe } => {
if self.for_universe.can_name(universe) {
Ok(c)
Expand All @@ -669,7 +673,22 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
}
}
}
ty::ConstKind::Unevaluated(..) if self.tcx().lazy_normalization() => Ok(c),
ty::ConstKind::Unevaluated(did, substs, promoted)
if self.tcx().lazy_normalization() =>
{
// We have to generalize inference variables used in the generic substitutions,
// as unevaluated consts may otherwise contain invalid inference variables.
let new_substs =
self.relate_with_variance(ty::Variance::Invariant, &substs, &substs)?;
if new_substs != substs {
Ok(self.tcx().mk_const(ty::Const {
ty: c.ty,
val: ty::ConstKind::Unevaluated(did, new_substs, promoted),
}))
} else {
Ok(c)
}
}
_ => relate::super_relate_consts(self, c, c),
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_middle/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,7 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {

impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
debug!("Ty::super_fold_with({:?})", self);
let kind = match self.kind {
ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)),
ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
Expand Down Expand Up @@ -1040,6 +1041,7 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T>

impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
debug!("Const::super_fold_with({:?})", self);
let ty = self.ty.fold_with(folder);
let val = self.val.fold_with(folder);
if ty != self.ty || val != self.val {
Expand Down

0 comments on commit 710192d

Please sign in to comment.