mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #79208 - LeSeulArtichaut:stable-unsafe_op_in_unsafe_fn, r=nikomatsakis
Stabilize `unsafe_op_in_unsafe_fn` lint This makes it possible to override the level of the `unsafe_op_in_unsafe_fn`, as proposed in https://github.com/rust-lang/rust/issues/71668#issuecomment-729770896. Tracking issue: #71668 r? ```@nikomatsakis``` cc ```@SimonSapin``` ```@RalfJung``` # Stabilization report This is a stabilization report for `#![feature(unsafe_block_in_unsafe_fn)]`. ## Summary Currently, the body of unsafe functions is an unsafe block, i.e. you can perform unsafe operations inside. The `unsafe_op_in_unsafe_fn` lint, stabilized here, can be used to change this behavior, so performing unsafe operations in unsafe functions requires an unsafe block. For now, the lint is allow-by-default, which means that this PR does not change anything without overriding the lint level. For more information, see [RFC 2585](https://github.com/rust-lang/rfcs/blob/master/text/2585-unsafe-block-in-unsafe-fn.md) ### Example ```rust // An `unsafe fn` for demonstration purposes. // Calling this is an unsafe operation. unsafe fn unsf() {} // #[allow(unsafe_op_in_unsafe_fn)] by default, // the behavior of `unsafe fn` is unchanged unsafe fn allowed() { // Here, no `unsafe` block is needed to // perform unsafe operations... unsf(); // ...and any `unsafe` block is considered // unused and is warned on by the compiler. unsafe { unsf(); } } #[warn(unsafe_op_in_unsafe_fn)] unsafe fn warned() { // Removing this `unsafe` block will // cause the compiler to emit a warning. // (Also, no "unused unsafe" warning will be emitted here.) unsafe { unsf(); } } #[deny(unsafe_op_in_unsafe_fn)] unsafe fn denied() { // Removing this `unsafe` block will // cause a compilation error. // (Also, no "unused unsafe" warning will be emitted here.) unsafe { unsf(); } } ```
This commit is contained in:
commit
c46f948a80
@ -275,6 +275,8 @@ declare_features! (
|
||||
(accepted, move_ref_pattern, "1.49.0", Some(68354), None),
|
||||
/// The smallest useful subset of `const_generics`.
|
||||
(accepted, min_const_generics, "1.51.0", Some(74878), None),
|
||||
/// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
|
||||
(accepted, unsafe_block_in_unsafe_fn, "1.51.0", Some(71668), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: accepted features
|
||||
|
@ -557,9 +557,6 @@ declare_features! (
|
||||
/// Allows the use of `#[ffi_const]` on foreign functions.
|
||||
(active, ffi_const, "1.45.0", Some(58328), None),
|
||||
|
||||
/// No longer treat an unsafe function as an unsafe block.
|
||||
(active, unsafe_block_in_unsafe_fn, "1.45.0", Some(71668), None),
|
||||
|
||||
/// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`.
|
||||
(active, abi_avr_interrupt, "1.45.0", Some(69664), None),
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
use crate::{declare_lint, declare_lint_pass};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
declare_lint! {
|
||||
/// The `forbidden_lint_groups` lint detects violations of
|
||||
@ -2489,16 +2488,11 @@ declare_lint! {
|
||||
|
||||
declare_lint! {
|
||||
/// The `unsafe_op_in_unsafe_fn` lint detects unsafe operations in unsafe
|
||||
/// functions without an explicit unsafe block. This lint only works on
|
||||
/// the [**nightly channel**] with the
|
||||
/// `#![feature(unsafe_block_in_unsafe_fn)]` feature.
|
||||
///
|
||||
/// [**nightly channel**]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
|
||||
/// functions without an explicit unsafe block.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,compile_fail
|
||||
/// #![feature(unsafe_block_in_unsafe_fn)]
|
||||
/// #![deny(unsafe_op_in_unsafe_fn)]
|
||||
///
|
||||
/// unsafe fn foo() {}
|
||||
@ -2536,7 +2530,6 @@ declare_lint! {
|
||||
pub UNSAFE_OP_IN_UNSAFE_FN,
|
||||
Allow,
|
||||
"unsafe operations in unsafe functions without an explicit unsafe block are deprecated",
|
||||
@feature_gate = sym::unsafe_block_in_unsafe_fn;
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
|
@ -28,11 +28,9 @@ pub enum UnsafetyViolationKind {
|
||||
BorrowPacked,
|
||||
/// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
|
||||
/// Has to be handled as a lint for backwards compatibility.
|
||||
/// Should stay gated under `#![feature(unsafe_block_in_unsafe_fn)]`.
|
||||
UnsafeFn,
|
||||
/// Borrow of packed field in an `unsafe fn` but outside an `unsafe` block.
|
||||
/// Has to be handled as a lint for backwards compatibility.
|
||||
/// Should stay gated under `#![feature(unsafe_block_in_unsafe_fn)]`.
|
||||
UnsafeFnBorrowPacked,
|
||||
}
|
||||
|
||||
|
@ -341,7 +341,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||
false
|
||||
}
|
||||
// With the RFC 2585, no longer allow `unsafe` operations in `unsafe fn`s
|
||||
Safety::FnUnsafe if self.tcx.features().unsafe_block_in_unsafe_fn => {
|
||||
Safety::FnUnsafe => {
|
||||
for violation in violations {
|
||||
let mut violation = *violation;
|
||||
|
||||
@ -356,8 +356,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||
}
|
||||
false
|
||||
}
|
||||
// `unsafe` function bodies allow unsafe without additional unsafe blocks (before RFC 2585)
|
||||
Safety::BuiltinUnsafe | Safety::FnUnsafe => true,
|
||||
Safety::BuiltinUnsafe => true,
|
||||
Safety::ExplicitUnsafe(hir_id) => {
|
||||
// mark unsafe block as used if there are any unsafe operations inside
|
||||
if !violations.is_empty() {
|
||||
|
@ -133,7 +133,7 @@
|
||||
#![feature(trusted_len)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unicode_internals)]
|
||||
#![feature(unsafe_block_in_unsafe_fn)]
|
||||
#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))]
|
||||
#![feature(unsize)]
|
||||
#![feature(unsized_fn_params)]
|
||||
#![feature(allocator_internals)]
|
||||
|
@ -164,8 +164,8 @@
|
||||
#![feature(const_caller_location)]
|
||||
#![feature(slice_ptr_get)]
|
||||
#![feature(no_niche)] // rust-lang/rust#68303
|
||||
#![feature(unsafe_block_in_unsafe_fn)]
|
||||
#![feature(int_error_matching)]
|
||||
#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
#[prelude_import]
|
||||
|
@ -72,7 +72,6 @@
|
||||
#![feature(peekable_peek_mut)]
|
||||
#![cfg_attr(not(bootstrap), feature(ptr_metadata))]
|
||||
#![feature(once_cell)]
|
||||
#![feature(unsafe_block_in_unsafe_fn)]
|
||||
#![feature(unsized_tuple_coercion)]
|
||||
#![feature(int_bits_const)]
|
||||
#![feature(nonzero_leading_trailing_zeros)]
|
||||
@ -80,8 +79,9 @@
|
||||
#![feature(integer_atomics)]
|
||||
#![feature(slice_group_by)]
|
||||
#![feature(trusted_random_access)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))]
|
||||
#![cfg_attr(not(bootstrap), feature(unsize))]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
|
@ -327,7 +327,7 @@
|
||||
#![feature(try_blocks)]
|
||||
#![feature(try_reserve)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unsafe_block_in_unsafe_fn)]
|
||||
#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))]
|
||||
#![feature(unsafe_cell_raw_get)]
|
||||
#![feature(unwind_attributes)]
|
||||
#![feature(vec_into_raw_parts)]
|
||||
|
@ -1,6 +0,0 @@
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
//~^ ERROR the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||
//~| ERROR the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||
//~| ERROR the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||
|
||||
fn main() {}
|
@ -1,30 +0,0 @@
|
||||
error[E0658]: the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||
--> $DIR/feature-gate-unsafe_block_in_unsafe_fn.rs:1:1
|
||||
|
|
||||
LL | #![deny(unsafe_op_in_unsafe_fn)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #71668 <https://github.com/rust-lang/rust/issues/71668> for more information
|
||||
= help: add `#![feature(unsafe_block_in_unsafe_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||
--> $DIR/feature-gate-unsafe_block_in_unsafe_fn.rs:1:1
|
||||
|
|
||||
LL | #![deny(unsafe_op_in_unsafe_fn)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #71668 <https://github.com/rust-lang/rust/issues/71668> for more information
|
||||
= help: add `#![feature(unsafe_block_in_unsafe_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||
--> $DIR/feature-gate-unsafe_block_in_unsafe_fn.rs:1:1
|
||||
|
|
||||
LL | #![deny(unsafe_op_in_unsafe_fn)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #71668 <https://github.com/rust-lang/rust/issues/71668> for more information
|
||||
= help: add `#![feature(unsafe_block_in_unsafe_fn)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -1,4 +1,3 @@
|
||||
#![feature(unsafe_block_in_unsafe_fn)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
#![deny(unused_unsafe)]
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
error: call to unsafe function is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:10:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:9:5
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:2:9
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:1:9
|
||||
|
|
||||
LL | #![deny(unsafe_op_in_unsafe_fn)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:11:5
|
||||
|
|
||||
LL | *PTR;
|
||||
| ^^^^ dereference of raw pointer
|
||||
@ -20,7 +20,7 @@ LL | *PTR;
|
||||
= 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: use of mutable static is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:13:5
|
||||
|
|
||||
LL | VOID = ();
|
||||
| ^^^^^^^^^ use of mutable static
|
||||
@ -28,25 +28,25 @@ LL | VOID = ();
|
||||
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5
|
||||
|
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:3:9
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:2:9
|
||||
|
|
||||
LL | #![deny(unused_unsafe)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: call to unsafe function is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:24:5
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:23:8
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:22:8
|
||||
|
|
||||
LL | #[deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
@ -54,7 +54,7 @@ LL | #[deny(warnings)]
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:5
|
||||
|
|
||||
LL | *PTR;
|
||||
| ^^^^ dereference of raw pointer
|
||||
@ -62,7 +62,7 @@ LL | *PTR;
|
||||
= 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: use of mutable static is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5
|
||||
|
|
||||
LL | VOID = ();
|
||||
| ^^^^^^^^^ use of mutable static
|
||||
@ -70,13 +70,13 @@ LL | VOID = ();
|
||||
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:30:5
|
||||
|
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:45:14
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:44:14
|
||||
|
|
||||
LL | unsafe { unsafe { unsf() } }
|
||||
| ------ ^^^^^^ unnecessary `unsafe` block
|
||||
@ -84,7 +84,7 @@ LL | unsafe { unsafe { unsf() } }
|
||||
| because it's nested under this `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:56:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:55:5
|
||||
|
|
||||
LL | unsafe fn allow_level() {
|
||||
| ----------------------- because it's nested under this `unsafe` fn
|
||||
@ -93,7 +93,7 @@ LL | unsafe { unsf() }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:68:9
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:67:9
|
||||
|
|
||||
LL | unsafe fn nested_allow_level() {
|
||||
| ------------------------------ because it's nested under this `unsafe` fn
|
||||
@ -102,7 +102,7 @@ LL | unsafe { unsf() }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:74:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:73:5
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
@ -110,7 +110,7 @@ LL | unsf();
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:9
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:77:9
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
Loading…
Reference in New Issue
Block a user