add a CastKind
to Node::Cast
This commit is contained in:
parent
955e2b2da0
commit
8c7954dc42
6 changed files with 42 additions and 10 deletions
|
@ -11,6 +11,14 @@ rustc_index::newtype_index! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||||
|
pub enum CastKind {
|
||||||
|
/// thir::ExprKind::As
|
||||||
|
As,
|
||||||
|
/// thir::ExprKind::Use
|
||||||
|
Use,
|
||||||
|
}
|
||||||
|
|
||||||
/// A node of an `AbstractConst`.
|
/// A node of an `AbstractConst`.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||||
pub enum Node<'tcx> {
|
pub enum Node<'tcx> {
|
||||||
|
@ -18,7 +26,7 @@ pub enum Node<'tcx> {
|
||||||
Binop(mir::BinOp, NodeId, NodeId),
|
Binop(mir::BinOp, NodeId, NodeId),
|
||||||
UnaryOp(mir::UnOp, NodeId),
|
UnaryOp(mir::UnOp, NodeId),
|
||||||
FunctionCall(NodeId, &'tcx [NodeId]),
|
FunctionCall(NodeId, &'tcx [NodeId]),
|
||||||
Cast(NodeId, Ty<'tcx>),
|
Cast(CastKind, NodeId, Ty<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||||
|
|
|
@ -158,7 +158,7 @@ where
|
||||||
let leaf = leaf.subst(tcx, ct.substs);
|
let leaf = leaf.subst(tcx, ct.substs);
|
||||||
self.visit_const(leaf)
|
self.visit_const(leaf)
|
||||||
}
|
}
|
||||||
ACNode::Cast(_, ty) => self.visit_ty(ty),
|
ACNode::Cast(_, _, ty) => self.visit_ty(ty),
|
||||||
ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => {
|
ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => {
|
||||||
ControlFlow::CONTINUE
|
ControlFlow::CONTINUE
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use rustc_infer::infer::InferCtxt;
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::thir;
|
use rustc_middle::thir;
|
||||||
use rustc_middle::thir::abstract_const::{Node, NodeId, NotConstEvaluatable};
|
use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable};
|
||||||
use rustc_middle::ty::subst::{Subst, SubstsRef};
|
use rustc_middle::ty::subst::{Subst, SubstsRef};
|
||||||
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
|
@ -91,7 +91,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
|
|
||||||
ControlFlow::CONTINUE
|
ControlFlow::CONTINUE
|
||||||
}
|
}
|
||||||
Node::Cast(_, ty) => {
|
Node::Cast(_, _, ty) => {
|
||||||
let ty = ty.subst(tcx, ct.substs);
|
let ty = ty.subst(tcx, ct.substs);
|
||||||
if ty.has_infer_types_or_consts() {
|
if ty.has_infer_types_or_consts() {
|
||||||
failure_kind = FailureKind::MentionsInfer;
|
failure_kind = FailureKind::MentionsInfer;
|
||||||
|
@ -368,10 +368,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
// `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
|
// `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
|
||||||
// "coercion cast" i.e. using a coercion or is a no-op.
|
// "coercion cast" i.e. using a coercion or is a no-op.
|
||||||
// This is important so that `N as usize as usize` doesnt unify with `N as usize`. (untested)
|
// This is important so that `N as usize as usize` doesnt unify with `N as usize`. (untested)
|
||||||
&ExprKind::Use { source}
|
&ExprKind::Use { source } => {
|
||||||
| &ExprKind::Cast { source } => {
|
|
||||||
let arg = self.recurse_build(source)?;
|
let arg = self.recurse_build(source)?;
|
||||||
self.nodes.push(Node::Cast(arg, node.ty))
|
self.nodes.push(Node::Cast(abstract_const::CastKind::Use, arg, node.ty))
|
||||||
|
},
|
||||||
|
&ExprKind::Cast { source } => {
|
||||||
|
let arg = self.recurse_build(source)?;
|
||||||
|
self.nodes.push(Node::Cast(abstract_const::CastKind::As, arg, node.ty))
|
||||||
},
|
},
|
||||||
|
|
||||||
// FIXME(generic_const_exprs): We may want to support these.
|
// FIXME(generic_const_exprs): We may want to support these.
|
||||||
|
@ -494,7 +497,7 @@ where
|
||||||
recurse(tcx, ct.subtree(func), f)?;
|
recurse(tcx, ct.subtree(func), f)?;
|
||||||
args.iter().try_for_each(|&arg| recurse(tcx, ct.subtree(arg), f))
|
args.iter().try_for_each(|&arg| recurse(tcx, ct.subtree(arg), f))
|
||||||
}
|
}
|
||||||
Node::Cast(operand, _) => recurse(tcx, ct.subtree(operand), f),
|
Node::Cast(_, operand, _) => recurse(tcx, ct.subtree(operand), f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,7 +580,7 @@ pub(super) fn try_unify<'tcx>(
|
||||||
&& iter::zip(a_args, b_args)
|
&& iter::zip(a_args, b_args)
|
||||||
.all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn)))
|
.all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn)))
|
||||||
}
|
}
|
||||||
(Node::Cast(a_operand, a_ty), Node::Cast(b_operand, b_ty)) if (a_ty == b_ty) => {
|
(Node::Cast(a_kind, a_operand, a_ty), Node::Cast(b_kind, b_operand, b_ty)) if (a_ty == b_ty) && (a_kind == b_kind) => {
|
||||||
try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand))
|
try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand))
|
||||||
}
|
}
|
||||||
// use this over `_ => false` to make adding variants to `Node` less error prone
|
// use this over `_ => false` to make adding variants to `Node` less error prone
|
||||||
|
|
|
@ -843,7 +843,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
||||||
let leaf = leaf.subst(self.tcx, ct.substs);
|
let leaf = leaf.subst(self.tcx, ct.substs);
|
||||||
self.visit_const(leaf)
|
self.visit_const(leaf)
|
||||||
}
|
}
|
||||||
Node::Cast(_, ty) => self.visit_ty(ty),
|
Node::Cast(_, _, ty) => self.visit_ty(ty),
|
||||||
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
|
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
|
||||||
ControlFlow::CONTINUE
|
ControlFlow::CONTINUE
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
fn foo<const N: u8>(a: [(); N as usize]) {
|
||||||
|
bar::<{ N as usize as usize }>();
|
||||||
|
//~^ error: unconstrained generic constant
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar<const N: usize>() {}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,10 @@
|
||||||
|
error: unconstrained generic constant
|
||||||
|
--> $DIR/abstract-consts-as-cast-5.rs:5:11
|
||||||
|
|
|
||||||
|
LL | bar::<{ N as usize as usize }>();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: try adding a `where` bound using this expression: `where [(); { N as usize as usize }]:`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue