Rollup merge of #55071 - oli-obk:const_cast_🍨, r=RalfJung
Fix ICE and report a human readable error fixes #55063 r? @RalfJung
This commit is contained in:
commit
89ebc6ce4f
6 changed files with 79 additions and 3 deletions
|
|
@ -58,6 +58,8 @@ pub enum CastKind {
|
|||
}
|
||||
|
||||
impl<'tcx> CastTy<'tcx> {
|
||||
/// Returns `Some` for integral/pointer casts.
|
||||
/// casts like unsizing casts will return `None`
|
||||
pub fn from_ty(t: Ty<'tcx>) -> Option<CastTy<'tcx>> {
|
||||
match t.sty {
|
||||
ty::Bool => Some(CastTy::Int(IntTy::Bool)),
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ fn check_rvalue(
|
|||
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) => {
|
||||
check_place(tcx, mir, place, span, PlaceMode::Read)
|
||||
}
|
||||
Rvalue::Cast(_, operand, cast_ty) => {
|
||||
Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
|
||||
use rustc::ty::cast::CastTy;
|
||||
let cast_in = CastTy::from_ty(operand.ty(mir, tcx)).expect("bad input type for cast");
|
||||
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
|
|
@ -163,6 +163,16 @@ fn check_rvalue(
|
|||
_ => check_operand(tcx, mir, operand, span),
|
||||
}
|
||||
}
|
||||
Rvalue::Cast(CastKind::UnsafeFnPointer, _, _) |
|
||||
Rvalue::Cast(CastKind::ClosureFnPointer, _, _) |
|
||||
Rvalue::Cast(CastKind::ReifyFnPointer, _, _) => Err((
|
||||
span,
|
||||
"function pointer casts are not allowed in const fn".into(),
|
||||
)),
|
||||
Rvalue::Cast(CastKind::Unsize, _, _) => Err((
|
||||
span,
|
||||
"unsizing casts are not allowed in const fn".into(),
|
||||
)),
|
||||
// binops are fine on integers
|
||||
Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
|
||||
check_operand(tcx, mir, lhs, span)?;
|
||||
|
|
@ -177,8 +187,11 @@ fn check_rvalue(
|
|||
))
|
||||
}
|
||||
}
|
||||
// checked by regular const fn checks
|
||||
Rvalue::NullaryOp(..) => Ok(()),
|
||||
Rvalue::NullaryOp(NullOp::SizeOf, _) => Ok(()),
|
||||
Rvalue::NullaryOp(NullOp::Box, _) => Err((
|
||||
span,
|
||||
"heap allocations are not allowed in const fn".into(),
|
||||
)),
|
||||
Rvalue::UnaryOp(_, operand) => {
|
||||
let ty = operand.ty(mir, tcx);
|
||||
if ty.is_integral() || ty.is_bool() {
|
||||
|
|
|
|||
5
src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs
Normal file
5
src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
const fn foo(a: i32) -> Vec<i32> {
|
||||
vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
10
src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
Normal file
10
src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
error: heap allocations are not allowed in const fn
|
||||
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
||||
|
|
||||
LL | vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
14
src/test/ui/consts/min_const_fn/cast_errors.rs
Normal file
14
src/test/ui/consts/min_const_fn/cast_errors.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
fn main() {}
|
||||
|
||||
const fn unsize(x: &[u8; 3]) -> &[u8] { x }
|
||||
//~^ ERROR unsizing casts are not allowed in const fn
|
||||
const fn closure() -> fn() { || {} }
|
||||
//~^ ERROR function pointers in const fn are unstable
|
||||
const fn closure2() {
|
||||
(|| {}) as fn();
|
||||
//~^ ERROR function pointers in const fn are unstable
|
||||
}
|
||||
const fn reify(f: fn()) -> unsafe fn() { f }
|
||||
//~^ ERROR function pointers in const fn are unstable
|
||||
const fn reify2() { main as unsafe fn(); }
|
||||
//~^ ERROR function pointers in const fn are unstable
|
||||
32
src/test/ui/consts/min_const_fn/cast_errors.stderr
Normal file
32
src/test/ui/consts/min_const_fn/cast_errors.stderr
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
error: unsizing casts are not allowed in const fn
|
||||
--> $DIR/cast_errors.rs:3:41
|
||||
|
|
||||
LL | const fn unsize(x: &[u8; 3]) -> &[u8] { x }
|
||||
| ^
|
||||
|
||||
error: function pointers in const fn are unstable
|
||||
--> $DIR/cast_errors.rs:5:23
|
||||
|
|
||||
LL | const fn closure() -> fn() { || {} }
|
||||
| ^^^^
|
||||
|
||||
error: function pointers in const fn are unstable
|
||||
--> $DIR/cast_errors.rs:8:5
|
||||
|
|
||||
LL | (|| {}) as fn();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: function pointers in const fn are unstable
|
||||
--> $DIR/cast_errors.rs:11:28
|
||||
|
|
||||
LL | const fn reify(f: fn()) -> unsafe fn() { f }
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: function pointers in const fn are unstable
|
||||
--> $DIR/cast_errors.rs:13:21
|
||||
|
|
||||
LL | const fn reify2() { main as unsafe fn(); }
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue