Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make const unsafe fn bodies unsafe #56706

Merged
merged 1 commit into from
Dec 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 0 additions & 7 deletions src/librustc_mir/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down
29 changes: 5 additions & 24 deletions src/librustc_mir/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -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!(
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
24 changes: 3 additions & 21 deletions src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
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

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
Expand Down Expand Up @@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Original file line number Diff line number Diff line change
@@ -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 11 previous errors
error: aborting due to 5 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`.