Skip to content

Commit 8c7954d

Browse files
committed
add a CastKind to Node::Cast
1 parent 955e2b2 commit 8c7954d

File tree

6 files changed

+42
-10
lines changed

6 files changed

+42
-10
lines changed

compiler/rustc_middle/src/thir/abstract_const.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,22 @@ rustc_index::newtype_index! {
1111
}
1212
}
1313

14+
#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
15+
pub enum CastKind {
16+
/// thir::ExprKind::As
17+
As,
18+
/// thir::ExprKind::Use
19+
Use,
20+
}
21+
1422
/// A node of an `AbstractConst`.
1523
#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
1624
pub enum Node<'tcx> {
1725
Leaf(&'tcx ty::Const<'tcx>),
1826
Binop(mir::BinOp, NodeId, NodeId),
1927
UnaryOp(mir::UnOp, NodeId),
2028
FunctionCall(NodeId, &'tcx [NodeId]),
21-
Cast(NodeId, Ty<'tcx>),
29+
Cast(CastKind, NodeId, Ty<'tcx>),
2230
}
2331

2432
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]

compiler/rustc_privacy/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ where
158158
let leaf = leaf.subst(tcx, ct.substs);
159159
self.visit_const(leaf)
160160
}
161-
ACNode::Cast(_, ty) => self.visit_ty(ty),
161+
ACNode::Cast(_, _, ty) => self.visit_ty(ty),
162162
ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => {
163163
ControlFlow::CONTINUE
164164
}

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_infer::infer::InferCtxt;
1515
use rustc_middle::mir;
1616
use rustc_middle::mir::interpret::ErrorHandled;
1717
use rustc_middle::thir;
18-
use rustc_middle::thir::abstract_const::{Node, NodeId, NotConstEvaluatable};
18+
use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable};
1919
use rustc_middle::ty::subst::{Subst, SubstsRef};
2020
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
2121
use rustc_session::lint;
@@ -91,7 +91,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
9191

9292
ControlFlow::CONTINUE
9393
}
94-
Node::Cast(_, ty) => {
94+
Node::Cast(_, _, ty) => {
9595
let ty = ty.subst(tcx, ct.substs);
9696
if ty.has_infer_types_or_consts() {
9797
failure_kind = FailureKind::MentionsInfer;
@@ -368,10 +368,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
368368
// `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
369369
// "coercion cast" i.e. using a coercion or is a no-op.
370370
// This is important so that `N as usize as usize` doesnt unify with `N as usize`. (untested)
371-
&ExprKind::Use { source}
372-
| &ExprKind::Cast { source } => {
371+
&ExprKind::Use { source } => {
373372
let arg = self.recurse_build(source)?;
374-
self.nodes.push(Node::Cast(arg, node.ty))
373+
self.nodes.push(Node::Cast(abstract_const::CastKind::Use, arg, node.ty))
374+
},
375+
&ExprKind::Cast { source } => {
376+
let arg = self.recurse_build(source)?;
377+
self.nodes.push(Node::Cast(abstract_const::CastKind::As, arg, node.ty))
375378
},
376379

377380
// FIXME(generic_const_exprs): We may want to support these.
@@ -494,7 +497,7 @@ where
494497
recurse(tcx, ct.subtree(func), f)?;
495498
args.iter().try_for_each(|&arg| recurse(tcx, ct.subtree(arg), f))
496499
}
497-
Node::Cast(operand, _) => recurse(tcx, ct.subtree(operand), f),
500+
Node::Cast(_, operand, _) => recurse(tcx, ct.subtree(operand), f),
498501
}
499502
}
500503

@@ -577,7 +580,7 @@ pub(super) fn try_unify<'tcx>(
577580
&& iter::zip(a_args, b_args)
578581
.all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn)))
579582
}
580-
(Node::Cast(a_operand, a_ty), Node::Cast(b_operand, b_ty)) if (a_ty == b_ty) => {
583+
(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) => {
581584
try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand))
582585
}
583586
// use this over `_ => false` to make adding variants to `Node` less error prone

compiler/rustc_trait_selection/src/traits/object_safety.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
843843
let leaf = leaf.subst(self.tcx, ct.substs);
844844
self.visit_const(leaf)
845845
}
846-
Node::Cast(_, ty) => self.visit_ty(ty),
846+
Node::Cast(_, _, ty) => self.visit_ty(ty),
847847
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
848848
ControlFlow::CONTINUE
849849
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(generic_const_exprs)]
2+
#![allow(incomplete_features)]
3+
4+
fn foo<const N: u8>(a: [(); N as usize]) {
5+
bar::<{ N as usize as usize }>();
6+
//~^ error: unconstrained generic constant
7+
}
8+
9+
fn bar<const N: usize>() {}
10+
11+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: unconstrained generic constant
2+
--> $DIR/abstract-consts-as-cast-5.rs:5:11
3+
|
4+
LL | bar::<{ N as usize as usize }>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= help: try adding a `where` bound using this expression: `where [(); { N as usize as usize }]:`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)