diff options
| author | bors <bors@rust-lang.org> | 2018-08-07 13:14:37 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-08-07 13:14:37 +0000 |
| commit | 39e95165323f76042dfab65772a8411dd85fe088 (patch) | |
| tree | fa86b133eeb4f43d7a7b741578332bd117607c0d /src | |
| parent | 18925dee25ce649562d203e72068e3a57b60b153 (diff) | |
| parent | 4b731a908b3df2a926eae5fb5233dbc73b098276 (diff) | |
Auto merge of #51990 - oli-obk:unstable_union, r=nikomatsakis
Place unions, pointer casts and pointer derefs behind extra feature gates
To ensure we don't stabilize these things together with const fn stabilization (or any other stabilization)
This PR moves union field accesses inside `const fn` behind a feature gate. It was possible without a feature gate before, but since `const fn` was behind a feature gate we can do this change.
While "dereferencing raw pointers" and "casting raw pointers to usize" were hard errors before this PR, one could work around them by abusing unions:
```rust
// deref
union Foo<T> {
x: &'static T,
y: *const T,
}
const FOO: u32 = unsafe { *Foo { y: 42 as *const T }.x };
// as usize cast
union Bar<T> {
x: usize,
y: *const T,
}
const BAR: usize = unsafe { Bar { y: &1u8 }.x };
```
r? @eddyb
cc @nikomatsakis
Diffstat (limited to 'src')
35 files changed, 317 insertions, 200 deletions
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a4a01990c22..dc4a2d7c0d7 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -82,6 +82,7 @@ #![feature(concat_idents)] #![feature(const_fn)] #![feature(const_int_ops)] +#![feature(const_fn_union)] #![feature(custom_attribute)] #![feature(doc_cfg)] #![feature(doc_spotlight)] diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 714218a0417..79b7d042dd6 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -619,38 +619,6 @@ If you really want global mutable state, try using `static mut` or a global `UnsafeCell`. "##, -E0018: r##" - -The value of static and constant integers must be known at compile time. You -can't cast a pointer to an integer because the address of a pointer can -vary. - -For example, if you write: - -```compile_fail,E0018 -static MY_STATIC: u32 = 42; -static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize; -static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR; -``` - -Then `MY_STATIC_ADDR` would contain the address of `MY_STATIC`. However, -the address can change when the program is linked, as well as change -between different executions due to ASLR, and many linkers would -not be able to calculate the value of `WHAT`. - -On the other hand, static and constant pointers can point either to -a known numeric address or to the address of a symbol. - -``` -static MY_STATIC: u32 = 42; -static MY_STATIC_ADDR: &'static u32 = &MY_STATIC; -const CONST_ADDR: *const u8 = 0x5f3759df as *const u8; -``` - -This does not pose a problem by itself because they can't be -accessed directly. -"##, - E0019: r##" A function call isn't allowed in the const's initialization expression because the expression's value must be known at compile-time. Erroneous code @@ -1145,36 +1113,6 @@ fn main() { ``` "##, -E0395: r##" -The value assigned to a constant scalar must be known at compile time, -which is not the case when comparing raw pointers. - -Erroneous code example: - -```compile_fail,E0395 -static FOO: i32 = 42; -static BAR: i32 = 42; - -static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; -// error: raw pointers cannot be compared in statics! -``` - -The address assigned by the linker to `FOO` and `BAR` may or may not -be identical, so the value of `BAZ` can't be determined. - -If you want to do the comparison, please do it at run-time. - -For example: - -``` -static FOO: i32 = 42; -static BAR: i32 = 42; - -let baz: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; -// baz isn't a constant expression so it's ok -``` -"##, - E0161: r##" A value was moved. However, its size was not known at compile time, and only values of a known size can be moved. @@ -1208,29 +1146,6 @@ fn main() { ``` "##, -E0396: r##" -The value behind a raw pointer can't be determined at compile-time -(or even link-time), which means it can't be used in a constant -expression. Erroneous code example: - -```compile_fail,E0396 -const REG_ADDR: *const u8 = 0x5f3759df as *const u8; - -const VALUE: u8 = unsafe { *REG_ADDR }; -// error: raw pointers cannot be dereferenced in constants -``` - -A possible fix is to dereference your pointer at some point in run-time. - -For example: - -``` -const REG_ADDR: *const u8 = 0x5f3759df as *const u8; - -let reg_value = unsafe { *REG_ADDR }; -``` -"##, - E0492: r##" A borrow of a constant containing interior mutability was attempted. Erroneous code example: diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 208679d2aa0..d876ee77e76 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -491,41 +491,46 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { this.super_place(place, context, location); match proj.elem { ProjectionElem::Deref => { - this.add(Qualif::NOT_CONST); - - let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); - if let ty::TyRawPtr(_) = base_ty.sty { - if this.mode != Mode::Fn { - let mut err = struct_span_err!( - this.tcx.sess, - this.span, - E0396, - "raw pointers cannot be dereferenced in {}s", - this.mode - ); - err.span_label(this.span, - "dereference of raw pointer in constant"); - if this.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "The value behind a raw pointer can't be determined \ - at compile-time (or even link-time), which means it \ - can't be used in a constant expression." + if let Mode::Fn = this.mode { + this.add(Qualif::NOT_CONST); + } else { + let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); + if let ty::TyRawPtr(_) = base_ty.sty { + if !this.tcx.sess.features_untracked().const_raw_ptr_deref { + emit_feature_err( + &this.tcx.sess.parse_sess, "const_raw_ptr_deref", + this.span, GateIssue::Language, + &format!( + "dereferencing raw pointers in {}s is unstable", + this.mode, + ), ); - err.help("A possible fix is to dereference your pointer \ - at some point in run-time."); } - err.emit(); } } } ProjectionElem::Field(..) | ProjectionElem::Index(_) => { - if this.mode == Mode::Fn { - let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); - if let Some(def) = base_ty.ty_adt_def() { - if def.is_union() { - this.not_const(); + let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); + if let Some(def) = base_ty.ty_adt_def() { + if def.is_union() { + match this.mode { + Mode::Fn => this.not_const(), + Mode::ConstFn => { + if !this.tcx.sess.features_untracked().const_fn_union { + emit_feature_err( + &this.tcx.sess.parse_sess, "const_fn_union", + this.span, GateIssue::Language, + "unions in const fn are unstable", + ); + } + }, + + | Mode::Static + | Mode::StaticMut + | Mode::Const + => {}, } } } @@ -722,44 +727,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { match (cast_in, cast_out) { (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => { - self.add(Qualif::NOT_CONST); - if self.mode != Mode::Fn { - let mut err = struct_span_err!( - self.tcx.sess, - self.span, - E0018, - "raw pointers cannot be cast to integers in {}s", - self.mode + if let Mode::Fn = self.mode { + self.add(Qualif::NOT_CONST); + } else if !self.tcx.sess.features_untracked().const_raw_ptr_to_usize_cast { + emit_feature_err( + &self.tcx.sess.parse_sess, "const_raw_ptr_to_usize_cast", + self.span, GateIssue::Language, + &format!( + "casting pointers to integers in {}s is unstable", + self.mode, + ), ); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note("\ -The value of static and constant integers must be known at compile time. You can't cast a pointer \ -to an integer because the address of a pointer can vary. - -For example, if you write: - -``` -static MY_STATIC: u32 = 42; -static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize; -static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR; -``` - -Then `MY_STATIC_ADDR` would contain the address of `MY_STATIC`. However, the address can change \ -when the program is linked, as well as change between different executions due to ASLR, and many \ -linkers would not be able to calculate the value of `WHAT`. - -On the other hand, static and constant pointers can point either to a known numeric address or to \ -the address of a symbol. - -``` -static MY_STATIC: u32 = 42; -static MY_STATIC_ADDR: &'static u32 = &MY_STATIC; -const CONST_ADDR: *const u8 = 0x5f3759df as *const u8; -``` - -This does not pose a problem by itself because they can't be accessed directly."); - } - err.emit(); } } _ => {} @@ -773,16 +751,16 @@ This does not pose a problem by itself because they can't be accessed directly." op == BinOp::Ge || op == BinOp::Gt || op == BinOp::Offset); - self.add(Qualif::NOT_CONST); - if self.mode != Mode::Fn { - struct_span_err!( - self.tcx.sess, self.span, E0395, - "raw pointers cannot be compared in {}s", - self.mode) - .span_label( + if let Mode::Fn = self.mode { + self.add(Qualif::NOT_CONST); + } else if !self.tcx.sess.features_untracked().const_compare_raw_pointers { + emit_feature_err( + &self.tcx.sess.parse_sess, + "const_compare_raw_pointers", self.span, - "comparing raw pointers in static") - .emit(); + GateIssue::Language, + &format!("comparing raw pointers inside {}", self.mode), + ); } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 3dac7734e91..6d71d276390 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -216,6 +216,18 @@ declare_features! ( // Allows let bindings and destructuring in `const fn` functions and constants. (active, const_let, "1.22.1", Some(48821), None), + // Allows accessing fields of unions inside const fn + (active, const_fn_union, "1.27.0", Some(51909), None), + + // Allows casting raw pointers to `usize` during const eval + (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None), + + // Allows dereferencing raw pointers during const eval + (active, const_raw_ptr_deref, "1.27.0", Some(51911), None), + + // Allows comparing raw pointers during const eval + (active, const_compare_raw_pointers, "1.27.0", Some(53020), None), + // Allows using #[prelude_import] on glob `use` items. // // rustc internal diff --git a/src/test/compile-fail/cast-ptr-to-int-const.rs b/src/test/compile-fail/cast-ptr-to-int-const.rs index 7c32e31d23b..8764cb72b8c 100644 --- a/src/test/compile-fail/cast-ptr-to-int-const.rs +++ b/src/test/compile-fail/cast-ptr-to-int-const.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-const_raw_ptr_to_usize_cast + fn main() { - const X: u32 = main as u32; //~ ERROR E0018 + const X: u32 = main as u32; //~ ERROR casting pointers to integers in constants is unstable const Y: u32 = 0; - const Z: u32 = &Y as *const u32 as u32; //~ ERROR E0018 + const Z: u32 = &Y as *const u32 as u32; //~ ERROR is unstable } diff --git a/src/test/ui/const-deref-ptr.rs b/src/test/ui/const-deref-ptr.rs index fa15f3e87c6..3d0477feb20 100644 --- a/src/test/ui/const-deref-ptr.rs +++ b/src/test/ui/const-deref-ptr.rs @@ -11,6 +11,7 @@ // Check that you can't dereference raw pointers in constants. fn main() { - static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0396 + static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; + //~^ ERROR dereferencing raw pointers in statics is unstable println!("{}", C); } diff --git a/src/test/ui/const-deref-ptr.stderr b/src/test/ui/const-deref-ptr.stderr index 61db58104d2..94a383bcf16 100644 --- a/src/test/ui/const-deref-ptr.stderr +++ b/src/test/ui/const-deref-ptr.stderr @@ -1,9 +1,11 @@ -error[E0396]: raw pointers cannot be dereferenced in statics +error[E0658]: dereferencing raw pointers in statics is unstable (see issue #51911) --> $DIR/const-deref-ptr.rs:14:29 | -LL | static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0396 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer in constant +LL | static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0396`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/const-eval/const_raw_ptr_ops.rs b/src/test/ui/const-eval/const_raw_ptr_ops.rs new file mode 100644 index 00000000000..2aff6a7c55c --- /dev/null +++ b/src/test/ui/const-eval/const_raw_ptr_ops.rs @@ -0,0 +1,27 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_raw_ptr_to_usize_cast, const_compare_raw_pointers, const_raw_ptr_deref)] + +fn main() {} + +// unconst and bad, will thus error in miri +const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR cannot be used +// unconst and fine +const X2: bool = 42 as *const i32 == 43 as *const i32; +// unconst and fine +const Y: usize = 42usize as *const i32 as usize + 1; +// unconst and bad, will thus error in miri +const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR cannot be used +// unconst and fine +const Z: i32 = unsafe { *(&1 as *const i32) }; +// unconst and bad, will thus error in miri +const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR cannot be used +const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR cannot be used diff --git a/src/test/ui/const-eval/const_raw_ptr_ops.stderr b/src/test/ui/const-eval/const_raw_ptr_ops.stderr new file mode 100644 index 00000000000..a9442be081d --- /dev/null +++ b/src/test/ui/const-eval/const_raw_ptr_ops.stderr @@ -0,0 +1,36 @@ +error: this constant cannot be used + --> $DIR/const_raw_ptr_ops.rs:16:1 + | +LL | const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR cannot be used + | ^^^^^^^^^^^^^^^^------------------------------------^ + | | + | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants + | + = note: #[deny(const_err)] on by default + +error: this constant cannot be used + --> $DIR/const_raw_ptr_ops.rs:22:1 + | +LL | const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR cannot be used + | ^^^^^^^^^^^^^^^^^^-----------------------------^ + | | + | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants + +error: this constant cannot be used + --> $DIR/const_raw_ptr_ops.rs:26:1 + | +LL | const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR cannot be used + | ^^^^^^^^^^^^^^^^^^^^^^^^^-------------------^^^ + | | + | tried to access memory with alignment 2, but alignment 4 is required + +error: this constant cannot be used + --> $DIR/const_raw_ptr_ops.rs:27:1 + | +LL | const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR cannot be used + | ^^^^^^^^^^^^^^^^^^^^^^^^^-------------------^^^ + | | + | a memory access tried to interpret some bytes as a pointer + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/const-eval/const_transmute.rs b/src/test/ui/const-eval/const_transmute.rs index e661444a7b4..8dd1476d25a 100644 --- a/src/test/ui/const-eval/const_transmute.rs +++ b/src/test/ui/const-eval/const_transmute.rs @@ -11,6 +11,8 @@ // compile-pass // run-pass +#![feature(const_fn_union)] + union Transmute<T: Copy, U: Copy> { t: T, u: U, diff --git a/src/test/ui/const-eval/feature-gate-const_fn_union.rs b/src/test/ui/const-eval/feature-gate-const_fn_union.rs new file mode 100644 index 00000000000..113046b0689 --- /dev/null +++ b/src/test/ui/const-eval/feature-gate-const_fn_union.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_fn)] + +fn main() {} + +union Foo { + u: u32, + i: i32, +} + +const unsafe fn foo(u: u32) -> i32 { + Foo { u }.i //~ ERROR unions in const fn are unstable +} diff --git a/src/test/ui/const-eval/feature-gate-const_fn_union.stderr b/src/test/ui/const-eval/feature-gate-const_fn_union.stderr new file mode 100644 index 00000000000..1e28f14165f --- /dev/null +++ b/src/test/ui/const-eval/feature-gate-const_fn_union.stderr @@ -0,0 +1,11 @@ +error[E0658]: unions in const fn are unstable (see issue #51909) + --> $DIR/feature-gate-const_fn_union.rs:21:5 + | +LL | Foo { u }.i //~ ERROR unions in const fn are unstable + | ^^^^^^^^^^^ + | + = help: add #![feature(const_fn_union)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/const-eval/match-test-ptr-null.rs b/src/test/ui/const-eval/match-test-ptr-null.rs index 19b3dcc3181..81fcd23fb78 100644 --- a/src/test/ui/const-eval/match-test-ptr-null.rs +++ b/src/test/ui/const-eval/match-test-ptr-null.rs @@ -13,7 +13,7 @@ fn main() { // that pointer comparison is disallowed, not that parts of a pointer are accessed as raw // bytes. let _: [u8; 0] = [4; { //~ ERROR could not evaluate repeat length - match &1 as *const i32 as usize { //~ ERROR raw pointers cannot be cast to integers + match &1 as *const i32 as usize { //~ ERROR casting pointers to integers in constants 0 => 42, //~ ERROR constant contains unimplemented expression type //~^ NOTE "pointer arithmetic or comparison" needs an rfc before being allowed n => n, diff --git a/src/test/ui/const-eval/match-test-ptr-null.stderr b/src/test/ui/const-eval/match-test-ptr-null.stderr index 726ada9b428..26577948fae 100644 --- a/src/test/ui/const-eval/match-test-ptr-null.stderr +++ b/src/test/ui/const-eval/match-test-ptr-null.stderr @@ -1,8 +1,10 @@ -error[E0018]: raw pointers cannot be cast to integers in constants +error[E0658]: casting pointers to integers in constants is unstable (see issue #51910) --> $DIR/match-test-ptr-null.rs:16:15 | -LL | match &1 as *const i32 as usize { //~ ERROR raw pointers cannot be cast to integers +LL | match &1 as *const i32 as usize { //~ ERROR casting pointers to integers in constants | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable error[E0019]: constant contains unimplemented expression type --> $DIR/match-test-ptr-null.rs:17:13 @@ -15,7 +17,7 @@ error[E0080]: could not evaluate repeat length | LL | let _: [u8; 0] = [4; { //~ ERROR could not evaluate repeat length | __________________________^ -LL | | match &1 as *const i32 as usize { //~ ERROR raw pointers cannot be cast to integers +LL | | match &1 as *const i32 as usize { //~ ERROR casting pointers to integers in constants LL | | 0 => 42, //~ ERROR constant contains unimplemented expression type | | - "pointer arithmetic or comparison" needs an rfc before being allowed inside constants LL | | //~^ NOTE "pointer arithmetic or comparison" needs an rfc before being allowed @@ -26,5 +28,5 @@ LL | | }]; error: aborting due to 3 previous errors -Some errors occurred: E0018, E0019, E0080. -For more information about an error, try `rustc --explain E0018`. +Some errors occurred: E0019, E0080, E0658. +For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/const-eval/promoted_const_fn_fail.rs b/src/test/ui/const-eval/promoted_const_fn_fail.rs index f0f35ce614e..19db07dd330 100644 --- a/src/test/ui/const-eval/promoted_const_fn_fail.rs +++ b/src/test/ui/const-eval/promoted_const_fn_fail.rs @@ -10,7 +10,7 @@ // compile-pass -#![feature(const_fn)] +#![feature(const_fn, const_fn_union)] #![deny(const_err)] diff --git a/src/test/ui/const-eval/promoted_raw_ptr_ops.rs b/src/test/ui/const-eval/promoted_raw_ptr_ops.rs new file mode 100644 index 00000000000..3b437f69d8d --- /dev/null +++ b/src/test/ui/const-eval/promoted_raw_ptr_ops.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_raw_ptr_to_usize_cast, const_compare_raw_pointers, const_raw_ptr_deref)] + +fn main() { + let x: &'static bool = &(42 as *const i32 == 43 as *const i32); + //~^ ERROR does not live long enough + let y: &'static usize = &(&1 as *const i32 as usize + 1); //~ ERROR does not live long enough + let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough +} diff --git a/src/test/ui/const-eval/promoted_raw_ptr_ops.stderr b/src/test/ui/const-eval/promoted_raw_ptr_ops.stderr new file mode 100644 index 00000000000..90c73c095fb --- /dev/null +++ b/src/test/ui/const-eval/promoted_raw_ptr_ops.stderr @@ -0,0 +1,35 @@ +error[E0597]: borrowed value does not live long enough + --> $DIR/promoted_raw_ptr_ops.rs:14:29 + | +LL | let x: &'static bool = &(42 as *const i32 == 43 as *const i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough +... +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error[E0597]: borrowed value does not live long enough + --> $DIR/promoted_raw_ptr_ops.rs:16:30 + | +LL | let y: &'static usize = &(&1 as *const i32 as usize + 1); //~ ERROR does not live long enough + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough +LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error[E0597]: borrowed value does not live long enough + --> $DIR/promoted_raw_ptr_ops.rs:17:28 + | +LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/const-eval/ref_to_float_transmute.rs b/src/test/ui/const-eval/ref_to_float_transmute.rs index 77d5222cb9c..1758ac72b63 100644 --- a/src/test/ui/const-eval/ref_to_float_transmute.rs +++ b/src/test/ui/const-eval/ref_to_float_transmute.rs @@ -10,6 +10,8 @@ //compile-pass +#![feature(const_fn_union)] + fn main() {} static FOO: u32 = 42; diff --git a/src/test/ui/const-eval/ref_to_int_match.rs b/src/test/ui/const-eval/ref_to_int_match.rs index 8ad7f11f0ce..cb942f465e4 100644 --- a/src/test/ui/const-eval/ref_to_int_match.rs +++ b/src/test/ui/const-eval/ref_to_int_match.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(const_fn_union)] + fn main() { let n: Int = 40; match n { diff --git a/src/test/ui/const-eval/ref_to_int_match.stderr b/src/test/ui/const-eval/ref_to_int_match.stderr index 64ea57702d7..e82a16c066f 100644 --- a/src/test/ui/const-eval/ref_to_int_match.stderr +++ b/src/test/ui/const-eval/ref_to_int_match.stderr @@ -1,5 +1,5 @@ error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/ref_to_int_match.rs:15:9 + --> $DIR/ref_to_int_match.rs:17:9 | LL | 10..=BAR => {}, //~ ERROR lower range bound must be less than or equal to upper | ^^ lower bound larger than upper bound diff --git a/src/test/ui/error-codes/E0395.rs b/src/test/ui/error-codes/E0395.rs index 00008ea6b6f..617050732b7 100644 --- a/src/test/ui/error-codes/E0395.rs +++ b/src/test/ui/error-codes/E0395.rs @@ -8,9 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-const_compare_raw_pointers + static FOO: i32 = 42; static BAR: i32 = 42; -static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR E0395 +static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020 fn main() { } diff --git a/src/test/ui/error-codes/E0395.stderr b/src/test/ui/error-codes/E0395.stderr index ee90df79870..0fb9a9e854d 100644 --- a/src/test/ui/error-codes/E0395.stderr +++ b/src/test/ui/error-codes/E0395.stderr @@ -1,9 +1,11 @@ -error[E0395]: raw pointers cannot be compared in statics - --> $DIR/E0395.rs:14:22 +error[E0658]: comparing raw pointers inside static (see issue #53020) + --> $DIR/E0395.rs:16:22 | -LL | static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR E0395 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comparing raw pointers in static +LL | static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0395`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/error-codes/E0396-fixed.rs b/src/test/ui/error-codes/E0396-fixed.rs new file mode 100644 index 00000000000..08d20e7850d --- /dev/null +++ b/src/test/ui/error-codes/E0396-fixed.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_raw_ptr_deref)] + +const REG_ADDR: *const u8 = 0x5f3759df as *const u8; + +const VALUE: u8 = unsafe { *REG_ADDR }; +//~^ ERROR this constant cannot be used + +fn main() { +} diff --git a/src/test/ui/error-codes/E0396-fixed.stderr b/src/test/ui/error-codes/E0396-fixed.stderr new file mode 100644 index 00000000000..7d3c98c8ea8 --- /dev/null +++ b/src/test/ui/error-codes/E0396-fixed.stderr @@ -0,0 +1,12 @@ +error: this constant cannot be used + --> $DIR/E0396-fixed.rs:15:1 + | +LL | const VALUE: u8 = unsafe { *REG_ADDR }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^^^ + | | + | a memory access tried to interpret some bytes as a pointer + | + = note: #[deny(const_err)] on by default + +error: aborting due to previous error + diff --git a/src/test/ui/error-codes/E0396.rs b/src/test/ui/error-codes/E0396.rs index 7f34acdfb90..1ee8a74a465 100644 --- a/src/test/ui/error-codes/E0396.rs +++ b/src/test/ui/error-codes/E0396.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-const_raw_ptr_deref + const REG_ADDR: *const u8 = 0x5f3759df as *const u8; -const VALUE: u8 = unsafe { *REG_ADDR }; //~ ERROR E0396 +const VALUE: u8 = unsafe { *REG_ADDR }; +//~^ ERROR dereferencing raw pointers in constants is unstable fn main() { } diff --git a/src/test/ui/error-codes/E0396.stderr b/src/test/ui/error-codes/E0396.stderr index 87dfd50dc97..a2a2e724358 100644 --- a/src/test/ui/error-codes/E0396.stderr +++ b/src/test/ui/error-codes/E0396.stderr @@ -1,9 +1,11 @@ -error[E0396]: raw pointers cannot be dereferenced in constants - --> $DIR/E0396.rs:13:28 +error[E0658]: dereferencing raw pointers in constants is unstable (see issue #51911) + --> $DIR/E0396.rs:15:28 | -LL | const VALUE: u8 = unsafe { *REG_ADDR }; //~ ERROR E0396 - | ^^^^^^^^^ dereference of raw pointer in constant +LL | const VALUE: u8 = unsafe { *REG_ADDR }; + | ^^^^^^^^^ + | + = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0396`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issue-17458.rs b/src/test/ui/issue-17458.rs index f5b7a0c13b7..354d389158d 100644 --- a/src/test/ui/issue-17458.rs +++ b/src/test/ui/issue-17458.rs @@ -9,7 +9,7 @@ // except according to those terms. static X: usize = 0 as *const usize as usize; -//~^ ERROR: raw pointers cannot be cast to integers in statics +//~^ ERROR: casting pointers to integers in statics is unstable fn main() { assert_eq!(X, 0); diff --git a/src/test/ui/issue-17458.stderr b/src/test/ui/issue-17458.stderr index 7a43813fa6d..0303e4bddb5 100644 --- a/src/test/ui/issue-17458.stderr +++ b/src/test/ui/issue-17458.stderr @@ -1,9 +1,11 @@ -error[E0018]: raw pointers cannot be cast to integers in statics +error[E0658]: casting pointers to integers in statics is unstable (see issue #51910) --> $DIR/issue-17458.rs:11:19 | LL | static X: usize = 0 as *const usize as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0018`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issue-18294.rs b/src/test/ui/issue-18294.rs index efc1ba1635c..28dc6846f69 100644 --- a/src/test/ui/issue-18294.rs +++ b/src/test/ui/issue-18294.rs @@ -10,6 +10,6 @@ fn main() { const X: u32 = 1; - const Y: usize = &X as *const u32 as usize; //~ ERROR E0018 + const Y: usize = &X as *const u32 as usize; //~ ERROR is unstable println!("{}", Y); } diff --git a/src/test/ui/issue-18294.stderr b/src/test/ui/issue-18294.stderr index 151deefb2b7..0b94e778d37 100644 --- a/src/test/ui/issue-18294.stderr +++ b/src/test/ui/issue-18294.stderr @@ -1,9 +1,11 @@ -error[E0018]: raw pointers cannot be cast to integers in constants +error[E0658]: casting pointers to integers in constants is unstable (see issue #51910) --> $DIR/issue-18294.rs:13:22 | -LL | const Y: usize = &X as *const u32 as usize; //~ ERROR E0018 +LL | const Y: usize = &X as *const u32 as usize; //~ ERROR is unstable | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0018`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issue-25826.rs b/src/test/ui/issue-25826.rs index 00e1279d58a..6b9caba0218 100644 --- a/src/test/ui/issue-25826.rs +++ b/src/test/ui/issue-25826.rs @@ -11,6 +11,6 @@ fn id<T>(t: T) -> T { t } fn main() { const A: bool = id::<u8> as *const () < id::<u16> as *const (); - //~^ ERROR raw pointers cannot be compared in constants [E0395] + //~^ ERROR comparing raw pointers inside constant println!("{}", A); } diff --git a/src/test/ui/issue-25826.stderr b/src/test/ui/issue-25826.stderr index fed9e8efa84..a5ab7cfa6d3 100644 --- a/src/test/ui/issue-25826.stderr +++ b/src/test/ui/issue-25826.stderr @@ -1,9 +1,11 @@ -error[E0395]: raw pointers cannot be compared in constants +error[E0658]: comparing raw pointers inside constant (see issue #53020) --> $DIR/issue-25826.rs:13:21 | LL | const A: bool = id::<u8> as *const () < id::<u16> as *const (); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comparing raw pointers in static + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0395`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issue-52023-array-size-pointer-cast.rs b/src/test/ui/issue-52023-array-size-pointer-cast.rs index f3bee1a6315..02bed69f0d4 100644 --- a/src/test/ui/issue-52023-array-size-pointer-cast.rs +++ b/src/test/ui/issue-52023-array-size-pointer-cast.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let _ = [0; (&0 as *const i32) as usize]; //~ ERROR raw pointers cannot be cast + let _ = [0; (&0 as *const i32) as usize]; //~ ERROR casting pointers to integers in constants } diff --git a/src/test/ui/issue-52023-array-size-pointer-cast.stderr b/src/test/ui/issue-52023-array-size-pointer-cast.stderr index 888de82e379..74270c2bef7 100644 --- a/src/test/ui/issue-52023-array-size-pointer-cast.stderr +++ b/src/test/ui/issue-52023-array-size-pointer-cast.stderr @@ -1,9 +1,11 @@ -error[E0018]: raw pointers cannot be cast to integers in constants +error[E0658]: casting pointers to integers in constants is unstable (see issue #51910) --> $DIR/issue-52023-array-size-pointer-cast.rs:12:17 | -LL | let _ = [0; (&0 as *const i32) as usize]; //~ ERROR raw pointers cannot be cast +LL | let _ = [0; (&0 as *const i32) as usize]; //~ ERROR casting pointers to integers in constants | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0018`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/union/union-const-eval.rs b/src/test/ui/union/union-const-eval.rs index 3ae76e1a82a..c640acec05e 100644 --- a/src/test/ui/union/union-const-eval.rs +++ b/src/test/ui/union/union-const-eval.rs @@ -9,6 +9,7 @@ // except according to those terms. // compile-pass +#![feature(const_fn_union)] union U { a: usize, |
