about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <github35764891676564198441@oli-obk.de>2018-07-02 19:00:07 +0200
committerOliver Schneider <github35764891676564198441@oli-obk.de>2018-08-07 14:41:33 +0200
commit3ef863bfdfb9173a0ad55d24e20202948dda6bbe (patch)
tree88363d22f4c514b1b5ca7f7e086258506096d306
parent9e472c2acea2b7714985390abb6b7fe420a4f346 (diff)
downloadrust-3ef863bfdfb9173a0ad55d24e20202948dda6bbe.tar.gz
rust-3ef863bfdfb9173a0ad55d24e20202948dda6bbe.zip
Place unions, pointer casts and pointer derefs behind extra feature gates
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/librustc_mir/diagnostics.rs55
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs97
-rw-r--r--src/libsyntax/feature_gate.rs9
-rw-r--r--src/test/compile-fail/cast-ptr-to-int-const.rs4
-rw-r--r--src/test/ui/const-deref-ptr.rs3
-rw-r--r--src/test/ui/const-deref-ptr.stderr10
-rw-r--r--src/test/ui/const-eval/const_transmute.rs2
-rw-r--r--src/test/ui/const-eval/promoted_const_fn_fail.rs2
-rw-r--r--src/test/ui/const-eval/ref_to_float_transmute.rs2
-rw-r--r--src/test/ui/const-eval/ref_to_int_match.rs2
-rw-r--r--src/test/ui/const-eval/ref_to_int_match.stderr2
-rw-r--r--src/test/ui/const-eval/union_promotion.nll.stderr11
-rw-r--r--src/test/ui/error-codes/E0396-fixed.rs19
-rw-r--r--src/test/ui/error-codes/E0396-fixed.stderr12
-rw-r--r--src/test/ui/error-codes/E0396.rs3
-rw-r--r--src/test/ui/error-codes/E0396.stderr10
-rw-r--r--src/test/ui/issue-17458.rs2
-rw-r--r--src/test/ui/issue-18294.rs2
-rw-r--r--src/test/ui/union/union-const-eval.rs1
20 files changed, 118 insertions, 131 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 3c751d52b06..e38b8633108 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
@@ -1208,29 +1176,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..025e639d928 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -495,37 +495,41 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
 
                             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
+                                if this.mode != Mode::Fn &&
+                                   !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.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."
-                                        );
-                                        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 => {},
+                                        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
+                                        => {},
                                     }
                                 }
                             }
@@ -723,43 +727,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                     (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 self.mode != Mode::Fn &&
+                           !self.tcx.sess.features_untracked().const_raw_ptr_deref {
+                            emit_feature_err(
+                                &self.tcx.sess.parse_sess, "const_raw_ptr_deref",
+                                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();
                         }
                     }
                     _ => {}
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index a3822a4a1f9..5ae9ae7f404 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -216,6 +216,15 @@ 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 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..30f94e1b5da 100644
--- a/src/test/compile-fail/cast-ptr-to-int-const.rs
+++ b/src/test/compile-fail/cast-ptr-to-int-const.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 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_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/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/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/const-eval/union_promotion.nll.stderr b/src/test/ui/const-eval/union_promotion.nll.stderr
new file mode 100644
index 00000000000..ea95a8b42a4
--- /dev/null
+++ b/src/test/ui/const-eval/union_promotion.nll.stderr
@@ -0,0 +1,11 @@
+error: internal compiler error: unexpected region for local data ReStatic
+  --> $DIR/union_promotion.rs:19:29
+   |
+LL |       let x: &'static bool = &unsafe { //~ borrowed value does not live long enough
+   |  _____________________________^
+LL | |         Foo { a: &1 }.b == Foo { a: &2 }.b
+LL | |     };
+   | |_____^
+
+error: aborting due to previous error
+
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..6434620d26a 100644
--- a/src/test/ui/error-codes/E0396.rs
+++ b/src/test/ui/error-codes/E0396.rs
@@ -10,7 +10,8 @@
 
 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..70331acc0e9 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
+error[E0658]: dereferencing raw pointers in constants is unstable (see issue #51911)
   --> $DIR/E0396.rs:13: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-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/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,