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
13 changed files with 26 additions and 74 deletions
|
@ -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() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue