From 8c7954dc425e8c6ee4aaaf14be5015ad8982d540 Mon Sep 17 00:00:00 2001 From: Ellen Date: Tue, 7 Sep 2021 13:24:04 +0100 Subject: [PATCH] add a `CastKind` to `Node::Cast` --- .../rustc_middle/src/thir/abstract_const.rs | 10 +++++++++- compiler/rustc_privacy/src/lib.rs | 2 +- .../src/traits/const_evaluatable.rs | 17 ++++++++++------- .../src/traits/object_safety.rs | 2 +- .../abstract-consts-as-cast-5.rs | 11 +++++++++++ .../abstract-consts-as-cast-5.stderr | 10 ++++++++++ 6 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs create mode 100644 src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr diff --git a/compiler/rustc_middle/src/thir/abstract_const.rs b/compiler/rustc_middle/src/thir/abstract_const.rs index 00f1390eb4d..f80beadd6e5 100644 --- a/compiler/rustc_middle/src/thir/abstract_const.rs +++ b/compiler/rustc_middle/src/thir/abstract_const.rs @@ -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`. #[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub enum Node<'tcx> { @@ -18,7 +26,7 @@ pub enum Node<'tcx> { Binop(mir::BinOp, NodeId, NodeId), UnaryOp(mir::UnOp, NodeId), FunctionCall(NodeId, &'tcx [NodeId]), - Cast(NodeId, Ty<'tcx>), + Cast(CastKind, NodeId, Ty<'tcx>), } #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 4dcb98ae7e9..391e4305423 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -158,7 +158,7 @@ where let leaf = leaf.subst(tcx, ct.substs); self.visit_const(leaf) } - ACNode::Cast(_, ty) => self.visit_ty(ty), + ACNode::Cast(_, _, ty) => self.visit_ty(ty), ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => { ControlFlow::CONTINUE } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 1845b9d1314..26c71a0f539 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -15,7 +15,7 @@ use rustc_infer::infer::InferCtxt; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; 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::{self, TyCtxt, TypeFoldable}; use rustc_session::lint; @@ -91,7 +91,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( ControlFlow::CONTINUE } - Node::Cast(_, ty) => { + Node::Cast(_, _, ty) => { let ty = ty.subst(tcx, ct.substs); if ty.has_infer_types_or_consts() { failure_kind = FailureKind::MentionsInfer; @@ -368,10 +368,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { // `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a // "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) - &ExprKind::Use { source} - | &ExprKind::Cast { source } => { + &ExprKind::Use { 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. @@ -494,7 +497,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), + 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) .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)) } // use this over `_ => false` to make adding variants to `Node` less error prone diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index e001bb7445e..70cdbe4d5c7 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -843,7 +843,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::Cast(_, _, ty) => self.visit_ty(ty), Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { ControlFlow::CONTINUE } diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs new file mode 100644 index 00000000000..b3cde61f5e7 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs @@ -0,0 +1,11 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +fn foo(a: [(); N as usize]) { + bar::<{ N as usize as usize }>(); + //~^ error: unconstrained generic constant +} + +fn bar() {} + +fn main() {} \ No newline at end of file diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr new file mode 100644 index 00000000000..d48b639dbde --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr @@ -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 +