Rollup merge of #56706 - oli-obk:const_unsafe_fn, r=Centril
Make `const unsafe fn` bodies `unsafe` r? @Centril Updated for tracking issue discussion https://github.com/rust-lang/rust/issues/55607#issuecomment-445882296
This commit is contained in:
commit
3552499010
@ -70,7 +70,7 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st
|
||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||
#[inline]
|
||||
pub const unsafe fn new_unchecked(n: $Int) -> Self {
|
||||
$Ty(unsafe { NonZero(n) })
|
||||
$Ty(NonZero(n))
|
||||
}
|
||||
|
||||
/// Create a non-zero if the given value is not zero.
|
||||
|
@ -2928,7 +2928,7 @@ impl<T: ?Sized> NonNull<T> {
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[inline]
|
||||
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
|
||||
NonNull { pointer: unsafe { NonZero(ptr as _) } }
|
||||
NonNull { pointer: NonZero(ptr as _) }
|
||||
}
|
||||
|
||||
/// Creates a new `NonNull` if `ptr` is non-null.
|
||||
|
@ -111,13 +111,6 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
|
||||
|
||||
let safety = match fn_sig.unsafety {
|
||||
hir::Unsafety::Normal => Safety::Safe,
|
||||
hir::Unsafety::Unsafe if tcx.is_min_const_fn(fn_def_id) => {
|
||||
// As specified in #55607, a `const unsafe fn` differs
|
||||
// from an `unsafe fn` in that its body is still considered
|
||||
// safe code by default.
|
||||
assert!(implicit_argument.is_none());
|
||||
Safety::Safe
|
||||
},
|
||||
hir::Unsafety::Unsafe => Safety::FnUnsafe,
|
||||
};
|
||||
|
||||
|
@ -311,13 +311,9 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||
violations: &[UnsafetyViolation],
|
||||
unsafe_blocks: &[(ast::NodeId, bool)]) {
|
||||
let safety = self.source_scope_local_data[self.source_info.scope].safety;
|
||||
let within_unsafe = match (safety, self.min_const_fn) {
|
||||
// Erring on the safe side, pun intended
|
||||
(Safety::BuiltinUnsafe, true) |
|
||||
// mir building encodes const fn bodies as safe, even for `const unsafe fn`
|
||||
(Safety::FnUnsafe, true) => bug!("const unsafe fn body treated as inherently unsafe"),
|
||||
let within_unsafe = match safety {
|
||||
// `unsafe` blocks are required in safe code
|
||||
(Safety::Safe, _) => {
|
||||
Safety::Safe => {
|
||||
for violation in violations {
|
||||
let mut violation = violation.clone();
|
||||
match violation.kind {
|
||||
@ -342,9 +338,9 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||
}
|
||||
false
|
||||
}
|
||||
// regular `unsafe` function bodies allow unsafe without additional unsafe blocks
|
||||
(Safety::BuiltinUnsafe, false) | (Safety::FnUnsafe, false) => true,
|
||||
(Safety::ExplicitUnsafe(node_id), _) => {
|
||||
// `unsafe` function bodies allow unsafe without additional unsafe blocks
|
||||
Safety::BuiltinUnsafe | Safety::FnUnsafe => true,
|
||||
Safety::ExplicitUnsafe(node_id) => {
|
||||
// mark unsafe block as used if there are any unsafe operations inside
|
||||
if !violations.is_empty() {
|
||||
self.used_unsafe.insert(node_id);
|
||||
@ -616,21 +612,6 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
|
||||
} in violations.iter() {
|
||||
// Report an error.
|
||||
match kind {
|
||||
UnsafetyViolationKind::General if tcx.is_min_const_fn(def_id) => {
|
||||
let mut err = tcx.sess.struct_span_err(
|
||||
source_info.span,
|
||||
&format!("{} is unsafe and unsafe operations \
|
||||
are not allowed in const fn", description));
|
||||
err.span_label(source_info.span, &description.as_str()[..])
|
||||
.note(&details.as_str()[..]);
|
||||
if tcx.fn_sig(def_id).unsafety() == hir::Unsafety::Unsafe {
|
||||
err.note(
|
||||
"unsafe action within a `const unsafe fn` still require an `unsafe` \
|
||||
block in contrast to regular `unsafe fn`."
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
UnsafetyViolationKind::GeneralAndConstFn |
|
||||
UnsafetyViolationKind::General => {
|
||||
struct_span_err!(
|
||||
|
@ -28,13 +28,13 @@ const fn call_unsafe_generic_cell_const_fn() -> *const Vec<std::cell::Cell<u32>>
|
||||
unsafe { ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>() }
|
||||
//~^ ERROR calls to `const unsafe fn` in const fns
|
||||
}
|
||||
const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
|
||||
const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x }
|
||||
//~^ dereferencing raw pointers in constant functions
|
||||
|
||||
fn main() {}
|
||||
|
||||
const unsafe fn no_union() {
|
||||
union Foo { x: (), y: () }
|
||||
Foo { x: () }.y //~ ERROR not allowed in const fn
|
||||
Foo { x: () }.y
|
||||
//~^ unions in const fn
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
|
||||
--> $DIR/min_const_fn_unsafe.rs:31:59
|
||||
|
|
||||
LL | const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
|
||||
LL | const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x }
|
||||
| ^^
|
||||
|
|
||||
= help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
|
||||
@ -9,7 +9,7 @@ LL | const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x } //~ ERROR no
|
||||
error[E0658]: unions in const fn are unstable (see issue #51909)
|
||||
--> $DIR/min_const_fn_unsafe.rs:38:5
|
||||
|
|
||||
LL | Foo { x: () }.y //~ ERROR not allowed in const fn
|
||||
LL | Foo { x: () }.y
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_fn_union)] to the crate attributes to enable
|
||||
@ -38,24 +38,6 @@ LL | unsafe { ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>() }
|
||||
|
|
||||
= help: add #![feature(min_const_unsafe_fn)] to the crate attributes to enable
|
||||
|
||||
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
|
||||
--> $DIR/min_const_fn_unsafe.rs:31:59
|
||||
|
|
||||
LL | const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
|
||||
| ^^ dereference of raw pointer
|
||||
|
|
||||
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
|
||||
|
||||
error: access to union field is unsafe and unsafe operations are not allowed in const fn
|
||||
--> $DIR/min_const_fn_unsafe.rs:38:5
|
||||
|
|
||||
LL | Foo { x: () }.y //~ ERROR not allowed in const fn
|
||||
| ^^^^^^^^^^^^^^^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -34,29 +34,28 @@ const unsafe fn foo9_3() -> *const String {
|
||||
const unsafe fn foo10_3() -> *const Vec<std::cell::Cell<u32>> {
|
||||
unsafe { foo6::<Vec<std::cell::Cell<u32>>>() }
|
||||
}
|
||||
// not ok
|
||||
const unsafe fn foo8_2() -> i32 {
|
||||
foo4() //~ ERROR not allowed in const fn
|
||||
foo4()
|
||||
}
|
||||
const unsafe fn foo9_2() -> *const String {
|
||||
foo5::<String>() //~ ERROR not allowed in const fn
|
||||
foo5::<String>()
|
||||
}
|
||||
const unsafe fn foo10_2() -> *const Vec<std::cell::Cell<u32>> {
|
||||
foo6::<Vec<std::cell::Cell<u32>>>() //~ ERROR not allowed in const fn
|
||||
foo6::<Vec<std::cell::Cell<u32>>>()
|
||||
}
|
||||
const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
|
||||
const unsafe fn foo30_3(x: *mut usize) -> usize { *x }
|
||||
//~^ dereferencing raw pointers in constant functions
|
||||
|
||||
const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x } //~ ERROR not allowed in const fn
|
||||
const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x }
|
||||
//~^ dereferencing raw pointers in constant functions
|
||||
|
||||
const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ ERROR not allowed
|
||||
const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
|
||||
//~^ dereferencing raw pointers in constant functions
|
||||
|
||||
fn main() {}
|
||||
|
||||
const unsafe fn no_union() {
|
||||
union Foo { x: (), y: () }
|
||||
Foo { x: () }.y //~ ERROR not allowed in const fn
|
||||
Foo { x: () }.y
|
||||
//~^ unions in const fn
|
||||
}
|
||||
|
@ -1,97 +1,44 @@
|
||||
error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:47:51
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:46:51
|
||||
|
|
||||
LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
|
||||
LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x }
|
||||
| ^^
|
||||
|
|
||||
= help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:50:60
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:49:60
|
||||
|
|
||||
LL | const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x } //~ ERROR not allowed in const fn
|
||||
LL | const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x }
|
||||
| ^^^
|
||||
|
|
||||
= help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:53:62
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:52:62
|
||||
|
|
||||
LL | const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ ERROR not allowed
|
||||
LL | const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
|
||||
| ^^^
|
||||
|
|
||||
= help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: unions in const fn are unstable (see issue #51909)
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:60:5
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:59:5
|
||||
|
|
||||
LL | Foo { x: () }.y //~ ERROR not allowed in const fn
|
||||
LL | Foo { x: () }.y
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_fn_union)] to the crate attributes to enable
|
||||
|
||||
error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:39:5
|
||||
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:52:62
|
||||
|
|
||||
LL | foo4() //~ ERROR not allowed in const fn
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
|
||||
|
||||
error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:42:5
|
||||
|
|
||||
LL | foo5::<String>() //~ ERROR not allowed in const fn
|
||||
| ^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
|
||||
|
||||
error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:45:5
|
||||
|
|
||||
LL | foo6::<Vec<std::cell::Cell<u32>>>() //~ ERROR not allowed in const fn
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
|
||||
|
||||
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:47:51
|
||||
|
|
||||
LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
|
||||
| ^^ dereference of raw pointer
|
||||
|
|
||||
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
|
||||
|
||||
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:50:60
|
||||
|
|
||||
LL | const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x } //~ ERROR not allowed in const fn
|
||||
| ^^^ dereference of raw pointer
|
||||
|
|
||||
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
|
||||
|
||||
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:53:62
|
||||
|
|
||||
LL | const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ ERROR not allowed
|
||||
LL | const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
|
||||
| ^^^ dereference of raw pointer
|
||||
|
|
||||
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
|
||||
error: access to union field is unsafe and unsafe operations are not allowed in const fn
|
||||
--> $DIR/min_const_fn_unsafe_feature_gate.rs:60:5
|
||||
|
|
||||
LL | Foo { x: () }.y //~ ERROR not allowed in const fn
|
||||
| ^^^^^^^^^^^^^^^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
Some errors occurred: E0133, E0658.
|
||||
For more information about an error, try `rustc --explain E0133`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user