about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2018-12-07 18:26:46 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2019-01-21 16:01:57 +0100
commitaedc3a51dfab0fa7205f1c0fd68a4e62dd6df712 (patch)
tree1e67a7725f854bc7c4c099f2d7e09d7dfba146c9 /src
parent64afc6b51779c32b3d68a45b956b76b8899a135e (diff)
downloadrust-aedc3a51dfab0fa7205f1c0fd68a4e62dd6df712.tar.gz
rust-aedc3a51dfab0fa7205f1c0fd68a4e62dd6df712.zip
Declare some unconst operations as unsafe in const fn
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs97
-rw-r--r--src/test/ui/cast/cast-ptr-to-int-const.rs8
-rw-r--r--src/test/ui/cast/cast-ptr-to-int-const.stderr12
-rw-r--r--src/test/ui/consts/const-eval/const_raw_ptr_ops.rs8
-rw-r--r--src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr16
-rw-r--r--src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs2
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr52
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.rs8
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.stderr50
-rw-r--r--src/test/ui/error-codes/E0395.rs2
-rw-r--r--src/test/ui/error-codes/E0395.stderr6
-rw-r--r--src/test/ui/issues/issue-17458.rs2
-rw-r--r--src/test/ui/issues/issue-17458.stderr6
-rw-r--r--src/test/ui/issues/issue-18294.rs2
-rw-r--r--src/test/ui/issues/issue-18294.stderr6
-rw-r--r--src/test/ui/issues/issue-25826.rs2
-rw-r--r--src/test/ui/issues/issue-25826.stderr6
17 files changed, 187 insertions, 98 deletions
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index eb151b56bed..ab8da2f352c 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -4,6 +4,7 @@ use rustc_data_structures::sync::Lrc;
 
 use rustc::ty::query::Providers;
 use rustc::ty::{self, TyCtxt};
+use rustc::ty::cast::CastTy;
 use rustc::hir;
 use rustc::hir::Node;
 use rustc::hir::def_id::DefId;
@@ -20,6 +21,7 @@ use util;
 
 pub struct UnsafetyChecker<'a, 'tcx: 'a> {
     mir: &'a Mir<'tcx>,
+    const_context: bool,
     min_const_fn: bool,
     source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
     violations: Vec<UnsafetyViolation>,
@@ -33,14 +35,20 @@ pub struct UnsafetyChecker<'a, 'tcx: 'a> {
 
 impl<'a, 'gcx, 'tcx> UnsafetyChecker<'a, 'tcx> {
     fn new(
+        const_context: bool,
         min_const_fn: bool,
         mir: &'a Mir<'tcx>,
         source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> Self {
+        // sanity check
+        if min_const_fn {
+            assert!(const_context);
+        }
         Self {
             mir,
+            const_context,
             min_const_fn,
             source_scope_local_data,
             violations: vec![],
@@ -124,29 +132,70 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                     rvalue: &Rvalue<'tcx>,
                     location: Location)
     {
-        if let &Rvalue::Aggregate(box ref aggregate, _) = rvalue {
-            match aggregate {
-                &AggregateKind::Array(..) |
-                &AggregateKind::Tuple => {}
-                &AggregateKind::Adt(ref def, ..) => {
-                    match self.tcx.layout_scalar_valid_range(def.did) {
-                        (Bound::Unbounded, Bound::Unbounded) => {},
-                        _ => self.require_unsafe(
-                            "initializing type with `rustc_layout_scalar_valid_range` attr",
-                            "initializing a layout restricted type's field with a value outside \
-                            the valid range is undefined behavior",
-                            UnsafetyViolationKind::GeneralAndConstFn,
-                        ),
+        match rvalue {
+            Rvalue::Aggregate(box ref aggregate, _) => {
+                match aggregate {
+                    &AggregateKind::Array(..) |
+                    &AggregateKind::Tuple => {}
+                    &AggregateKind::Adt(ref def, ..) => {
+                        match self.tcx.layout_scalar_valid_range(def.did) {
+                            (Bound::Unbounded, Bound::Unbounded) => {},
+                            _ => self.require_unsafe(
+                                "initializing type with `rustc_layout_scalar_valid_range` attr",
+                                "initializing a layout restricted type's field with a value \
+                                outside the valid range is undefined behavior",
+                                UnsafetyViolationKind::GeneralAndConstFn,
+                            ),
+                        }
+                    }
+                    &AggregateKind::Closure(def_id, _) |
+                    &AggregateKind::Generator(def_id, _, _) => {
+                        let UnsafetyCheckResult {
+                            violations, unsafe_blocks
+                        } = self.tcx.unsafety_check_result(def_id);
+                        self.register_violations(&violations, &unsafe_blocks);
                     }
                 }
-                &AggregateKind::Closure(def_id, _) |
-                &AggregateKind::Generator(def_id, _, _) => {
-                    let UnsafetyCheckResult {
-                        violations, unsafe_blocks
-                    } = self.tcx.unsafety_check_result(def_id);
-                    self.register_violations(&violations, &unsafe_blocks);
+            },
+            // casting pointers to ints is unsafe in const fn because the const evaluator cannot
+            // possibly know what the result of various operations like `address / 2` would be
+            // pointers during const evaluation have no integral address, only an abstract one
+            Rvalue::Cast(CastKind::Misc, ref operand, cast_ty)
+            if self.const_context && self.tcx.features().const_raw_ptr_to_usize_cast => {
+                let operand_ty = operand.ty(self.mir, self.tcx);
+                let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
+                let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
+                match (cast_in, cast_out) {
+                    (CastTy::Ptr(_), CastTy::Int(_)) |
+                    (CastTy::FnPtr, CastTy::Int(_)) => {
+                        self.register_violations(&[UnsafetyViolation {
+                            source_info: self.source_info,
+                            description: Symbol::intern("cast of pointer to int").as_interned_str(),
+                            details: Symbol::intern("casting pointers to integers in constants")
+                                     .as_interned_str(),
+                            kind: UnsafetyViolationKind::General,
+                        }], &[]);
+                    },
+                    _ => {},
                 }
             }
+            // raw pointer and fn pointer operations are unsafe as it is not clear whether one
+            // pointer would be "less" or "equal" to another, because we cannot know where llvm
+            // or the linker will place various statics in memory. Without this information the
+            // result of a comparison of addresses would differ between runtime and compile-time.
+            Rvalue::BinaryOp(_, ref lhs, _)
+            if self.const_context && self.tcx.features().const_compare_raw_pointers => {
+                if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.mir, self.tcx).sty {
+                    self.register_violations(&[UnsafetyViolation {
+                        source_info: self.source_info,
+                        description: Symbol::intern("pointer operation").as_interned_str(),
+                        details: Symbol::intern("operations on pointers in constants")
+                                 .as_interned_str(),
+                        kind: UnsafetyViolationKind::General,
+                    }], &[]);
+                }
+            }
+            _ => {},
         }
         self.super_rvalue(rvalue, location);
     }
@@ -484,8 +533,16 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
     };
 
     let param_env = tcx.param_env(def_id);
+
+    let id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) {
+        hir::BodyOwnerKind::Closure => (false, false),
+        hir::BodyOwnerKind::Fn => (tcx.is_const_fn(def_id), tcx.is_min_const_fn(def_id)),
+        hir::BodyOwnerKind::Const |
+        hir::BodyOwnerKind::Static(_) => (true, false),
+    };
     let mut checker = UnsafetyChecker::new(
-        tcx.is_min_const_fn(def_id),
+        const_context, min_const_fn,
         mir, source_scope_local_data, tcx, param_env);
     checker.visit_mir(mir);
 
diff --git a/src/test/ui/cast/cast-ptr-to-int-const.rs b/src/test/ui/cast/cast-ptr-to-int-const.rs
index 70b4869ef63..ac153cb5742 100644
--- a/src/test/ui/cast/cast-ptr-to-int-const.rs
+++ b/src/test/ui/cast/cast-ptr-to-int-const.rs
@@ -1,7 +1,11 @@
 // gate-test-const_raw_ptr_to_usize_cast
 
 fn main() {
-    const X: u32 = main as u32; //~ ERROR casting pointers to integers in constants is unstable
+    const X: u32 = unsafe {
+        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 is unstable
+    const Z: u32 = unsafe {
+        &Y as *const u32 as u32 //~ ERROR is unstable
+    };
 }
diff --git a/src/test/ui/cast/cast-ptr-to-int-const.stderr b/src/test/ui/cast/cast-ptr-to-int-const.stderr
index 3cce07d64ec..d04595ee4e8 100644
--- a/src/test/ui/cast/cast-ptr-to-int-const.stderr
+++ b/src/test/ui/cast/cast-ptr-to-int-const.stderr
@@ -1,16 +1,16 @@
 error[E0658]: casting pointers to integers in constants is unstable (see issue #51910)
-  --> $DIR/cast-ptr-to-int-const.rs:4:20
+  --> $DIR/cast-ptr-to-int-const.rs:5:9
    |
-LL |     const X: u32 = main as u32; //~ ERROR casting pointers to integers in constants is unstable
-   |                    ^^^^^^^^^^^
+LL |         main as u32 //~ ERROR casting pointers to integers in constants is unstable
+   |         ^^^^^^^^^^^
    |
    = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
 
 error[E0658]: casting pointers to integers in constants is unstable (see issue #51910)
-  --> $DIR/cast-ptr-to-int-const.rs:6:20
+  --> $DIR/cast-ptr-to-int-const.rs:9:9
    |
-LL |     const Z: u32 = &Y as *const u32 as u32; //~ ERROR is unstable
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^
+LL |         &Y as *const u32 as u32 //~ ERROR is unstable
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
 
diff --git a/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs b/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs
index 63bac17f1c0..44266682a5c 100644
--- a/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs
+++ b/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs
@@ -3,13 +3,13 @@
 fn main() {}
 
 // unconst and bad, will thus error in miri
-const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR any use of this value will cause
+const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR any use of this
 // unconst and fine
-const X2: bool = 42 as *const i32 == 43 as *const i32;
+const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 };
 // unconst and fine
-const Y: usize = 42usize as *const i32 as usize + 1;
+const Y: usize = unsafe { 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 any use of this value will cause
+const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; //~ ERROR any use of this
 // unconst and fine
 const Z: i32 = unsafe { *(&1 as *const i32) };
 // unconst and bad, will thus error in miri
diff --git a/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr b/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr
index ea11359af85..6be54c0bad4 100644
--- a/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr
+++ b/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr
@@ -1,20 +1,20 @@
 error: any use of this value will cause an error
   --> $DIR/const_raw_ptr_ops.rs:6:1
    |
-LL | const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR any use of this value will cause
-   | ^^^^^^^^^^^^^^^^------------------------------------^
-   |                 |
-   |                 "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
+LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR any use of this
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                          |
+   |                          "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
    |
    = note: #[deny(const_err)] on by default
 
 error: any use of this value will cause an error
   --> $DIR/const_raw_ptr_ops.rs:12:1
    |
-LL | const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR any use of this value will cause
-   | ^^^^^^^^^^^^^^^^^^-----------------------------^
-   |                   |
-   |                   "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
+LL | const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; //~ ERROR any use of this
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------^^^
+   |                            |
+   |                            "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
 
 error: any use of this value will cause an error
   --> $DIR/const_raw_ptr_ops.rs:16:1
diff --git a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs
index d8abd976558..c2600f894dc 100644
--- a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs
+++ b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs
@@ -1,5 +1,5 @@
 const fn cmp(x: fn(), y: fn()) -> bool { //~ ERROR function pointers in const fn are unstable
-    x == y
+    unsafe { x == y }
 }
 
 fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr
index 91b076097b0..763c69e8050 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr
@@ -95,97 +95,109 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
 
 error: casting pointers to ints is unstable in const fn
-  --> $DIR/min_const_fn.rs:94:42
+  --> $DIR/min_const_fn.rs:94:63
+   |
+LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
+   |                                                               ^^^^^^^^^^
+
+error: casting pointers to ints is unstable in const fn
+  --> $DIR/min_const_fn.rs:96:42
    |
 LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
 
+error: casting pointers to ints is unstable in const fn
+  --> $DIR/min_const_fn.rs:98:63
+   |
+LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
+   |                                                               ^^^^^^^^^^
+
 error: `if`, `match`, `&&` and `||` are not stable in const fn
-  --> $DIR/min_const_fn.rs:96:38
+  --> $DIR/min_const_fn.rs:100:38
    |
 LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
    |                                      ^^^^^^^^^^^^^^^^^^^^^^
 
 error: `if`, `match`, `&&` and `||` are not stable in const fn
-  --> $DIR/min_const_fn.rs:98:29
+  --> $DIR/min_const_fn.rs:102:29
    |
 LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
    |                             ^^^^^^^^^^^
 
 error: `if`, `match`, `&&` and `||` are not stable in const fn
-  --> $DIR/min_const_fn.rs:100:44
+  --> $DIR/min_const_fn.rs:104:44
    |
 LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
    |                                            ^^^^^^
 
 error: `if`, `match`, `&&` and `||` are not stable in const fn
-  --> $DIR/min_const_fn.rs:102:44
+  --> $DIR/min_const_fn.rs:106:44
    |
 LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
    |                                            ^^^^^^
 
 error: mutable references in const fn are unstable
-  --> $DIR/min_const_fn.rs:104:14
+  --> $DIR/min_const_fn.rs:108:14
    |
 LL | const fn inc(x: &mut i32) { *x += 1 }
    |              ^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:109:6
+  --> $DIR/min_const_fn.rs:113:6
    |
 LL | impl<T: std::fmt::Debug> Foo<T> {
    |      ^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:114:6
+  --> $DIR/min_const_fn.rs:118:6
    |
 LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
    |      ^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:119:6
+  --> $DIR/min_const_fn.rs:123:6
    |
 LL | impl<T: Sync + Sized> Foo<T> {
    |      ^
 
 error: `impl Trait` in const fn is unstable
-  --> $DIR/min_const_fn.rs:125:24
+  --> $DIR/min_const_fn.rs:129:24
    |
 LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { AlanTuring(0) }
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:127:34
+  --> $DIR/min_const_fn.rs:131:34
    |
 LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
    |                                  ^^^^^^^^^^^^^^^^^^^^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:129:22
+  --> $DIR/min_const_fn.rs:133:22
    |
 LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
    |                      ^^^^^^^^^^^^^^^^^^^^
 
 error: `impl Trait` in const fn is unstable
-  --> $DIR/min_const_fn.rs:130:23
+  --> $DIR/min_const_fn.rs:134:23
    |
 LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable
    |                       ^^^^^^^^^^^^^^^^^^^^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:131:23
+  --> $DIR/min_const_fn.rs:135:23
    |
 LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
    |                       ^^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:132:32
+  --> $DIR/min_const_fn.rs:136:32
    |
 LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning[E0515]: cannot return reference to temporary value
-  --> $DIR/min_const_fn.rs:132:63
+  --> $DIR/min_const_fn.rs:136:63
    |
 LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    |                                                               ^--
@@ -197,24 +209,24 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:137:41
+  --> $DIR/min_const_fn.rs:141:41
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 }
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: function pointers in const fn are unstable
-  --> $DIR/min_const_fn.rs:140:21
+  --> $DIR/min_const_fn.rs:144:21
    |
 LL | const fn no_fn_ptrs(_x: fn()) {}
    |                     ^^
 
 error: function pointers in const fn are unstable
-  --> $DIR/min_const_fn.rs:142:27
+  --> $DIR/min_const_fn.rs:146:27
    |
 LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    |                           ^^^^
 
-error: aborting due to 34 previous errors
+error: aborting due to 36 previous errors
 
 Some errors occurred: E0493, E0515.
 For more information about an error, try `rustc --explain E0493`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs
index 05cf3d5f1f1..ee3ffcd4026 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs
@@ -90,9 +90,13 @@ static BAR: u32 = 42;
 const fn foo25() -> u32 { BAR } //~ ERROR cannot access `static` items in const fn
 const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot access `static` items
 const fn foo30(x: *const u32) -> usize { x as usize }
-//~^ ERROR casting pointers to int
+//~^ ERROR casting pointers to ints is unstable
+const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
+//~^ ERROR casting pointers to ints is unstable
 const fn foo30_2(x: *mut u32) -> usize { x as usize }
-//~^ ERROR casting pointers to int
+//~^ ERROR casting pointers to ints is unstable
+const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
+//~^ ERROR casting pointers to ints is unstable
 const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
 //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
 const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
index 2cae714fbf7..52c60c57b8f 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
@@ -95,113 +95,125 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
 
 error: casting pointers to ints is unstable in const fn
-  --> $DIR/min_const_fn.rs:94:42
+  --> $DIR/min_const_fn.rs:94:63
+   |
+LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
+   |                                                               ^^^^^^^^^^
+
+error: casting pointers to ints is unstable in const fn
+  --> $DIR/min_const_fn.rs:96:42
    |
 LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
 
+error: casting pointers to ints is unstable in const fn
+  --> $DIR/min_const_fn.rs:98:63
+   |
+LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
+   |                                                               ^^^^^^^^^^
+
 error: `if`, `match`, `&&` and `||` are not stable in const fn
-  --> $DIR/min_const_fn.rs:96:38
+  --> $DIR/min_const_fn.rs:100:38
    |
 LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
    |                                      ^^^^^^^^^^^^^^^^^^^^^^
 
 error: `if`, `match`, `&&` and `||` are not stable in const fn
-  --> $DIR/min_const_fn.rs:98:29
+  --> $DIR/min_const_fn.rs:102:29
    |
 LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
    |                             ^^^^^^^^^^^
 
 error: `if`, `match`, `&&` and `||` are not stable in const fn
-  --> $DIR/min_const_fn.rs:100:44
+  --> $DIR/min_const_fn.rs:104:44
    |
 LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
    |                                            ^^^^^^
 
 error: `if`, `match`, `&&` and `||` are not stable in const fn
-  --> $DIR/min_const_fn.rs:102:44
+  --> $DIR/min_const_fn.rs:106:44
    |
 LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
    |                                            ^^^^^^
 
 error: mutable references in const fn are unstable
-  --> $DIR/min_const_fn.rs:104:14
+  --> $DIR/min_const_fn.rs:108:14
    |
 LL | const fn inc(x: &mut i32) { *x += 1 }
    |              ^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:109:6
+  --> $DIR/min_const_fn.rs:113:6
    |
 LL | impl<T: std::fmt::Debug> Foo<T> {
    |      ^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:114:6
+  --> $DIR/min_const_fn.rs:118:6
    |
 LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
    |      ^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:119:6
+  --> $DIR/min_const_fn.rs:123:6
    |
 LL | impl<T: Sync + Sized> Foo<T> {
    |      ^
 
 error: `impl Trait` in const fn is unstable
-  --> $DIR/min_const_fn.rs:125:24
+  --> $DIR/min_const_fn.rs:129:24
    |
 LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { AlanTuring(0) }
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:127:34
+  --> $DIR/min_const_fn.rs:131:34
    |
 LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
    |                                  ^^^^^^^^^^^^^^^^^^^^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:129:22
+  --> $DIR/min_const_fn.rs:133:22
    |
 LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
    |                      ^^^^^^^^^^^^^^^^^^^^
 
 error: `impl Trait` in const fn is unstable
-  --> $DIR/min_const_fn.rs:130:23
+  --> $DIR/min_const_fn.rs:134:23
    |
 LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable
    |                       ^^^^^^^^^^^^^^^^^^^^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:131:23
+  --> $DIR/min_const_fn.rs:135:23
    |
 LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
    |                       ^^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:132:32
+  --> $DIR/min_const_fn.rs:136:32
    |
 LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:137:41
+  --> $DIR/min_const_fn.rs:141:41
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 }
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: function pointers in const fn are unstable
-  --> $DIR/min_const_fn.rs:140:21
+  --> $DIR/min_const_fn.rs:144:21
    |
 LL | const fn no_fn_ptrs(_x: fn()) {}
    |                     ^^
 
 error: function pointers in const fn are unstable
-  --> $DIR/min_const_fn.rs:142:27
+  --> $DIR/min_const_fn.rs:146:27
    |
 LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    |                           ^^^^
 
-error: aborting due to 34 previous errors
+error: aborting due to 36 previous errors
 
 For more information about this error, try `rustc --explain E0493`.
diff --git a/src/test/ui/error-codes/E0395.rs b/src/test/ui/error-codes/E0395.rs
index c2de56c413f..9657bbdeadc 100644
--- a/src/test/ui/error-codes/E0395.rs
+++ b/src/test/ui/error-codes/E0395.rs
@@ -3,6 +3,6 @@
 static FOO: i32 = 42;
 static BAR: i32 = 42;
 
-static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020
+static BAZ: bool = unsafe { (&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 45e1ba05ff9..cc7d94e22eb 100644
--- a/src/test/ui/error-codes/E0395.stderr
+++ b/src/test/ui/error-codes/E0395.stderr
@@ -1,8 +1,8 @@
 error[E0658]: comparing raw pointers inside static (see issue #53020)
-  --> $DIR/E0395.rs:6:22
+  --> $DIR/E0395.rs:6:29
    |
-LL | static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable
 
diff --git a/src/test/ui/issues/issue-17458.rs b/src/test/ui/issues/issue-17458.rs
index d7a1752b96c..444e94d829b 100644
--- a/src/test/ui/issues/issue-17458.rs
+++ b/src/test/ui/issues/issue-17458.rs
@@ -1,4 +1,4 @@
-static X: usize = 0 as *const usize as usize;
+static X: usize = unsafe { 0 as *const usize as usize };
 //~^ ERROR: casting pointers to integers in statics is unstable
 
 fn main() {
diff --git a/src/test/ui/issues/issue-17458.stderr b/src/test/ui/issues/issue-17458.stderr
index 04921419ae0..a1a8ed9f0cd 100644
--- a/src/test/ui/issues/issue-17458.stderr
+++ b/src/test/ui/issues/issue-17458.stderr
@@ -1,8 +1,8 @@
 error[E0658]: casting pointers to integers in statics is unstable (see issue #51910)
-  --> $DIR/issue-17458.rs:1:19
+  --> $DIR/issue-17458.rs:1:28
    |
-LL | static X: usize = 0 as *const usize as usize;
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | static X: usize = unsafe { 0 as *const usize as usize };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
 
diff --git a/src/test/ui/issues/issue-18294.rs b/src/test/ui/issues/issue-18294.rs
index df4fd1642f2..1c2229fb9ea 100644
--- a/src/test/ui/issues/issue-18294.rs
+++ b/src/test/ui/issues/issue-18294.rs
@@ -1,5 +1,5 @@
 fn main() {
     const X: u32 = 1;
-    const Y: usize = &X as *const u32 as usize; //~ ERROR is unstable
+    const Y: usize = unsafe { &X as *const u32 as usize }; //~ ERROR is unstable
     println!("{}", Y);
 }
diff --git a/src/test/ui/issues/issue-18294.stderr b/src/test/ui/issues/issue-18294.stderr
index 2af7f45628e..f3e8ab1a313 100644
--- a/src/test/ui/issues/issue-18294.stderr
+++ b/src/test/ui/issues/issue-18294.stderr
@@ -1,8 +1,8 @@
 error[E0658]: casting pointers to integers in constants is unstable (see issue #51910)
-  --> $DIR/issue-18294.rs:3:22
+  --> $DIR/issue-18294.rs:3:31
    |
-LL |     const Y: usize = &X as *const u32 as usize; //~ ERROR is unstable
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     const Y: usize = unsafe { &X as *const u32 as usize }; //~ ERROR is unstable
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
 
diff --git a/src/test/ui/issues/issue-25826.rs b/src/test/ui/issues/issue-25826.rs
index e6022653d9c..36a69cf4c22 100644
--- a/src/test/ui/issues/issue-25826.rs
+++ b/src/test/ui/issues/issue-25826.rs
@@ -1,6 +1,6 @@
 fn id<T>(t: T) -> T { t }
 fn main() {
-    const A: bool = id::<u8> as *const () < id::<u16> as *const ();
+    const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
     //~^ ERROR comparing raw pointers inside constant
     println!("{}", A);
 }
diff --git a/src/test/ui/issues/issue-25826.stderr b/src/test/ui/issues/issue-25826.stderr
index 73ebf29d08e..dc547f7c32c 100644
--- a/src/test/ui/issues/issue-25826.stderr
+++ b/src/test/ui/issues/issue-25826.stderr
@@ -1,8 +1,8 @@
 error[E0658]: comparing raw pointers inside constant (see issue #53020)
-  --> $DIR/issue-25826.rs:3:21
+  --> $DIR/issue-25826.rs:3:30
    |
-LL |     const A: bool = id::<u8> as *const () < id::<u16> as *const ();
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable