mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-09 16:37:36 +00:00
Fix rebase from LazyConst removal
This commit is contained in:
parent
c888af52be
commit
fc16b0a147
@ -15,6 +15,7 @@ use std::sync::atomic::Ordering;
|
||||
use crate::ty::fold::{TypeFoldable, TypeFolder};
|
||||
use crate::ty::subst::Kind;
|
||||
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::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> {
|
||||
if let ty::LazyConst::Evaluated(ct) = c {
|
||||
match ct.val {
|
||||
ConstValue::Infer(InferConst::Var(vid)) => {
|
||||
debug!("canonical: const var found with vid {:?}", vid);
|
||||
match self.infcx.unwrap().probe_const_var(vid) {
|
||||
Ok(c) => {
|
||||
debug!("(resolved to {:?})", c);
|
||||
return self.fold_const(c);
|
||||
}
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
match ct.val {
|
||||
ConstValue::Infer(InferConst::Var(vid)) => {
|
||||
debug!("canonical: const var found with vid {:?}", vid);
|
||||
match self.infcx.unwrap().probe_const_var(vid) {
|
||||
Ok(c) => {
|
||||
debug!("(resolved to {:?})", c);
|
||||
return self.fold_const(c);
|
||||
}
|
||||
|
||||
// `ConstVar(vid)` is unresolved, track its universe index in the
|
||||
// canonicalized result
|
||||
Err(mut ui) => {
|
||||
if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
|
||||
// FIXME: perf problem described in #55921.
|
||||
ui = ty::UniverseIndex::ROOT;
|
||||
}
|
||||
return self.canonicalize_const_var(
|
||||
CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Const(ui),
|
||||
},
|
||||
c,
|
||||
);
|
||||
// `ConstVar(vid)` is unresolved, track its universe index in the
|
||||
// canonicalized result
|
||||
Err(mut ui) => {
|
||||
if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
|
||||
// FIXME: perf problem described in #55921.
|
||||
ui = ty::UniverseIndex::ROOT;
|
||||
}
|
||||
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) {
|
||||
c.super_fold_with(self)
|
||||
let flags = FlagComputation::for_const(ct);
|
||||
if flags.intersects(self.needs_canonical_flags) {
|
||||
ct.super_fold_with(self)
|
||||
} else {
|
||||
c
|
||||
ct
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -700,25 +700,19 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
||||
fn canonicalize_const_var(
|
||||
&mut self,
|
||||
info: CanonicalVarInfo,
|
||||
const_var: &'tcx ty::LazyConst<'tcx>
|
||||
) -> &'tcx ty::LazyConst<'tcx> {
|
||||
const_var: &'tcx ty::Const<'tcx>
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
let infcx = self.infcx.expect("encountered const-var without infcx");
|
||||
let bound_to = infcx.resolve_const_var(const_var);
|
||||
if bound_to != const_var {
|
||||
self.fold_const(bound_to)
|
||||
} 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());
|
||||
self.tcx().mk_lazy_const(
|
||||
ty::LazyConst::Evaluated(ty::Const {
|
||||
self.tcx().mk_const(
|
||||
ty::Const {
|
||||
val: ConstValue::Infer(InferConst::Canonical(self.binder_index, var.into())),
|
||||
ty,
|
||||
})
|
||||
ty: const_var.ty,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -419,12 +419,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||
universe: universe_mapped,
|
||||
name,
|
||||
};
|
||||
self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
|
||||
self.tcx.mk_const(
|
||||
ty::Const {
|
||||
val: ConstValue::Placeholder(placeholder_mapped),
|
||||
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))
|
||||
).into(),
|
||||
UnpackedKind::Const(ct) => {
|
||||
let ty = match ct {
|
||||
ty::LazyConst::Unevaluated(def_id, _) => {
|
||||
tcx.type_of(*def_id)
|
||||
}
|
||||
ty::LazyConst::Evaluated(ty::Const { ty, .. }) => ty,
|
||||
};
|
||||
tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const {
|
||||
ty: ty,
|
||||
tcx.mk_const(ty::Const {
|
||||
ty: ct.ty,
|
||||
val: ConstValue::Infer(
|
||||
InferConst::Canonical(ty::INNERMOST, ty::BoundVar::from_u32(i))
|
||||
),
|
||||
})).into()
|
||||
}).into()
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
|
@ -481,10 +481,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
UnpackedKind::Const(result_value) => {
|
||||
if let ty::LazyConst::Evaluated(ty::Const {
|
||||
if let ty::Const {
|
||||
val: ConstValue::Infer(InferConst::Canonical(debrujin, b)),
|
||||
..
|
||||
}) = result_value {
|
||||
} = result_value {
|
||||
// ...in which case we would set `canonical_vars[0]` to `Some(const X)`.
|
||||
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
|
@ -33,7 +33,7 @@ use super::unify_key::{ConstVarValue, ConstVariableValue, ConstVariableOrigin};
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::mir::interpret::ConstValue;
|
||||
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::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
use crate::ty::subst::SubstsRef;
|
||||
@ -118,41 +118,39 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
|
||||
pub fn super_combine_consts<R>(
|
||||
&self,
|
||||
relation: &mut R,
|
||||
a: &'tcx LazyConst<'tcx>,
|
||||
b: &'tcx LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx LazyConst<'tcx>>
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
|
||||
where
|
||||
R: TypeRelation<'infcx, 'gcx, 'tcx>,
|
||||
{
|
||||
let a_is_expected = relation.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))) => {
|
||||
self.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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
match (a.val, b.val) {
|
||||
(ConstValue::Infer(InferConst::Var(a_vid)),
|
||||
ConstValue::Infer(InferConst::Var(b_vid))) => {
|
||||
self.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);
|
||||
}
|
||||
|
||||
// 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)
|
||||
@ -162,8 +160,8 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
|
||||
&self,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::ConstVid<'tcx>,
|
||||
value: &'tcx LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx LazyConst<'tcx>> {
|
||||
value: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
self.const_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_value(vid, ConstVarValue {
|
||||
@ -582,16 +580,13 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
c: &'tcx ty::LazyConst<'tcx>,
|
||||
c2: &'tcx ty::LazyConst<'tcx>
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
|
||||
c: &'tcx ty::Const<'tcx>,
|
||||
c2: &'tcx ty::Const<'tcx>
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
|
||||
|
||||
match c {
|
||||
LazyConst::Evaluated(ty::Const {
|
||||
val: ConstValue::Infer(InferConst::Var(vid)),
|
||||
..
|
||||
}) => {
|
||||
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
|
||||
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
|
||||
match variable_table.probe_value(*vid).val.known() {
|
||||
Some(u) => {
|
||||
@ -628,7 +623,7 @@ impl<'tcx, T:Clone + PartialEq> RelateResultCompare<'tcx, T> for RelateResult<'t
|
||||
|
||||
pub fn const_unification_error<'tcx>(
|
||||
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::ConstMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b))
|
||||
}
|
||||
|
@ -104,9 +104,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
b: &'tcx ty::LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
|
||||
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 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(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)), _) => {
|
||||
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);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
match (a.val, b.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)), _) => {
|
||||
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)?;
|
||||
|
@ -46,7 +46,7 @@ pub struct TypeFreshener<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
ty_freshen_count: u32,
|
||||
const_freshen_count: u32,
|
||||
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> {
|
||||
@ -88,11 +88,11 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
|
||||
|
||||
fn freshen_const<F>(
|
||||
&mut self,
|
||||
opt_ct: Option<&'tcx ty::LazyConst<'tcx>>,
|
||||
opt_ct: Option<&'tcx ty::Const<'tcx>>,
|
||||
key: ty::InferConst<'tcx>,
|
||||
freshener: F,
|
||||
ty: Ty<'tcx>,
|
||||
) -> &'tcx ty::LazyConst<'tcx>
|
||||
) -> &'tcx ty::Const<'tcx>
|
||||
where
|
||||
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> {
|
||||
if let ty::LazyConst::Evaluated(ty::Const{ val, ty }) = ct {
|
||||
match val {
|
||||
ConstValue::Infer(ty::InferConst::Var(v)) => {
|
||||
let opt_ct = self.infcx.const_unification_table
|
||||
.borrow_mut()
|
||||
.probe_value(*v)
|
||||
.val
|
||||
.known();
|
||||
return self.freshen_const(
|
||||
opt_ct,
|
||||
ty::InferConst::Var(*v),
|
||||
ty::InferConst::Fresh,
|
||||
ty,
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
match ct.val {
|
||||
ConstValue::Infer(ty::InferConst::Var(v)) => {
|
||||
let opt_ct = self.infcx.const_unification_table
|
||||
.borrow_mut()
|
||||
.probe_value(v)
|
||||
.val
|
||||
.known();
|
||||
return self.freshen_const(
|
||||
opt_ct,
|
||||
ty::InferConst::Var(v),
|
||||
ty::InferConst::Fresh,
|
||||
ct.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)) => {
|
||||
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(..) => {}
|
||||
return ct;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -176,11 +176,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for InferenceFudger<'a, 'gcx, 'tcx>
|
||||
r
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
|
||||
if let ty::LazyConst::Evaluated(ty::Const {
|
||||
val: ConstValue::Infer(ty::InferConst::Var(vid)),
|
||||
ty,
|
||||
}) = *ct {
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
if let ty::Const { val: ConstValue::Infer(ty::InferConst::Var(vid)), ty } = *ct {
|
||||
if self.const_variables.contains(&vid) {
|
||||
// This variable was created during the
|
||||
// fudging. Recreate it with a fresh variable
|
||||
|
@ -62,9 +62,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
b: &'tcx ty::LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
|
@ -101,7 +101,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
};
|
||||
|
||||
let fld_c = |bound_var: ty::BoundVar, ty| {
|
||||
self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
|
||||
self.tcx.mk_const(
|
||||
ty::Const {
|
||||
val: ConstValue::Placeholder(ty::PlaceholderConst {
|
||||
universe: next_universe,
|
||||
@ -109,7 +109,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}),
|
||||
ty,
|
||||
}
|
||||
))
|
||||
)
|
||||
};
|
||||
|
||||
let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c);
|
||||
|
@ -62,9 +62,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
b: &'tcx ty::LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
|
@ -1004,7 +1004,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
&self,
|
||||
ty: Ty<'tcx>,
|
||||
origin: ConstVariableOrigin
|
||||
) -> &'tcx ty::LazyConst<'tcx> {
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
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>,
|
||||
origin: ConstVariableOrigin,
|
||||
universe: ty::UniverseIndex,
|
||||
) -> &'tcx ty::LazyConst<'tcx> {
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
let vid = self.const_unification_table
|
||||
.borrow_mut()
|
||||
.new_key(ConstVarValue {
|
||||
@ -1367,7 +1367,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn probe_const_var(
|
||||
&self,
|
||||
vid: ty::ConstVid<'tcx>
|
||||
) -> Result<&'tcx ty::LazyConst<'tcx>, ty::UniverseIndex> {
|
||||
) -> Result<&'tcx ty::Const<'tcx>, ty::UniverseIndex> {
|
||||
use self::unify_key::ConstVariableValue;
|
||||
|
||||
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(
|
||||
&self,
|
||||
ct: &'tcx ty::LazyConst<'tcx>
|
||||
) -> &'tcx ty::LazyConst<'tcx> {
|
||||
if let ty::LazyConst::Evaluated(ty::Const {
|
||||
val: ConstValue::Infer(InferConst::Var(v)),
|
||||
..
|
||||
}) = ct {
|
||||
ct: &'tcx ty::Const<'tcx>
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
if let ty::Const { val: ConstValue::Infer(InferConst::Var(v)), .. } = ct {
|
||||
self.const_unification_table
|
||||
.borrow_mut()
|
||||
.probe_value(*v)
|
||||
@ -1398,13 +1395,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
pub fn shallow_resolve_const(
|
||||
&self,
|
||||
ct: &'tcx ty::LazyConst<'tcx>
|
||||
) -> &'tcx ty::LazyConst<'tcx> {
|
||||
ct: &'tcx ty::Const<'tcx>
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
match ct {
|
||||
ty::LazyConst::Evaluated(ty::Const {
|
||||
val: ConstValue::Infer(InferConst::Var(vid)),
|
||||
..
|
||||
}) => {
|
||||
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
|
||||
self.const_unification_table
|
||||
.borrow_mut()
|
||||
.probe_value(*vid)
|
||||
|
@ -610,13 +610,10 @@ where
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
b: &'tcx ty::LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
|
||||
if let ty::LazyConst::Evaluated(ty::Const {
|
||||
val: ConstValue::Infer(InferConst::Canonical(_, _)),
|
||||
..
|
||||
}) = a {
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
if let ty::Const { val: ConstValue::Infer(InferConst::Canonical(_, _)), .. } = a {
|
||||
// FIXME(const_generics): I'm unsure how this branch should actually be handled,
|
||||
// so this is probably not correct.
|
||||
self.infcx.super_combine_consts(self, a, b)
|
||||
@ -983,15 +980,12 @@ where
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
_: &'tcx ty::LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
_: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
debug!("TypeGeneralizer::consts(a={:?})", a);
|
||||
|
||||
if let ty::LazyConst::Evaluated(ty::Const {
|
||||
val: ConstValue::Infer(InferConst::Canonical(_, _)),
|
||||
..
|
||||
}) = a {
|
||||
if let ty::Const { val: ConstValue::Infer(InferConst::Canonical(_, _)), .. } = a {
|
||||
bug!(
|
||||
"unexpected inference variable encountered in NLL generalization: {:?}",
|
||||
a
|
||||
|
@ -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() {
|
||||
ct // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||
} 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) {
|
||||
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
|
||||
// defaulted tuples.
|
||||
} else {
|
||||
let c = self.infcx.shallow_resolve_const(c);
|
||||
match c {
|
||||
ty::LazyConst::Evaluated(ty::Const { val, .. }) => {
|
||||
match val {
|
||||
ConstValue::Infer(InferConst::Var(vid)) => {
|
||||
self.err = Some(FixupError::UnresolvedConst(*vid));
|
||||
return self.tcx().types.ct_err;
|
||||
}
|
||||
ConstValue::Infer(InferConst::Fresh(_)) => {
|
||||
bug!("Unexpected const in full const resolver: {:?}", c);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
match c.val {
|
||||
ConstValue::Infer(InferConst::Var(vid)) => {
|
||||
self.err = Some(FixupError::UnresolvedConst(vid));
|
||||
return self.tcx().types.ct_err;
|
||||
}
|
||||
ConstValue::Infer(InferConst::Fresh(_)) => {
|
||||
bug!("Unexpected const in full const resolver: {:?}", c);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -137,9 +137,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
b: &'tcx ty::LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
|
||||
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
|
||||
// relation, so we're just going to perform equating here instead.
|
||||
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)), _) => {
|
||||
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);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
match (a.val, b.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)), _) => {
|
||||
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)?;
|
||||
|
@ -90,14 +90,14 @@ pub enum ConstVariableOrigin {
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum ConstVariableValue<'tcx> {
|
||||
Known { value: &'tcx ty::LazyConst<'tcx> },
|
||||
Known { value: &'tcx ty::Const<'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>> {
|
||||
pub fn known(&self) -> Option<&'tcx ty::Const<'tcx>> {
|
||||
match *self {
|
||||
ConstVariableValue::Unknown { .. } => None,
|
||||
ConstVariableValue::Known { value } => Some(value),
|
||||
@ -126,7 +126,7 @@ impl<'tcx> UnifyKey for ty::ConstVid<'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> {
|
||||
let val = match (value1.val, value2.val) {
|
||||
@ -134,7 +134,7 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
|
||||
ConstVariableValue::Known { value: value1 },
|
||||
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 }),
|
||||
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(
|
||||
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 {
|
||||
c: &'tcx ty::Const<'tcx>
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
if let ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } = c {
|
||||
match table.probe_value(*vid).val.known() {
|
||||
Some(c) => c,
|
||||
None => c,
|
||||
|
@ -81,26 +81,24 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Match<'a, 'gcx, 'tcx> {
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
b: &'tcx ty::LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
|
||||
if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) {
|
||||
match (a_eval.val, b_eval.val) {
|
||||
(_, ConstValue::Infer(InferConst::Fresh(_))) => {
|
||||
return Ok(a);
|
||||
}
|
||||
|
||||
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
|
||||
return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
|
||||
}
|
||||
|
||||
_ => {}
|
||||
match (a.val, b.val) {
|
||||
(_, ConstValue::Infer(InferConst::Fresh(_))) => {
|
||||
return Ok(a);
|
||||
}
|
||||
|
||||
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
|
||||
return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
relate::super_relate_consts(self, a, b)
|
||||
|
@ -232,7 +232,7 @@ pub struct CommonLifetimes<'tcx> {
|
||||
pub re_static: 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> {
|
||||
@ -2683,11 +2683,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
self,
|
||||
ic: InferConst<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> &'tcx LazyConst<'tcx> {
|
||||
self.mk_lazy_const(LazyConst::Evaluated(ty::Const {
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
self.mk_const(ty::Const {
|
||||
val: ConstValue::Infer(ic),
|
||||
ty,
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -45,7 +45,7 @@ pub enum TypeError<'tcx> {
|
||||
ProjectionBoundsLength(ExpectedFound<usize>),
|
||||
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)]
|
||||
|
@ -201,7 +201,7 @@ pub trait TypeVisitor<'tcx> : Sized {
|
||||
pub struct BottomUpFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F, G, H>
|
||||
where F: FnMut(Ty<'tcx>) -> Ty<'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 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>
|
||||
where F: FnMut(Ty<'tcx>) -> Ty<'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 }
|
||||
|
||||
@ -226,7 +226,7 @@ impl<'a, 'gcx, 'tcx, F, G, H> TypeFolder<'gcx, 'tcx> for BottomUpFolder<'a, 'gcx
|
||||
(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);
|
||||
(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_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> {
|
||||
@ -447,7 +447,7 @@ impl<'a, 'gcx, 'tcx> BoundVarReplacer<'a, 'gcx, 'tcx> {
|
||||
) -> Self
|
||||
where F: FnMut(ty::BoundRegion) -> ty::Region<'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 {
|
||||
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> {
|
||||
if let ty::LazyConst::Evaluated(ty::Const {
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
if let ty::Const {
|
||||
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, bound_const)),
|
||||
ty,
|
||||
}) = *ct {
|
||||
} = *ct {
|
||||
if debruijn == self.current_index {
|
||||
let fld_c = &mut self.fld_c;
|
||||
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>>)
|
||||
where F: FnMut(ty::BoundRegion) -> ty::Region<'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>,
|
||||
{
|
||||
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>>)
|
||||
where F: FnMut(ty::BoundRegion) -> ty::Region<'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>
|
||||
{
|
||||
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> {
|
||||
if let ty::LazyConst::Evaluated(ty::Const {
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
if let ty::Const {
|
||||
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, bound_const)),
|
||||
ty,
|
||||
}) = *ct {
|
||||
} = *ct {
|
||||
if self.amount == 0 || debruijn < self.current_index {
|
||||
ct
|
||||
} else {
|
||||
@ -908,11 +908,11 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
|
||||
r.bound_at_or_above_binder(self.outer_index)
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> bool {
|
||||
if let ty::LazyConst::Evaluated(ty::Const {
|
||||
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> bool {
|
||||
if let ty::Const {
|
||||
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, _)),
|
||||
..
|
||||
}) = *ct {
|
||||
} = *ct {
|
||||
debruijn >= self.outer_index
|
||||
} else {
|
||||
false
|
||||
|
@ -96,6 +96,7 @@ mod constness;
|
||||
pub mod error;
|
||||
mod erase_regions;
|
||||
pub mod fast_reject;
|
||||
pub mod flags;
|
||||
pub mod fold;
|
||||
pub mod inhabitedness;
|
||||
pub mod layout;
|
||||
@ -112,7 +113,6 @@ pub mod wf;
|
||||
pub mod util;
|
||||
|
||||
mod context;
|
||||
mod flags;
|
||||
mod instance;
|
||||
mod structural_impls;
|
||||
mod sty;
|
||||
|
@ -712,7 +712,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
|
||||
// in order to place the projections inside the `<...>`.
|
||||
if !resugared {
|
||||
// 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 args = self.generic_args_to_print(
|
||||
@ -1481,7 +1481,7 @@ define_print_and_forward_display! {
|
||||
|
||||
ty::ExistentialTraitRef<'tcx> {
|
||||
// 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);
|
||||
p!(print(trait_ref))
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
|
||||
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::util::common::ErrorReported;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
@ -86,9 +86,9 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized {
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
b: &'tcx ty::LazyConst<'tcx>
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>>;
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>;
|
||||
|
||||
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &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,
|
||||
};
|
||||
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.
|
||||
pub fn super_relate_consts<'a, 'gcx, 'tcx, R>(
|
||||
relation: &mut R,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
b: &'tcx ty::LazyConst<'tcx>
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>>
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
|
||||
where
|
||||
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();
|
||||
|
||||
match (a, b) {
|
||||
(ty::LazyConst::Evaluated(a_eval), ty::LazyConst::Evaluated(b_eval)) => {
|
||||
// Only consts whose types are equal should be compared.
|
||||
assert_eq!(a_eval.ty, b_eval.ty);
|
||||
// Currently, the values that can be unified are those that
|
||||
// implement both `PartialEq` and `Eq`, corresponding to
|
||||
// `structural_match` types.
|
||||
// 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
|
||||
// implement both `PartialEq` and `Eq`, corresponding to
|
||||
// `structural_match` types.
|
||||
// FIXME(const_generics): check for `structural_match` synthetic attribute.
|
||||
match (a_eval.val, b_eval.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,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
|
||||
}
|
||||
// FIXME(const_generics): this is wrong, as it is a projection
|
||||
(ConstValue::Unevaluated(a_def_id, a_substs),
|
||||
ConstValue::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_const(ty::Const {
|
||||
val: ConstValue::Unevaluated(a_def_id, &substs),
|
||||
ty: a.ty,
|
||||
})
|
||||
}
|
||||
}
|
||||
// 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)))
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
a: &&'tcx ty::LazyConst<'tcx>,
|
||||
b: &&'tcx ty::LazyConst<'tcx>)
|
||||
-> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>>
|
||||
a: &&'tcx ty::Const<'tcx>,
|
||||
b: &&'tcx ty::Const<'tcx>)
|
||||
-> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
|
||||
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
|
||||
{
|
||||
relation.consts(*a, *b)
|
||||
|
@ -279,13 +279,13 @@ impl TypeRelation<'cx, 'gcx, 'tcx> for AnswerSubstitutor<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::LazyConst<'tcx>,
|
||||
b: &'tcx ty::LazyConst<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::LazyConst<'tcx>> {
|
||||
if let ty::LazyConst::Evaluated(ty::Const {
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
if let ty::Const {
|
||||
val: ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)),
|
||||
..
|
||||
}) = a {
|
||||
} = a {
|
||||
if *debruijn == self.binder_index {
|
||||
self.unify_free_answer_var(*bound_ct, b.into())?;
|
||||
return Ok(b);
|
||||
@ -294,14 +294,14 @@ impl TypeRelation<'cx, 'gcx, 'tcx> for AnswerSubstitutor<'cx, 'gcx, 'tcx> {
|
||||
|
||||
match (a, b) {
|
||||
(
|
||||
ty::LazyConst::Evaluated(ty::Const {
|
||||
ty::Const {
|
||||
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)),
|
||||
..
|
||||
}),
|
||||
},
|
||||
) => {
|
||||
assert_eq!(a_debruijn, b_debruijn);
|
||||
assert_eq!(a_bound, b_bound);
|
||||
|
@ -11,7 +11,7 @@ use rustc::infer::InferCtxt;
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast};
|
||||
use rustc::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder};
|
||||
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::util::nodemap::DefIdSet;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
@ -567,36 +567,34 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
},
|
||||
ct_op: |ct| {
|
||||
trace!("checking const {:?}", ct);
|
||||
// find a const parameter
|
||||
if let LazyConst::Evaluated(Const { ty, val }) = ct {
|
||||
if let ConstValue::Param(..) = val {
|
||||
// look it up in the substitution list
|
||||
assert_eq!(opaque_defn.substs.len(), generics.params.len());
|
||||
for (subst, param) in opaque_defn.substs.iter()
|
||||
.zip(&generics.params) {
|
||||
if let UnpackedKind::Const(subst) = subst.unpack() {
|
||||
if subst == ct {
|
||||
// found it in the substitution list, replace with the
|
||||
// parameter from the existential type
|
||||
return self.tcx()
|
||||
.global_tcx()
|
||||
.mk_const_param(param.index, param.name, ty);
|
||||
}
|
||||
// Find a const parameter
|
||||
if let ConstValue::Param(..) = ct.val {
|
||||
// look it up in the substitution list
|
||||
assert_eq!(opaque_defn.substs.len(), generics.params.len());
|
||||
for (subst, param) in opaque_defn.substs.iter()
|
||||
.zip(&generics.params) {
|
||||
if let UnpackedKind::Const(subst) = subst.unpack() {
|
||||
if subst == ct {
|
||||
// found it in the substitution list, replace with the
|
||||
// parameter from the existential type
|
||||
return self.tcx()
|
||||
.global_tcx()
|
||||
.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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user