Fix rebase from LazyConst removal

This commit is contained in:
varkor 2019-03-18 20:55:19 +00:00
parent c888af52be
commit fc16b0a147
24 changed files with 342 additions and 394 deletions

View File

@ -15,6 +15,7 @@ use std::sync::atomic::Ordering;
use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::fold::{TypeFoldable, TypeFolder};
use crate::ty::subst::Kind; use crate::ty::subst::Kind;
use crate::ty::{self, BoundVar, InferConst, Lift, List, Ty, TyCtxt, TypeFlags}; use crate::ty::{self, BoundVar, InferConst, Lift, List, Ty, TyCtxt, TypeFlags};
use crate::ty::flags::FlagComputation;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
@ -434,59 +435,58 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
} }
} }
fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::LazyConst::Evaluated(ct) = c { match ct.val {
match ct.val { ConstValue::Infer(InferConst::Var(vid)) => {
ConstValue::Infer(InferConst::Var(vid)) => { debug!("canonical: const var found with vid {:?}", vid);
debug!("canonical: const var found with vid {:?}", vid); match self.infcx.unwrap().probe_const_var(vid) {
match self.infcx.unwrap().probe_const_var(vid) { Ok(c) => {
Ok(c) => { debug!("(resolved to {:?})", c);
debug!("(resolved to {:?})", c); return self.fold_const(c);
return self.fold_const(c); }
}
// `ConstVar(vid)` is unresolved, track its universe index in the // `ConstVar(vid)` is unresolved, track its universe index in the
// canonicalized result // canonicalized result
Err(mut ui) => { Err(mut ui) => {
if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk { if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
// FIXME: perf problem described in #55921. // FIXME: perf problem described in #55921.
ui = ty::UniverseIndex::ROOT; ui = ty::UniverseIndex::ROOT;
}
return self.canonicalize_const_var(
CanonicalVarInfo {
kind: CanonicalVarKind::Const(ui),
},
c,
);
} }
return self.canonicalize_const_var(
CanonicalVarInfo {
kind: CanonicalVarKind::Const(ui),
},
ct,
);
} }
} }
ConstValue::Infer(InferConst::Fresh(_)) => {
bug!("encountered a fresh const during canonicalization")
}
ConstValue::Infer(InferConst::Canonical(debruijn, _)) => {
if debruijn >= self.binder_index {
bug!("escaping bound type during canonicalization")
} else {
return c;
}
}
ConstValue::Placeholder(placeholder) => {
return self.canonicalize_const_var(
CanonicalVarInfo {
kind: CanonicalVarKind::PlaceholderConst(placeholder),
},
c,
);
}
_ => {}
} }
ConstValue::Infer(InferConst::Fresh(_)) => {
bug!("encountered a fresh const during canonicalization")
}
ConstValue::Infer(InferConst::Canonical(debruijn, _)) => {
if debruijn >= self.binder_index {
bug!("escaping bound type during canonicalization")
} else {
return ct;
}
}
ConstValue::Placeholder(placeholder) => {
return self.canonicalize_const_var(
CanonicalVarInfo {
kind: CanonicalVarKind::PlaceholderConst(placeholder),
},
ct,
);
}
_ => {}
} }
if c.type_flags().intersects(self.needs_canonical_flags) { let flags = FlagComputation::for_const(ct);
c.super_fold_with(self) if flags.intersects(self.needs_canonical_flags) {
ct.super_fold_with(self)
} else { } else {
c ct
} }
} }
} }
@ -700,25 +700,19 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
fn canonicalize_const_var( fn canonicalize_const_var(
&mut self, &mut self,
info: CanonicalVarInfo, info: CanonicalVarInfo,
const_var: &'tcx ty::LazyConst<'tcx> const_var: &'tcx ty::Const<'tcx>
) -> &'tcx ty::LazyConst<'tcx> { ) -> &'tcx ty::Const<'tcx> {
let infcx = self.infcx.expect("encountered const-var without infcx"); let infcx = self.infcx.expect("encountered const-var without infcx");
let bound_to = infcx.resolve_const_var(const_var); let bound_to = infcx.resolve_const_var(const_var);
if bound_to != const_var { if bound_to != const_var {
self.fold_const(bound_to) self.fold_const(bound_to)
} else { } else {
let ty = match const_var {
ty::LazyConst::Unevaluated(def_id, _) => {
self.tcx.type_of(*def_id)
}
ty::LazyConst::Evaluated(ty::Const { ty, .. }) => ty,
};
let var = self.canonical_var(info, const_var.into()); let var = self.canonical_var(info, const_var.into());
self.tcx().mk_lazy_const( self.tcx().mk_const(
ty::LazyConst::Evaluated(ty::Const { ty::Const {
val: ConstValue::Infer(InferConst::Canonical(self.binder_index, var.into())), val: ConstValue::Infer(InferConst::Canonical(self.binder_index, var.into())),
ty, ty: const_var.ty,
}) }
) )
} }
} }

View File

@ -419,12 +419,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
universe: universe_mapped, universe: universe_mapped,
name, name,
}; };
self.tcx.mk_lazy_const(ty::LazyConst::Evaluated( self.tcx.mk_const(
ty::Const { ty::Const {
val: ConstValue::Placeholder(placeholder_mapped), val: ConstValue::Placeholder(placeholder_mapped),
ty: self.tcx.types.err, // FIXME(const_generics) ty: self.tcx.types.err, // FIXME(const_generics)
} }
)).into() ).into()
} }
} }
} }
@ -482,18 +482,12 @@ impl<'tcx> CanonicalVarValues<'tcx> {
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i)) ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))
).into(), ).into(),
UnpackedKind::Const(ct) => { UnpackedKind::Const(ct) => {
let ty = match ct { tcx.mk_const(ty::Const {
ty::LazyConst::Unevaluated(def_id, _) => { ty: ct.ty,
tcx.type_of(*def_id)
}
ty::LazyConst::Evaluated(ty::Const { ty, .. }) => ty,
};
tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const {
ty: ty,
val: ConstValue::Infer( val: ConstValue::Infer(
InferConst::Canonical(ty::INNERMOST, ty::BoundVar::from_u32(i)) InferConst::Canonical(ty::INNERMOST, ty::BoundVar::from_u32(i))
), ),
})).into() }).into()
} }
}) })
.collect() .collect()

View File

@ -481,10 +481,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
} }
} }
UnpackedKind::Const(result_value) => { UnpackedKind::Const(result_value) => {
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const {
val: ConstValue::Infer(InferConst::Canonical(debrujin, b)), val: ConstValue::Infer(InferConst::Canonical(debrujin, b)),
.. ..
}) = result_value { } = result_value {
// ...in which case we would set `canonical_vars[0]` to `Some(const X)`. // ...in which case we would set `canonical_vars[0]` to `Some(const X)`.
// We only allow a `ty::INNERMOST` index in substitutions. // We only allow a `ty::INNERMOST` index in substitutions.

View File

@ -33,7 +33,7 @@ use super::unify_key::{ConstVarValue, ConstVariableValue, ConstVariableOrigin};
use crate::hir::def_id::DefId; use crate::hir::def_id::DefId;
use crate::mir::interpret::ConstValue; use crate::mir::interpret::ConstValue;
use crate::ty::{IntType, UintType}; use crate::ty::{IntType, UintType};
use crate::ty::{self, Ty, TyCtxt, InferConst, LazyConst}; use crate::ty::{self, Ty, TyCtxt, InferConst};
use crate::ty::error::TypeError; use crate::ty::error::TypeError;
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
use crate::ty::subst::SubstsRef; use crate::ty::subst::SubstsRef;
@ -118,41 +118,39 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
pub fn super_combine_consts<R>( pub fn super_combine_consts<R>(
&self, &self,
relation: &mut R, relation: &mut R,
a: &'tcx LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx LazyConst<'tcx>, b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx LazyConst<'tcx>> ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
where where
R: TypeRelation<'infcx, 'gcx, 'tcx>, R: TypeRelation<'infcx, 'gcx, 'tcx>,
{ {
let a_is_expected = relation.a_is_expected(); let a_is_expected = relation.a_is_expected();
if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) { match (a.val, b.val) {
match (a_eval.val, b_eval.val) { (ConstValue::Infer(InferConst::Var(a_vid)),
(ConstValue::Infer(InferConst::Var(a_vid)), ConstValue::Infer(InferConst::Var(b_vid))) => {
ConstValue::Infer(InferConst::Var(b_vid))) => { self.const_unification_table
self.const_unification_table .borrow_mut()
.borrow_mut() .unify_var_var(a_vid, b_vid)
.unify_var_var(a_vid, b_vid) .map_err(|e| const_unification_error(a_is_expected, e))?;
.map_err(|e| const_unification_error(a_is_expected, e))?; return Ok(a);
return Ok(a);
}
// All other cases of inference with other variables are errors.
(ConstValue::Infer(InferConst::Var(_)), ConstValue::Infer(_)) |
(ConstValue::Infer(_), ConstValue::Infer(InferConst::Var(_))) => {
bug!("tried to combine ConstValue::Infer/ConstValue::Infer(InferConst::Var)")
}
(ConstValue::Infer(InferConst::Var(vid)), _) => {
return self.unify_const_variable(a_is_expected, vid, b);
}
(_, ConstValue::Infer(InferConst::Var(vid))) => {
return self.unify_const_variable(!a_is_expected, vid, a);
}
_ => {}
} }
// All other cases of inference with other variables are errors.
(ConstValue::Infer(InferConst::Var(_)), ConstValue::Infer(_)) |
(ConstValue::Infer(_), ConstValue::Infer(InferConst::Var(_))) => {
bug!("tried to combine ConstValue::Infer/ConstValue::Infer(InferConst::Var)")
}
(ConstValue::Infer(InferConst::Var(vid)), _) => {
return self.unify_const_variable(a_is_expected, vid, b);
}
(_, ConstValue::Infer(InferConst::Var(vid))) => {
return self.unify_const_variable(!a_is_expected, vid, a);
}
_ => {}
} }
ty::relate::super_relate_consts(relation, a, b) ty::relate::super_relate_consts(relation, a, b)
@ -162,8 +160,8 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
&self, &self,
vid_is_expected: bool, vid_is_expected: bool,
vid: ty::ConstVid<'tcx>, vid: ty::ConstVid<'tcx>,
value: &'tcx LazyConst<'tcx>, value: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
self.const_unification_table self.const_unification_table
.borrow_mut() .borrow_mut()
.unify_var_value(vid, ConstVarValue { .unify_var_value(vid, ConstVarValue {
@ -582,16 +580,13 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
fn consts( fn consts(
&mut self, &mut self,
c: &'tcx ty::LazyConst<'tcx>, c: &'tcx ty::Const<'tcx>,
c2: &'tcx ty::LazyConst<'tcx> c2: &'tcx ty::Const<'tcx>
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be == assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
match c { match c {
LazyConst::Evaluated(ty::Const { ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
val: ConstValue::Infer(InferConst::Var(vid)),
..
}) => {
let mut variable_table = self.infcx.const_unification_table.borrow_mut(); let mut variable_table = self.infcx.const_unification_table.borrow_mut();
match variable_table.probe_value(*vid).val.known() { match variable_table.probe_value(*vid).val.known() {
Some(u) => { Some(u) => {
@ -628,7 +623,7 @@ impl<'tcx, T:Clone + PartialEq> RelateResultCompare<'tcx, T> for RelateResult<'t
pub fn const_unification_error<'tcx>( pub fn const_unification_error<'tcx>(
a_is_expected: bool, a_is_expected: bool,
(a, b): (&'tcx LazyConst<'tcx>, &'tcx LazyConst<'tcx>), (a, b): (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>),
) -> TypeError<'tcx> { ) -> TypeError<'tcx> {
TypeError::ConstMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b)) TypeError::ConstMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b))
} }

View File

@ -104,9 +104,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::LazyConst<'tcx>, b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b); debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b { return Ok(a); } if a == b { return Ok(a); }
@ -114,29 +114,28 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a); 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 b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b);
let a_is_expected = self.a_is_expected(); 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(InferConst::Var(a_vid)),
ConstValue::Infer(InferConst::Var(b_vid))) => {
infcx.const_unification_table
.borrow_mut()
.unify_var_var(a_vid, b_vid)
.map_err(|e| const_unification_error(a_is_expected, e))?;
return Ok(a);
}
(ConstValue::Infer(InferConst::Var(a_id)), _) => { match (a.val, b.val) {
self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?; (ConstValue::Infer(InferConst::Var(a_vid)),
return Ok(a); ConstValue::Infer(InferConst::Var(b_vid))) => {
} infcx.const_unification_table
.borrow_mut()
(_, ConstValue::Infer(InferConst::Var(b_id))) => { .unify_var_var(a_vid, b_vid)
self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?; .map_err(|e| const_unification_error(a_is_expected, e))?;
return Ok(a); return Ok(a);
}
_ => {}
} }
(ConstValue::Infer(InferConst::Var(a_id)), _) => {
self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
return Ok(a);
}
(_, ConstValue::Infer(InferConst::Var(b_id))) => {
self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
return Ok(a);
}
_ => {}
} }
self.fields.infcx.super_combine_consts(self, a, b)?; self.fields.infcx.super_combine_consts(self, a, b)?;

View File

@ -46,7 +46,7 @@ pub struct TypeFreshener<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
ty_freshen_count: u32, ty_freshen_count: u32,
const_freshen_count: u32, const_freshen_count: u32,
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>, ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::LazyConst<'tcx>>, const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::Const<'tcx>>,
} }
impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
@ -88,11 +88,11 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
fn freshen_const<F>( fn freshen_const<F>(
&mut self, &mut self,
opt_ct: Option<&'tcx ty::LazyConst<'tcx>>, opt_ct: Option<&'tcx ty::Const<'tcx>>,
key: ty::InferConst<'tcx>, key: ty::InferConst<'tcx>,
freshener: F, freshener: F,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> &'tcx ty::LazyConst<'tcx> ) -> &'tcx ty::Const<'tcx>
where where
F: FnOnce(u32) -> ty::InferConst<'tcx>, F: FnOnce(u32) -> ty::InferConst<'tcx>,
{ {
@ -226,44 +226,43 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
} }
} }
fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::LazyConst::Evaluated(ty::Const{ val, ty }) = ct { match ct.val {
match val { ConstValue::Infer(ty::InferConst::Var(v)) => {
ConstValue::Infer(ty::InferConst::Var(v)) => { let opt_ct = self.infcx.const_unification_table
let opt_ct = self.infcx.const_unification_table .borrow_mut()
.borrow_mut() .probe_value(v)
.probe_value(*v) .val
.val .known();
.known(); return self.freshen_const(
return self.freshen_const( opt_ct,
opt_ct, ty::InferConst::Var(v),
ty::InferConst::Var(*v), ty::InferConst::Fresh,
ty::InferConst::Fresh, ct.ty,
ty, );
}
ConstValue::Infer(ty::InferConst::Fresh(i)) => {
if i >= self.const_freshen_count {
bug!(
"Encountered a freshend const with id {} \
but our counter is only at {}",
i,
self.const_freshen_count,
); );
} }
ConstValue::Infer(ty::InferConst::Fresh(i)) => { return ct;
if *i >= self.const_freshen_count {
bug!(
"Encountered a freshend const with id {} \
but our counter is only at {}",
i,
self.const_freshen_count,
);
}
return ct;
}
ConstValue::Infer(ty::InferConst::Canonical(..)) |
ConstValue::Placeholder(_) => {
bug!("unexpected const {:?}", ct)
}
ConstValue::Param(_) |
ConstValue::Scalar(_) |
ConstValue::Slice(..) |
ConstValue::ByRef(..) => {}
} }
ConstValue::Infer(ty::InferConst::Canonical(..)) |
ConstValue::Placeholder(_) => {
bug!("unexpected const {:?}", ct)
}
ConstValue::Param(_) |
ConstValue::Scalar(_) |
ConstValue::Slice(..) |
ConstValue::ByRef(..) |
ConstValue::Unevaluated(..) => {}
} }
ct.super_fold_with(self) ct.super_fold_with(self)

View File

@ -176,11 +176,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for InferenceFudger<'a, 'gcx, 'tcx>
r r
} }
fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const { val: ConstValue::Infer(ty::InferConst::Var(vid)), ty } = *ct {
val: ConstValue::Infer(ty::InferConst::Var(vid)),
ty,
}) = *ct {
if self.const_variables.contains(&vid) { if self.const_variables.contains(&vid) {
// This variable was created during the // This variable was created during the
// fudging. Recreate it with a fresh variable // fudging. Recreate it with a fresh variable

View File

@ -62,9 +62,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::LazyConst<'tcx>, b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b); debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b { if a == b {
return Ok(a); return Ok(a);

View File

@ -101,7 +101,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}; };
let fld_c = |bound_var: ty::BoundVar, ty| { let fld_c = |bound_var: ty::BoundVar, ty| {
self.tcx.mk_lazy_const(ty::LazyConst::Evaluated( self.tcx.mk_const(
ty::Const { ty::Const {
val: ConstValue::Placeholder(ty::PlaceholderConst { val: ConstValue::Placeholder(ty::PlaceholderConst {
universe: next_universe, universe: next_universe,
@ -109,7 +109,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}), }),
ty, ty,
} }
)) )
}; };
let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c); let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c);

View File

@ -62,9 +62,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::LazyConst<'tcx>, b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b); debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b { if a == b {
return Ok(a); return Ok(a);

View File

@ -1004,7 +1004,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
&self, &self,
ty: Ty<'tcx>, ty: Ty<'tcx>,
origin: ConstVariableOrigin origin: ConstVariableOrigin
) -> &'tcx ty::LazyConst<'tcx> { ) -> &'tcx ty::Const<'tcx> {
self.tcx.mk_const_var(self.next_const_var_id(origin), ty) self.tcx.mk_const_var(self.next_const_var_id(origin), ty)
} }
@ -1013,7 +1013,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
ty: Ty<'tcx>, ty: Ty<'tcx>,
origin: ConstVariableOrigin, origin: ConstVariableOrigin,
universe: ty::UniverseIndex, universe: ty::UniverseIndex,
) -> &'tcx ty::LazyConst<'tcx> { ) -> &'tcx ty::Const<'tcx> {
let vid = self.const_unification_table let vid = self.const_unification_table
.borrow_mut() .borrow_mut()
.new_key(ConstVarValue { .new_key(ConstVarValue {
@ -1367,7 +1367,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn probe_const_var( pub fn probe_const_var(
&self, &self,
vid: ty::ConstVid<'tcx> vid: ty::ConstVid<'tcx>
) -> Result<&'tcx ty::LazyConst<'tcx>, ty::UniverseIndex> { ) -> Result<&'tcx ty::Const<'tcx>, ty::UniverseIndex> {
use self::unify_key::ConstVariableValue; use self::unify_key::ConstVariableValue;
match self.const_unification_table.borrow_mut().probe_value(vid).val { match self.const_unification_table.borrow_mut().probe_value(vid).val {
@ -1378,12 +1378,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn resolve_const_var( pub fn resolve_const_var(
&self, &self,
ct: &'tcx ty::LazyConst<'tcx> ct: &'tcx ty::Const<'tcx>
) -> &'tcx ty::LazyConst<'tcx> { ) -> &'tcx ty::Const<'tcx> {
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const { val: ConstValue::Infer(InferConst::Var(v)), .. } = ct {
val: ConstValue::Infer(InferConst::Var(v)),
..
}) = ct {
self.const_unification_table self.const_unification_table
.borrow_mut() .borrow_mut()
.probe_value(*v) .probe_value(*v)
@ -1398,13 +1395,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn shallow_resolve_const( pub fn shallow_resolve_const(
&self, &self,
ct: &'tcx ty::LazyConst<'tcx> ct: &'tcx ty::Const<'tcx>
) -> &'tcx ty::LazyConst<'tcx> { ) -> &'tcx ty::Const<'tcx> {
match ct { match ct {
ty::LazyConst::Evaluated(ty::Const { ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
val: ConstValue::Infer(InferConst::Var(vid)),
..
}) => {
self.const_unification_table self.const_unification_table
.borrow_mut() .borrow_mut()
.probe_value(*vid) .probe_value(*vid)

View File

@ -610,13 +610,10 @@ where
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::LazyConst<'tcx>, b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const { val: ConstValue::Infer(InferConst::Canonical(_, _)), .. } = a {
val: ConstValue::Infer(InferConst::Canonical(_, _)),
..
}) = a {
// FIXME(const_generics): I'm unsure how this branch should actually be handled, // FIXME(const_generics): I'm unsure how this branch should actually be handled,
// so this is probably not correct. // so this is probably not correct.
self.infcx.super_combine_consts(self, a, b) self.infcx.super_combine_consts(self, a, b)
@ -983,15 +980,12 @@ where
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
_: &'tcx ty::LazyConst<'tcx>, _: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("TypeGeneralizer::consts(a={:?})", a); debug!("TypeGeneralizer::consts(a={:?})", a);
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const { val: ConstValue::Infer(InferConst::Canonical(_, _)), .. } = a {
val: ConstValue::Infer(InferConst::Canonical(_, _)),
..
}) = a {
bug!( bug!(
"unexpected inference variable encountered in NLL generalization: {:?}", "unexpected inference variable encountered in NLL generalization: {:?}",
a a

View File

@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
} }
} }
fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if !ct.needs_infer() { if !ct.needs_infer() {
ct // micro-optimize -- if there is nothing in this const that this fold affects... ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else { } else {
@ -210,25 +210,20 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
} }
} }
fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if !c.needs_infer() && !ty::keep_local(&c) { if !c.needs_infer() && !ty::keep_local(&c) {
c // micro-optimize -- if there is nothing in this const that this fold affects... c // micro-optimize -- if there is nothing in this const that this fold affects...
// ^ we need to have the `keep_local` check to un-default // ^ we need to have the `keep_local` check to un-default
// defaulted tuples. // defaulted tuples.
} else { } else {
let c = self.infcx.shallow_resolve_const(c); let c = self.infcx.shallow_resolve_const(c);
match c { match c.val {
ty::LazyConst::Evaluated(ty::Const { val, .. }) => { ConstValue::Infer(InferConst::Var(vid)) => {
match val { self.err = Some(FixupError::UnresolvedConst(vid));
ConstValue::Infer(InferConst::Var(vid)) => { return self.tcx().types.ct_err;
self.err = Some(FixupError::UnresolvedConst(*vid)); }
return self.tcx().types.ct_err; ConstValue::Infer(InferConst::Fresh(_)) => {
} bug!("Unexpected const in full const resolver: {:?}", c);
ConstValue::Infer(InferConst::Fresh(_)) => {
bug!("Unexpected const in full const resolver: {:?}", c);
}
_ => {}
}
} }
_ => {} _ => {}
} }

View File

@ -137,9 +137,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::LazyConst<'tcx>, b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b); debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b { return Ok(a); } if a == b { return Ok(a); }
@ -150,29 +150,27 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
// Consts can only be equal or unequal to each other: there's no subtyping // 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. // relation, so we're just going to perform equating here instead.
let a_is_expected = self.a_is_expected(); let a_is_expected = self.a_is_expected();
if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) { match (a.val, b.val) {
match (a_eval.val, b_eval.val) { (ConstValue::Infer(InferConst::Var(a_vid)),
(ConstValue::Infer(InferConst::Var(a_vid)), ConstValue::Infer(InferConst::Var(b_vid))) => {
ConstValue::Infer(InferConst::Var(b_vid))) => { infcx.const_unification_table
infcx.const_unification_table .borrow_mut()
.borrow_mut() .unify_var_var(a_vid, b_vid)
.unify_var_var(a_vid, b_vid) .map_err(|e| const_unification_error(a_is_expected, e))?;
.map_err(|e| const_unification_error(a_is_expected, e))?; return Ok(a);
return Ok(a);
}
(ConstValue::Infer(InferConst::Var(a_id)), _) => {
self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
return Ok(a);
}
(_, ConstValue::Infer(InferConst::Var(b_id))) => {
self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
return Ok(a);
}
_ => {}
} }
(ConstValue::Infer(InferConst::Var(a_id)), _) => {
self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
return Ok(a);
}
(_, ConstValue::Infer(InferConst::Var(b_id))) => {
self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
return Ok(a);
}
_ => {}
} }
self.fields.infcx.super_combine_consts(self, a, b)?; self.fields.infcx.super_combine_consts(self, a, b)?;

View File

@ -90,14 +90,14 @@ pub enum ConstVariableOrigin {
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum ConstVariableValue<'tcx> { pub enum ConstVariableValue<'tcx> {
Known { value: &'tcx ty::LazyConst<'tcx> }, Known { value: &'tcx ty::Const<'tcx> },
Unknown { universe: ty::UniverseIndex }, Unknown { universe: ty::UniverseIndex },
} }
impl<'tcx> ConstVariableValue<'tcx> { impl<'tcx> ConstVariableValue<'tcx> {
/// If this value is known, returns the const it is known to be. /// If this value is known, returns the const it is known to be.
/// Otherwise, `None`. /// Otherwise, `None`.
pub fn known(&self) -> Option<&'tcx ty::LazyConst<'tcx>> { pub fn known(&self) -> Option<&'tcx ty::Const<'tcx>> {
match *self { match *self {
ConstVariableValue::Unknown { .. } => None, ConstVariableValue::Unknown { .. } => None,
ConstVariableValue::Known { value } => Some(value), ConstVariableValue::Known { value } => Some(value),
@ -126,7 +126,7 @@ impl<'tcx> UnifyKey for ty::ConstVid<'tcx> {
} }
impl<'tcx> UnifyValue for ConstVarValue<'tcx> { impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
type Error = (&'tcx ty::LazyConst<'tcx>, &'tcx ty::LazyConst<'tcx>); type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> { fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
let val = match (value1.val, value2.val) { let val = match (value1.val, value2.val) {
@ -134,7 +134,7 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
ConstVariableValue::Known { value: value1 }, ConstVariableValue::Known { value: value1 },
ConstVariableValue::Known { value: value2 } ConstVariableValue::Known { value: value2 }
) => { ) => {
match <&'tcx ty::LazyConst<'tcx>>::unify_values(&value1, &value2) { match <&'tcx ty::Const<'tcx>>::unify_values(&value1, &value2) {
Ok(value) => Ok(ConstVariableValue::Known { value }), Ok(value) => Ok(ConstVariableValue::Known { value }),
Err(err) => Err(err), Err(err) => Err(err),
} }
@ -168,16 +168,13 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
} }
} }
impl<'tcx> EqUnifyValue for &'tcx ty::LazyConst<'tcx> {} impl<'tcx> EqUnifyValue for &'tcx ty::Const<'tcx> {}
pub fn replace_if_possible( pub fn replace_if_possible(
mut table: RefMut<'_, UnificationTable<InPlace<ty::ConstVid<'tcx>>>>, mut table: RefMut<'_, UnificationTable<InPlace<ty::ConstVid<'tcx>>>>,
c: &'tcx ty::LazyConst<'tcx> c: &'tcx ty::Const<'tcx>
) -> &'tcx ty::LazyConst<'tcx> { ) -> &'tcx ty::Const<'tcx> {
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } = c {
val: ConstValue::Infer(InferConst::Var(vid)),
..
}) = c {
match table.probe_value(*vid).val.known() { match table.probe_value(*vid).val.known() {
Some(c) => c, Some(c) => c,
None => c, None => c,

View File

@ -81,26 +81,24 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Match<'a, 'gcx, 'tcx> {
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::LazyConst<'tcx>, b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b); debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b { if a == b {
return Ok(a); return Ok(a);
} }
if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) { match (a.val, b.val) {
match (a_eval.val, b_eval.val) { (_, ConstValue::Infer(InferConst::Fresh(_))) => {
(_, ConstValue::Infer(InferConst::Fresh(_))) => { return Ok(a);
return Ok(a);
}
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
}
_ => {}
} }
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
}
_ => {}
} }
relate::super_relate_consts(self, a, b) relate::super_relate_consts(self, a, b)

View File

@ -232,7 +232,7 @@ pub struct CommonLifetimes<'tcx> {
pub re_static: Region<'tcx>, pub re_static: Region<'tcx>,
pub re_erased: Region<'tcx>, pub re_erased: Region<'tcx>,
pub ct_err: &'tcx LazyConst<'tcx>, pub ct_err: &'tcx Const<'tcx>,
} }
pub struct LocalTableInContext<'a, V: 'a> { pub struct LocalTableInContext<'a, V: 'a> {
@ -2683,11 +2683,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self, self,
ic: InferConst<'tcx>, ic: InferConst<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> &'tcx LazyConst<'tcx> { ) -> &'tcx ty::Const<'tcx> {
self.mk_lazy_const(LazyConst::Evaluated(ty::Const { self.mk_const(ty::Const {
val: ConstValue::Infer(ic), val: ConstValue::Infer(ic),
ty, ty,
})) })
} }
#[inline] #[inline]

View File

@ -45,7 +45,7 @@ pub enum TypeError<'tcx> {
ProjectionBoundsLength(ExpectedFound<usize>), ProjectionBoundsLength(ExpectedFound<usize>),
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>), ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),
ConstMismatch(ExpectedFound<&'tcx ty::LazyConst<'tcx>>), ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
} }
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]

View File

@ -201,7 +201,7 @@ pub trait TypeVisitor<'tcx> : Sized {
pub struct BottomUpFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F, G, H> pub struct BottomUpFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F, G, H>
where F: FnMut(Ty<'tcx>) -> Ty<'tcx>, where F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>, G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
H: FnMut(&'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx>, H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
{ {
pub tcx: TyCtxt<'a, 'gcx, 'tcx>, pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
pub ty_op: F, pub ty_op: F,
@ -212,7 +212,7 @@ pub struct BottomUpFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F, G, H>
impl<'a, 'gcx, 'tcx, F, G, H> TypeFolder<'gcx, 'tcx> for BottomUpFolder<'a, 'gcx, 'tcx, F, G, H> impl<'a, 'gcx, 'tcx, F, G, H> TypeFolder<'gcx, 'tcx> for BottomUpFolder<'a, 'gcx, 'tcx, F, G, H>
where F: FnMut(Ty<'tcx>) -> Ty<'tcx>, where F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>, G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
H: FnMut(&'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx>, H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
{ {
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx } fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
@ -226,7 +226,7 @@ impl<'a, 'gcx, 'tcx, F, G, H> TypeFolder<'gcx, 'tcx> for BottomUpFolder<'a, 'gcx
(self.lt_op)(r) (self.lt_op)(r)
} }
fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
let ct = ct.super_fold_with(self); let ct = ct.super_fold_with(self);
(self.ct_op)(ct) (self.ct_op)(ct)
} }
@ -435,7 +435,7 @@ struct BoundVarReplacer<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
fld_r: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a), fld_r: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
fld_t: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a), fld_t: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a),
fld_c: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx> + 'a), fld_c: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a),
} }
impl<'a, 'gcx, 'tcx> BoundVarReplacer<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> BoundVarReplacer<'a, 'gcx, 'tcx> {
@ -447,7 +447,7 @@ impl<'a, 'gcx, 'tcx> BoundVarReplacer<'a, 'gcx, 'tcx> {
) -> Self ) -> Self
where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>, G: FnMut(ty::BoundTy) -> Ty<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx>, H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
{ {
BoundVarReplacer { BoundVarReplacer {
tcx, tcx,
@ -515,11 +515,11 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for BoundVarReplacer<'a, 'gcx, 'tcx>
} }
} }
fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const {
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, bound_const)), val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, bound_const)),
ty, ty,
}) = *ct { } = *ct {
if debruijn == self.current_index { if debruijn == self.current_index {
let fld_c = &mut self.fld_c; let fld_c = &mut self.fld_c;
let ct = fld_c(bound_const, ty); let ct = fld_c(bound_const, ty);
@ -582,7 +582,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>) ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>, G: FnMut(ty::BoundTy) -> Ty<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx>, H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
T: TypeFoldable<'tcx>, T: TypeFoldable<'tcx>,
{ {
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
@ -629,7 +629,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>) ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>, G: FnMut(ty::BoundTy) -> Ty<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx>, H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
T: TypeFoldable<'tcx> T: TypeFoldable<'tcx>
{ {
self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c) self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c)
@ -794,11 +794,11 @@ impl TypeFolder<'gcx, 'tcx> for Shifter<'a, 'gcx, 'tcx> {
} }
} }
fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const {
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, bound_const)), val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, bound_const)),
ty, ty,
}) = *ct { } = *ct {
if self.amount == 0 || debruijn < self.current_index { if self.amount == 0 || debruijn < self.current_index {
ct ct
} else { } else {
@ -908,11 +908,11 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
r.bound_at_or_above_binder(self.outer_index) r.bound_at_or_above_binder(self.outer_index)
} }
fn visit_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> bool { fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> bool {
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const {
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, _)), val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, _)),
.. ..
}) = *ct { } = *ct {
debruijn >= self.outer_index debruijn >= self.outer_index
} else { } else {
false false

View File

@ -96,6 +96,7 @@ mod constness;
pub mod error; pub mod error;
mod erase_regions; mod erase_regions;
pub mod fast_reject; pub mod fast_reject;
pub mod flags;
pub mod fold; pub mod fold;
pub mod inhabitedness; pub mod inhabitedness;
pub mod layout; pub mod layout;
@ -112,7 +113,6 @@ pub mod wf;
pub mod util; pub mod util;
mod context; mod context;
mod flags;
mod instance; mod instance;
mod structural_impls; mod structural_impls;
mod sty; mod sty;

View File

@ -712,7 +712,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
// in order to place the projections inside the `<...>`. // in order to place the projections inside the `<...>`.
if !resugared { if !resugared {
// Use a type that can't appear in defaults of type parameters. // Use a type that can't appear in defaults of type parameters.
let dummy_self = self.tcx().mk_infer(ty::FreshTy(0)); let dummy_self = self.tcx().mk_ty_infer(ty::FreshTy(0));
let principal = principal.with_self_ty(self.tcx(), dummy_self); let principal = principal.with_self_ty(self.tcx(), dummy_self);
let args = self.generic_args_to_print( let args = self.generic_args_to_print(
@ -1481,7 +1481,7 @@ define_print_and_forward_display! {
ty::ExistentialTraitRef<'tcx> { ty::ExistentialTraitRef<'tcx> {
// Use a type that can't appear in defaults of type parameters. // Use a type that can't appear in defaults of type parameters.
let dummy_self = cx.tcx().mk_infer(ty::FreshTy(0)); let dummy_self = cx.tcx().mk_ty_infer(ty::FreshTy(0));
let trait_ref = self.with_self_ty(cx.tcx(), dummy_self); let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
p!(print(trait_ref)) p!(print(trait_ref))
} }

View File

@ -7,7 +7,7 @@
use crate::hir::def_id::DefId; use crate::hir::def_id::DefId;
use crate::ty::subst::{Kind, UnpackedKind, SubstsRef}; use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use crate::ty::error::{ExpectedFound, TypeError, ConstError}; use crate::ty::error::{ExpectedFound, TypeError};
use crate::mir::interpret::{GlobalId, ConstValue, Scalar}; use crate::mir::interpret::{GlobalId, ConstValue, Scalar};
use crate::util::common::ErrorReported; use crate::util::common::ErrorReported;
use syntax_pos::DUMMY_SP; use syntax_pos::DUMMY_SP;
@ -86,9 +86,9 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized {
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::LazyConst<'tcx> b: &'tcx ty::Const<'tcx>
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>>; ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>;
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>) fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> RelateResult<'tcx, ty::Binder<T>> -> RelateResult<'tcx, ty::Binder<T>>
@ -124,7 +124,7 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
ast::Mutability::MutMutable => ty::Invariant, ast::Mutability::MutMutable => ty::Invariant,
}; };
let ty = relation.relate_with_variance(variance, &a.ty, &b.ty)?; let ty = relation.relate_with_variance(variance, &a.ty, &b.ty)?;
Ok(ty::TypeAndMut {ty: ty, mutbl: mutbl}) Ok(ty::TypeAndMut { ty, mutbl })
} }
} }
} }
@ -590,59 +590,55 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
/// it. /// it.
pub fn super_relate_consts<'a, 'gcx, 'tcx, R>( pub fn super_relate_consts<'a, 'gcx, 'tcx, R>(
relation: &mut R, relation: &mut R,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::LazyConst<'tcx> b: &'tcx ty::Const<'tcx>
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
where where
R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{ {
// Only consts whose types are equal should be compared.
assert_eq!(a.ty, b.ty);
let tcx = relation.tcx(); let tcx = relation.tcx();
match (a, b) { // Currently, the values that can be unified are those that
(ty::LazyConst::Evaluated(a_eval), ty::LazyConst::Evaluated(b_eval)) => { // implement both `PartialEq` and `Eq`, corresponding to
// Only consts whose types are equal should be compared. // `structural_match` types.
assert_eq!(a_eval.ty, b_eval.ty); // FIXME(const_generics): check for `structural_match` synthetic attribute.
match (a.val, b.val) {
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
// The caller should handle these cases!
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
}
(ConstValue::Param(a_p), ConstValue::Param(b_p)) if a_p.index == b_p.index => {
Ok(a)
}
(ConstValue::Placeholder(p1), ConstValue::Placeholder(p2)) if p1 == p2 => {
Ok(a)
}
(ConstValue::Scalar(Scalar::Bits { .. }), _) if a == b => {
Ok(a)
}
(ConstValue::ByRef(..), _) => {
bug!(
"non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}",
a,
b,
);
}
// Currently, the values that can be unified are those that // FIXME(const_generics): this is wrong, as it is a projection
// implement both `PartialEq` and `Eq`, corresponding to (ConstValue::Unevaluated(a_def_id, a_substs),
// `structural_match` types. ConstValue::Unevaluated(b_def_id, b_substs)) if a_def_id == b_def_id => {
// FIXME(const_generics): check for `structural_match` synthetic attribute. let substs =
match (a_eval.val, b_eval.val) { relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?;
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => { Ok(tcx.mk_const(ty::Const {
// The caller should handle these cases! val: ConstValue::Unevaluated(a_def_id, &substs),
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b) ty: a.ty,
} })
(ConstValue::Param(a_p), ConstValue::Param(b_p)) if a_p.index == b_p.index => {
Ok(a)
}
(ConstValue::Placeholder(p1), ConstValue::Placeholder(p2)) if p1 == p2 => {
Ok(a)
}
(ConstValue::Scalar(Scalar::Bits { .. }), _) if a == b => {
Ok(a)
}
(ConstValue::ByRef(..), _) => {
bug!(
"non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}",
a,
b,
);
}
_ => {
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
}
} }
}
// FIXME(const_generics): this is probably wrong (regarding TyProjection) _ => {
(
ty::LazyConst::Unevaluated(a_def_id, a_substs),
ty::LazyConst::Unevaluated(b_def_id, b_substs),
) if a_def_id == b_def_id => {
let substs =
relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
Ok(tcx.mk_lazy_const(ty::LazyConst::Unevaluated(*a_def_id, substs)))
}
_ => {
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))) Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
} }
} }
@ -719,11 +715,11 @@ impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
} }
} }
impl<'tcx> Relate<'tcx> for &'tcx ty::LazyConst<'tcx> { impl<'tcx> Relate<'tcx> for &'tcx ty::Const<'tcx> {
fn relate<'a, 'gcx, R>(relation: &mut R, fn relate<'a, 'gcx, R>(relation: &mut R,
a: &&'tcx ty::LazyConst<'tcx>, a: &&'tcx ty::Const<'tcx>,
b: &&'tcx ty::LazyConst<'tcx>) b: &&'tcx ty::Const<'tcx>)
-> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{ {
relation.consts(*a, *b) relation.consts(*a, *b)

View File

@ -279,13 +279,13 @@ impl TypeRelation<'cx, 'gcx, 'tcx> for AnswerSubstitutor<'cx, 'gcx, 'tcx> {
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::LazyConst<'tcx>, a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::LazyConst<'tcx>, b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
if let ty::LazyConst::Evaluated(ty::Const { if let ty::Const {
val: ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)), val: ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)),
.. ..
}) = a { } = a {
if *debruijn == self.binder_index { if *debruijn == self.binder_index {
self.unify_free_answer_var(*bound_ct, b.into())?; self.unify_free_answer_var(*bound_ct, b.into())?;
return Ok(b); return Ok(b);
@ -294,14 +294,14 @@ impl TypeRelation<'cx, 'gcx, 'tcx> for AnswerSubstitutor<'cx, 'gcx, 'tcx> {
match (a, b) { match (a, b) {
( (
ty::LazyConst::Evaluated(ty::Const { ty::Const {
val: ConstValue::Infer(InferConst::Canonical(a_debruijn, a_bound)), val: ConstValue::Infer(InferConst::Canonical(a_debruijn, a_bound)),
.. ..
}), },
ty::LazyConst::Evaluated(ty::Const { ty::Const {
val: ConstValue::Infer(InferConst::Canonical(b_debruijn, b_bound)), val: ConstValue::Infer(InferConst::Canonical(b_debruijn, b_bound)),
.. ..
}), },
) => { ) => {
assert_eq!(a_debruijn, b_debruijn); assert_eq!(a_debruijn, b_debruijn);
assert_eq!(a_bound, b_bound); assert_eq!(a_bound, b_bound);

View File

@ -11,7 +11,7 @@ use rustc::infer::InferCtxt;
use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast}; use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast};
use rustc::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder}; use rustc::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder};
use rustc::ty::subst::UnpackedKind; use rustc::ty::subst::UnpackedKind;
use rustc::ty::{self, Ty, TyCtxt, Const, LazyConst}; use rustc::ty::{self, Ty, TyCtxt, Const};
use rustc::mir::interpret::ConstValue; use rustc::mir::interpret::ConstValue;
use rustc::util::nodemap::DefIdSet; use rustc::util::nodemap::DefIdSet;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -567,36 +567,34 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}, },
ct_op: |ct| { ct_op: |ct| {
trace!("checking const {:?}", ct); trace!("checking const {:?}", ct);
// find a const parameter // Find a const parameter
if let LazyConst::Evaluated(Const { ty, val }) = ct { if let ConstValue::Param(..) = ct.val {
if let ConstValue::Param(..) = val { // look it up in the substitution list
// look it up in the substitution list assert_eq!(opaque_defn.substs.len(), generics.params.len());
assert_eq!(opaque_defn.substs.len(), generics.params.len()); for (subst, param) in opaque_defn.substs.iter()
for (subst, param) in opaque_defn.substs.iter() .zip(&generics.params) {
.zip(&generics.params) { if let UnpackedKind::Const(subst) = subst.unpack() {
if let UnpackedKind::Const(subst) = subst.unpack() { if subst == ct {
if subst == ct { // found it in the substitution list, replace with the
// found it in the substitution list, replace with the // parameter from the existential type
// parameter from the existential type return self.tcx()
return self.tcx() .global_tcx()
.global_tcx() .mk_const_param(param.index, param.name, ty);
.mk_const_param(param.index, param.name, ty);
}
} }
} }
self.tcx()
.sess
.struct_span_err(
span,
&format!(
"const parameter `{}` is part of concrete type but not \
used in parameter list for existential type",
ct,
),
)
.emit();
return self.tcx().types.ct_err;
} }
self.tcx()
.sess
.struct_span_err(
span,
&format!(
"const parameter `{}` is part of concrete type but not \
used in parameter list for existential type",
ct,
),
)
.emit();
return self.tcx().types.ct_err;
} }
ct ct
} }