Auto merge of #55009 - oli-obk:const_safety, r=RalfJung
Make raw ptr ops unsafe in const contexts
r? @RalfJung
cc @Centril
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index d9ca37c..c3e4f0c 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -455,11 +455,20 @@
Node::AnonConst(_) => {
BodyOwnerKind::Const
}
+ Node::Variant(&Spanned { node: VariantKind { data: VariantData::Tuple(..), .. }, .. }) |
+ Node::StructCtor(..) |
+ Node::Item(&Item { node: ItemKind::Fn(..), .. }) |
+ Node::TraitItem(&TraitItem { node: TraitItemKind::Method(..), .. }) |
+ Node::ImplItem(&ImplItem { node: ImplItemKind::Method(..), .. }) => {
+ BodyOwnerKind::Fn
+ }
Node::Item(&Item { node: ItemKind::Static(_, m, _), .. }) => {
BodyOwnerKind::Static(m)
}
- // Default to function if it's not a constant or static.
- _ => BodyOwnerKind::Fn
+ Node::Expr(&Expr { node: ExprKind::Closure(..), .. }) => {
+ BodyOwnerKind::Closure
+ }
+ node => bug!("{:#?} is not a body node", node),
}
}
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 65d9d5a..b58b1d3 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1270,6 +1270,9 @@
/// Functions and methods.
Fn,
+ /// Closures
+ Closure,
+
/// Constants and associated constants.
Const,
@@ -1277,6 +1280,15 @@
Static(Mutability),
}
+impl BodyOwnerKind {
+ pub fn is_fn_or_closure(self) -> bool {
+ match self {
+ BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
+ BodyOwnerKind::Const | BodyOwnerKind::Static(_) => false,
+ }
+ }
+}
+
/// A constant (expression) that's not an item or associated item,
/// but needs its own `DefId` for type-checking, const-eval, etc.
/// These are usually found nested inside types (e.g., array lengths)
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 819dd8a..31f91a1 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -1268,8 +1268,8 @@
// The body of the every fn is a root scope.
self.cx.parent = self.cx.var_parent;
- if let hir::BodyOwnerKind::Fn = self.tcx.hir().body_owner_kind(owner_id) {
- self.visit_expr(&body.value);
+ if self.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() {
+ self.visit_expr(&body.value)
} else {
// Only functions have an outer terminating (drop) scope, while
// temporaries in constant initializers may be 'static, but only
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 4563224..9d49814 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -163,10 +163,7 @@
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
));
- let locals_are_invalidated_at_exit = match tcx.hir().body_owner_kind(id) {
- hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => false,
- hir::BodyOwnerKind::Fn => true,
- };
+ let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure();
let borrow_set = Rc::new(BorrowSet::build(
tcx, mir, locals_are_invalidated_at_exit, &mdpe.move_data));
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index c63d45c..0a214e6 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -476,6 +476,7 @@
let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id);
match tcx.hir().body_owner_kind(self.mir_node_id) {
+ BodyOwnerKind::Closure |
BodyOwnerKind::Fn => {
let defining_ty = if self.mir_def_id == closure_base_def_id {
tcx.type_of(closure_base_def_id)
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 2bf2824..420ae11 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -75,7 +75,7 @@
let cx = Cx::new(&infcx, id);
let mut mir = if cx.tables().tainted_by_errors {
build::construct_error(cx, body_id)
- } else if let hir::BodyOwnerKind::Fn = cx.body_owner_kind {
+ } else if cx.body_owner_kind.is_fn_or_closure() {
// fetch the fully liberated fn signature (that is, all bound
// types/lifetimes replaced)
let fn_hir_id = tcx.hir().node_to_hir_id(id);
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index b44c2cc..78abba5 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -613,6 +613,7 @@
hir::BodyOwnerKind::Static(_) =>
// No need to free storage in this context.
None,
+ hir::BodyOwnerKind::Closure |
hir::BodyOwnerKind::Fn =>
Some(self.topmost_scope()),
}
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index 6113d88..f514cac 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -61,6 +61,7 @@
let constness = match body_owner_kind {
hir::BodyOwnerKind::Const |
hir::BodyOwnerKind::Static(_) => hir::Constness::Const,
+ hir::BodyOwnerKind::Closure |
hir::BodyOwnerKind::Fn => hir::Constness::NotConst,
};
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index eb151b5..ab8da2f 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -4,6 +4,7 @@
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 @@
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 @@
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 @@
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 @@
};
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/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 8b970c1..9f0907a 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -1,6 +1,5 @@
//! Inlining pass for MIR functions
-use rustc::hir;
use rustc::hir::CodegenFnAttrFlags;
use rustc::hir::def_id::DefId;
@@ -74,15 +73,12 @@
// Only do inlining into fn bodies.
let id = self.tcx.hir().as_local_node_id(self.source.def_id).unwrap();
- let body_owner_kind = self.tcx.hir().body_owner_kind(id);
-
- if let (hir::BodyOwnerKind::Fn, None) = (body_owner_kind, self.source.promoted) {
-
+ if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() && self.source.promoted.is_none() {
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
if let Some(callsite) = self.get_valid_function_call(bb,
- bb_data,
- caller_mir,
- param_env) {
+ bb_data,
+ caller_mir,
+ param_env) {
callsites.push_back(callsite);
}
}
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 78cf715..2d94190 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1152,6 +1152,7 @@
let id = tcx.hir().as_local_node_id(def_id).unwrap();
let mut const_promoted_temps = None;
let mode = match tcx.hir().body_owner_kind(id) {
+ hir::BodyOwnerKind::Closure => Mode::Fn,
hir::BodyOwnerKind::Fn => {
if tcx.is_const_fn(def_id) {
Mode::ConstFn
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index fca208b..f4685e0 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -573,6 +573,7 @@
let body_owner_kind = tcx.hir().body_owner_kind(id);
match (body_owner_kind, src.promoted) {
(_, Some(i)) => write!(w, "{:?} in", i)?,
+ (hir::BodyOwnerKind::Closure, _) |
(hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?,
(hir::BodyOwnerKind::Const, _) => write!(w, "const")?,
(hir::BodyOwnerKind::Static(hir::MutImmutable), _) => write!(w, "static")?,
@@ -585,6 +586,7 @@
})?;
match (body_owner_kind, src.promoted) {
+ (hir::BodyOwnerKind::Closure, None) |
(hir::BodyOwnerKind::Fn, None) => {
write!(w, "(")?;
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 49914dc..c11b1af 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -191,6 +191,7 @@
self.in_static = false;
match self.tcx.hir().body_owner_kind(item_id) {
+ hir::BodyOwnerKind::Closure |
hir::BodyOwnerKind::Fn => self.in_fn = true,
hir::BodyOwnerKind::Static(_) => self.in_static = true,
_ => {}
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 70b4869..ac153cb 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 3cce07d..d04595e 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 63bac17..4426668 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 ea11359..6be54c0 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 d8abd97..c2600f8 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 91b0760..763c69e 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 @@
| ^^^^^^^^^^
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 @@
= 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 05cf3d5..ee3ffcd 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 @@
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 2cae714..52c60c5 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 @@
| ^^^^^^^^^^
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 c2de56c..9657bbd 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 45e1ba0..cc7d94e 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 d7a1752..444e94d 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 0492141..a1a8ed9 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 df4fd16..1c2229f 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 2af7f45..f3e8ab1 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 e602265..36a69cf 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 73ebf29..dc547f7c 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