Skip to content

Commit 89ebc6c

Browse files
committed
Rollup merge of rust-lang#55071 - oli-obk:const_cast_🍨, r=RalfJung
Fix ICE and report a human readable error fixes rust-lang#55063 r? @RalfJung
2 parents 1419a69 + 38f3ad4 commit 89ebc6c

File tree

6 files changed

+79
-3
lines changed

6 files changed

+79
-3
lines changed

src/librustc/ty/cast.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ pub enum CastKind {
5858
}
5959

6060
impl<'tcx> CastTy<'tcx> {
61+
/// Returns `Some` for integral/pointer casts.
62+
/// casts like unsizing casts will return `None`
6163
pub fn from_ty(t: Ty<'tcx>) -> Option<CastTy<'tcx>> {
6264
match t.sty {
6365
ty::Bool => Some(CastTy::Int(IntTy::Bool)),

src/librustc_mir/transform/qualify_min_const_fn.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ fn check_rvalue(
148148
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) => {
149149
check_place(tcx, mir, place, span, PlaceMode::Read)
150150
}
151-
Rvalue::Cast(_, operand, cast_ty) => {
151+
Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
152152
use rustc::ty::cast::CastTy;
153153
let cast_in = CastTy::from_ty(operand.ty(mir, tcx)).expect("bad input type for cast");
154154
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
@@ -163,6 +163,16 @@ fn check_rvalue(
163163
_ => check_operand(tcx, mir, operand, span),
164164
}
165165
}
166+
Rvalue::Cast(CastKind::UnsafeFnPointer, _, _) |
167+
Rvalue::Cast(CastKind::ClosureFnPointer, _, _) |
168+
Rvalue::Cast(CastKind::ReifyFnPointer, _, _) => Err((
169+
span,
170+
"function pointer casts are not allowed in const fn".into(),
171+
)),
172+
Rvalue::Cast(CastKind::Unsize, _, _) => Err((
173+
span,
174+
"unsizing casts are not allowed in const fn".into(),
175+
)),
166176
// binops are fine on integers
167177
Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
168178
check_operand(tcx, mir, lhs, span)?;
@@ -177,8 +187,11 @@ fn check_rvalue(
177187
))
178188
}
179189
}
180-
// checked by regular const fn checks
181-
Rvalue::NullaryOp(..) => Ok(()),
190+
Rvalue::NullaryOp(NullOp::SizeOf, _) => Ok(()),
191+
Rvalue::NullaryOp(NullOp::Box, _) => Err((
192+
span,
193+
"heap allocations are not allowed in const fn".into(),
194+
)),
182195
Rvalue::UnaryOp(_, operand) => {
183196
let ty = operand.ty(mir, tcx);
184197
if ty.is_integral() || ty.is_bool() {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const fn foo(a: i32) -> Vec<i32> {
2+
vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn
3+
}
4+
5+
fn main() {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: heap allocations are not allowed in const fn
2+
--> $DIR/bad_const_fn_body_ice.rs:2:5
3+
|
4+
LL | vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn
5+
| ^^^^^^^^^^^^^
6+
|
7+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
8+
9+
error: aborting due to previous error
10+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
fn main() {}
2+
3+
const fn unsize(x: &[u8; 3]) -> &[u8] { x }
4+
//~^ ERROR unsizing casts are not allowed in const fn
5+
const fn closure() -> fn() { || {} }
6+
//~^ ERROR function pointers in const fn are unstable
7+
const fn closure2() {
8+
(|| {}) as fn();
9+
//~^ ERROR function pointers in const fn are unstable
10+
}
11+
const fn reify(f: fn()) -> unsafe fn() { f }
12+
//~^ ERROR function pointers in const fn are unstable
13+
const fn reify2() { main as unsafe fn(); }
14+
//~^ ERROR function pointers in const fn are unstable
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
error: unsizing casts are not allowed in const fn
2+
--> $DIR/cast_errors.rs:3:41
3+
|
4+
LL | const fn unsize(x: &[u8; 3]) -> &[u8] { x }
5+
| ^
6+
7+
error: function pointers in const fn are unstable
8+
--> $DIR/cast_errors.rs:5:23
9+
|
10+
LL | const fn closure() -> fn() { || {} }
11+
| ^^^^
12+
13+
error: function pointers in const fn are unstable
14+
--> $DIR/cast_errors.rs:8:5
15+
|
16+
LL | (|| {}) as fn();
17+
| ^^^^^^^^^^^^^^^
18+
19+
error: function pointers in const fn are unstable
20+
--> $DIR/cast_errors.rs:11:28
21+
|
22+
LL | const fn reify(f: fn()) -> unsafe fn() { f }
23+
| ^^^^^^^^^^^
24+
25+
error: function pointers in const fn are unstable
26+
--> $DIR/cast_errors.rs:13:21
27+
|
28+
LL | const fn reify2() { main as unsafe fn(); }
29+
| ^^^^^^^^^^^^^^^^^^^
30+
31+
error: aborting due to 5 previous errors
32+

0 commit comments

Comments
 (0)