1
Fork 0

Auto merge of #86130 - BoxyUwU:abstract_const_as_cast, r=oli-obk

const_eval_checked: Support as casts in abstract consts
This commit is contained in:
bors 2021-06-12 08:50:22 +00:00
commit d59b80d588
10 changed files with 313 additions and 3 deletions

View file

@ -97,6 +97,16 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
ControlFlow::CONTINUE
}
Node::Cast(_, _, ty) => {
let ty = ty.subst(tcx, ct.substs);
if ty.has_infer_types_or_consts() {
failure_kind = FailureKind::MentionsInfer;
} else if ty.has_param_types_or_consts() {
failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam);
}
ControlFlow::CONTINUE
}
Node::Binop(_, _, _) | Node::UnaryOp(_, _) | Node::FunctionCall(_, _) => {
ControlFlow::CONTINUE
}
@ -304,6 +314,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
self.nodes[func].used = true;
nodes.iter().for_each(|&n| self.nodes[n].used = true);
}
Node::Cast(_, operand, _) => {
self.nodes[operand].used = true;
}
}
// Nodes start as unused.
@ -408,11 +421,19 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
self.locals[local] = self.add_node(Node::UnaryOp(op, operand), span);
Ok(())
}
Rvalue::Cast(cast_kind, ref operand, ty) => {
let operand = self.operand_to_node(span, operand)?;
self.locals[local] =
self.add_node(Node::Cast(cast_kind, operand, ty), span);
Ok(())
}
_ => self.error(Some(span), "unsupported rvalue")?,
}
}
// These are not actually relevant for us here, so we can ignore them.
StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => Ok(()),
StatementKind::AscribeUserType(..)
| StatementKind::StorageLive(_)
| StatementKind::StorageDead(_) => Ok(()),
_ => self.error(Some(stmt.source_info.span), "unsupported statement")?,
}
}
@ -594,6 +615,7 @@ where
recurse(tcx, ct.subtree(func), f)?;
args.iter().try_for_each(|&arg| recurse(tcx, ct.subtree(arg), f))
}
Node::Cast(_, operand, _) => recurse(tcx, ct.subtree(operand), f),
}
}
@ -676,6 +698,11 @@ pub(super) fn try_unify<'tcx>(
&& iter::zip(a_args, b_args)
.all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn)))
}
(Node::Cast(a_cast_kind, a_operand, a_ty), Node::Cast(b_cast_kind, b_operand, b_ty))
if (a_ty == b_ty) && (a_cast_kind == b_cast_kind) =>
{
try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand))
}
_ => false,
}
}

View file

@ -838,6 +838,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
let leaf = leaf.subst(self.tcx, ct.substs);
self.visit_const(leaf)
}
Node::Cast(_, _, ty) => self.visit_ty(ty),
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
ControlFlow::CONTINUE
}
@ -859,6 +860,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
let leaf = leaf.subst(self.tcx, ct.substs);
self.visit_const(leaf)
}
Node::Cast(_, _, ty) => self.visit_ty(ty),
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
ControlFlow::CONTINUE
}