Skip to content

Commit 81b7e62

Browse files
committed
Prevent pointer -> int casts in constexprs
These cause issues, as addresses aren't fixed at compile-time. Fixes #18294
1 parent a34b8de commit 81b7e62

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

src/librustc/diagnostics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ register_diagnostics!(
3636
E0015,
3737
E0016,
3838
E0017,
39+
E0018,
3940
E0019,
4041
E0020,
4142
E0022,

src/librustc/middle/check_const.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,18 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) -> bool {
119119
}
120120
}
121121
ExprLit(_) => (),
122-
ExprCast(_, _) => {
123-
let ety = ty::expr_ty(v.tcx, e);
124-
if !ty::type_is_numeric(ety) && !ty::type_is_unsafe_ptr(ety) {
122+
ExprCast(ref from, _) => {
123+
let toty = ty::expr_ty(v.tcx, e);
124+
let fromty = ty::expr_ty(v.tcx, &**from);
125+
if !ty::type_is_numeric(toty) && !ty::type_is_unsafe_ptr(toty) {
125126
span_err!(v.tcx.sess, e.span, E0012,
126127
"can not cast to `{}` in a constant expression",
127-
ppaux::ty_to_string(v.tcx, ety));
128+
ppaux::ty_to_string(v.tcx, toty));
129+
}
130+
if ty::type_is_unsafe_ptr(fromty) && ty::type_is_numeric(toty) {
131+
span_err!(v.tcx.sess, e.span, E0018,
132+
"can not cast a pointer to an integer in a constant \
133+
expression");
128134
}
129135
}
130136
ExprPath(ref pth) => {

src/test/compile-fail/issue-18294.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
const X: u32 = 1;
13+
const Y: uint = &X as *const u32 as uint; //~ ERROR E0018
14+
println!("{}", Y);
15+
}

0 commit comments

Comments
 (0)