1
Fork 0

extract ConstKind::Unevaluated into a struct

This commit is contained in:
lcnr 2021-03-12 00:01:34 +01:00
parent 41b315a470
commit 43ebac119b
25 changed files with 131 additions and 88 deletions

View file

@ -803,7 +803,12 @@ impl AutoTraitFinder<'tcx> {
}
ty::PredicateKind::ConstEquate(c1, c2) => {
let evaluate = |c: &'tcx ty::Const<'tcx>| {
if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
if let ty::ConstKind::Unevaluated(ty::Unevaluated {
def,
substs,
promoted,
}) = c.val
{
match select.infcx().const_eval_resolve(
obligation.param_env,
def,

View file

@ -239,7 +239,9 @@ impl AbstractConst<'tcx> {
ct: &ty::Const<'tcx>,
) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
match ct.val {
ty::ConstKind::Unevaluated(def, substs, None) => AbstractConst::new(tcx, def, substs),
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: _ }) => {
AbstractConst::new(tcx, def, substs)
}
ty::ConstKind::Error(_) => Err(ErrorReported),
_ => Ok(None),
}
@ -532,22 +534,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
if let Some(next) = self.build_terminator(block.terminator())? {
block = &self.body.basic_blocks()[next];
} else {
assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap());
// `AbstractConst`s should not contain any promoteds as they require references which
// are not allowed.
assert!(!self.nodes.iter().any(|n| matches!(
n.node,
Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(_, _, Some(_)), ty: _ })
)));
self.nodes[self.locals[mir::RETURN_PLACE]].used = true;
if let Some(&unused) = self.nodes.iter().find(|n| !n.used) {
self.error(Some(unused.span), "dead code")?;
}
return Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node)));
break;
}
}
assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap());
for n in self.nodes.iter() {
if let Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(ct), ty: _ }) = n.node {
// `AbstractConst`s should not contain any promoteds as they require references which
// are not allowed.
assert_eq!(ct.promoted, None);
}
}
self.nodes[self.locals[mir::RETURN_PLACE]].used = true;
if let Some(&unused) = self.nodes.iter().find(|n| !n.used) {
self.error(Some(unused.span), "dead code")?;
}
Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node)))
}
}
@ -673,10 +678,16 @@ pub(super) fn try_unify<'tcx>(
// we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
// means that we only allow inference variables if they are equal.
(ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => a_val == b_val,
(
ty::ConstKind::Unevaluated(a_def, a_substs, None),
ty::ConstKind::Unevaluated(b_def, b_substs, None),
) => a_def == b_def && a_substs == b_substs,
// We expand generic anonymous constants at the start of this function, so this
// branch should only be taking when dealing with associated constants, at
// which point directly comparing them seems like the desired behavior.
//
// FIXME(const_evaluatable_checked): This isn't actually the case.
// We also take this branch for concrete anonymous constants and
// expand generic anonymous constants with concrete substs.
(ty::ConstKind::Unevaluated(a_uv), ty::ConstKind::Unevaluated(b_uv)) => {
a_uv == b_uv
}
// FIXME(const_evaluatable_checked): We may want to either actually try
// to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like
// this, for now we just return false here.

View file

@ -516,15 +516,13 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
// if the constants depend on generic parameters.
//
// Let's just see where this breaks :shrug:
if let (
ty::ConstKind::Unevaluated(a_def, a_substs, None),
ty::ConstKind::Unevaluated(b_def, b_substs, None),
) = (c1.val, c2.val)
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
(c1.val, c2.val)
{
if self
.selcx
.tcx()
.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs)))
.try_unify_abstract_consts(((a.def, a.substs), (b.def, b.substs)))
{
return ProcessResult::Changed(vec![]);
}
@ -534,7 +532,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
let stalled_on = &mut pending_obligation.stalled_on;
let mut evaluate = |c: &'tcx Const<'tcx>| {
if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
if let ty::ConstKind::Unevaluated(ty::Unevaluated {
def,
substs,
promoted,
}) = c.val
{
match self.selcx.infcx().const_eval_resolve(
obligation.param_env,
def,

View file

@ -556,7 +556,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
debug!(?c1, ?c2, "evaluate_predicate_recursively: equating consts");
let evaluate = |c: &'tcx ty::Const<'tcx>| {
if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
if let ty::ConstKind::Unevaluated(ty::Unevaluated {
def,
substs,
promoted,
}) = c.val
{
self.infcx
.const_eval_resolve(
obligation.param_env,

View file

@ -430,7 +430,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
GenericArgKind::Const(constant) => {
match constant.val {
ty::ConstKind::Unevaluated(def, substs, promoted) => {
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
assert!(promoted.is_none());
let obligations = self.nominal_obligations(def.did, substs);