mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-10 08:57: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::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,
|
||||||
})
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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.
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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)?;
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -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)?;
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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]
|
||||||
|
@ -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)]
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user