Skip to content

Commit c46f948

Browse files
authored
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 #71668 (comment). 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(); } } ```
2 parents 25fd504 + ec20993 commit c46f948

File tree

13 files changed

+26
-74
lines changed

13 files changed

+26
-74
lines changed

compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,8 @@ declare_features! (
275275
(accepted, move_ref_pattern, "1.49.0", Some(68354), None),
276276
/// The smallest useful subset of `const_generics`.
277277
(accepted, min_const_generics, "1.51.0", Some(74878), None),
278+
/// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
279+
(accepted, unsafe_block_in_unsafe_fn, "1.51.0", Some(71668), None),
278280

279281
// -------------------------------------------------------------------------
280282
// feature-group-end: accepted features

compiler/rustc_feature/src/active.rs

-3
Original file line numberDiff line numberDiff line change
@@ -557,9 +557,6 @@ declare_features! (
557557
/// Allows the use of `#[ffi_const]` on foreign functions.
558558
(active, ffi_const, "1.45.0", Some(58328), None),
559559

560-
/// No longer treat an unsafe function as an unsafe block.
561-
(active, unsafe_block_in_unsafe_fn, "1.45.0", Some(71668), None),
562-
563560
/// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`.
564561
(active, abi_avr_interrupt, "1.45.0", Some(69664), None),
565562

compiler/rustc_lint_defs/src/builtin.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
99
use crate::{declare_lint, declare_lint_pass};
1010
use rustc_span::edition::Edition;
11-
use rustc_span::symbol::sym;
1211

1312
declare_lint! {
1413
/// The `forbidden_lint_groups` lint detects violations of
@@ -2489,16 +2488,11 @@ declare_lint! {
24892488

24902489
declare_lint! {
24912490
/// The `unsafe_op_in_unsafe_fn` lint detects unsafe operations in unsafe
2492-
/// functions without an explicit unsafe block. This lint only works on
2493-
/// the [**nightly channel**] with the
2494-
/// `#![feature(unsafe_block_in_unsafe_fn)]` feature.
2495-
///
2496-
/// [**nightly channel**]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
2491+
/// functions without an explicit unsafe block.
24972492
///
24982493
/// ### Example
24992494
///
25002495
/// ```rust,compile_fail
2501-
/// #![feature(unsafe_block_in_unsafe_fn)]
25022496
/// #![deny(unsafe_op_in_unsafe_fn)]
25032497
///
25042498
/// unsafe fn foo() {}
@@ -2536,7 +2530,6 @@ declare_lint! {
25362530
pub UNSAFE_OP_IN_UNSAFE_FN,
25372531
Allow,
25382532
"unsafe operations in unsafe functions without an explicit unsafe block are deprecated",
2539-
@feature_gate = sym::unsafe_block_in_unsafe_fn;
25402533
}
25412534

25422535
declare_lint! {

compiler/rustc_middle/src/mir/query.rs

-2
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@ pub enum UnsafetyViolationKind {
2828
BorrowPacked,
2929
/// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
3030
/// Has to be handled as a lint for backwards compatibility.
31-
/// Should stay gated under `#![feature(unsafe_block_in_unsafe_fn)]`.
3231
UnsafeFn,
3332
/// Borrow of packed field in an `unsafe fn` but outside an `unsafe` block.
3433
/// Has to be handled as a lint for backwards compatibility.
35-
/// Should stay gated under `#![feature(unsafe_block_in_unsafe_fn)]`.
3634
UnsafeFnBorrowPacked,
3735
}
3836

compiler/rustc_mir/src/transform/check_unsafety.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
341341
false
342342
}
343343
// With the RFC 2585, no longer allow `unsafe` operations in `unsafe fn`s
344-
Safety::FnUnsafe if self.tcx.features().unsafe_block_in_unsafe_fn => {
344+
Safety::FnUnsafe => {
345345
for violation in violations {
346346
let mut violation = *violation;
347347

@@ -356,8 +356,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
356356
}
357357
false
358358
}
359-
// `unsafe` function bodies allow unsafe without additional unsafe blocks (before RFC 2585)
360-
Safety::BuiltinUnsafe | Safety::FnUnsafe => true,
359+
Safety::BuiltinUnsafe => true,
361360
Safety::ExplicitUnsafe(hir_id) => {
362361
// mark unsafe block as used if there are any unsafe operations inside
363362
if !violations.is_empty() {

library/alloc/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@
133133
#![feature(trusted_len)]
134134
#![feature(unboxed_closures)]
135135
#![feature(unicode_internals)]
136-
#![feature(unsafe_block_in_unsafe_fn)]
136+
#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))]
137137
#![feature(unsize)]
138138
#![feature(unsized_fn_params)]
139139
#![feature(allocator_internals)]

library/core/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@
164164
#![feature(const_caller_location)]
165165
#![feature(slice_ptr_get)]
166166
#![feature(no_niche)] // rust-lang/rust#68303
167-
#![feature(unsafe_block_in_unsafe_fn)]
168167
#![feature(int_error_matching)]
168+
#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))]
169169
#![deny(unsafe_op_in_unsafe_fn)]
170170

171171
#[prelude_import]

library/core/tests/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,16 @@
7272
#![feature(peekable_peek_mut)]
7373
#![cfg_attr(not(bootstrap), feature(ptr_metadata))]
7474
#![feature(once_cell)]
75-
#![feature(unsafe_block_in_unsafe_fn)]
7675
#![feature(unsized_tuple_coercion)]
7776
#![feature(int_bits_const)]
7877
#![feature(nonzero_leading_trailing_zeros)]
7978
#![feature(const_option)]
8079
#![feature(integer_atomics)]
8180
#![feature(slice_group_by)]
8281
#![feature(trusted_random_access)]
83-
#![deny(unsafe_op_in_unsafe_fn)]
82+
#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))]
8483
#![cfg_attr(not(bootstrap), feature(unsize))]
84+
#![deny(unsafe_op_in_unsafe_fn)]
8585

8686
extern crate test;
8787

library/std/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@
327327
#![feature(try_blocks)]
328328
#![feature(try_reserve)]
329329
#![feature(unboxed_closures)]
330-
#![feature(unsafe_block_in_unsafe_fn)]
330+
#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))]
331331
#![feature(unsafe_cell_raw_get)]
332332
#![feature(unwind_attributes)]
333333
#![feature(vec_into_raw_parts)]

src/test/ui/feature-gates/feature-gate-unsafe_block_in_unsafe_fn.rs

-6
This file was deleted.

src/test/ui/feature-gates/feature-gate-unsafe_block_in_unsafe_fn.stderr

-30
This file was deleted.

src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![feature(unsafe_block_in_unsafe_fn)]
21
#![deny(unsafe_op_in_unsafe_fn)]
32
#![deny(unused_unsafe)]
43

src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,90 @@
11
error: call to unsafe function is unsafe and requires unsafe block (error E0133)
2-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:10:5
2+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:9:5
33
|
44
LL | unsf();
55
| ^^^^^^ call to unsafe function
66
|
77
note: the lint level is defined here
8-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:2:9
8+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:1:9
99
|
1010
LL | #![deny(unsafe_op_in_unsafe_fn)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^
1212
= note: consult the function's documentation for information on how to avoid undefined behavior
1313

1414
error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
15-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5
15+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:11:5
1616
|
1717
LL | *PTR;
1818
| ^^^^ dereference of raw pointer
1919
|
2020
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
2121

2222
error: use of mutable static is unsafe and requires unsafe block (error E0133)
23-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5
23+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:13:5
2424
|
2525
LL | VOID = ();
2626
| ^^^^^^^^^ use of mutable static
2727
|
2828
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
2929

3030
error: unnecessary `unsafe` block
31-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5
31+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5
3232
|
3333
LL | unsafe {}
3434
| ^^^^^^ unnecessary `unsafe` block
3535
|
3636
note: the lint level is defined here
37-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:3:9
37+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:2:9
3838
|
3939
LL | #![deny(unused_unsafe)]
4040
| ^^^^^^^^^^^^^
4141

4242
error: call to unsafe function is unsafe and requires unsafe block (error E0133)
43-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:5
43+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:24:5
4444
|
4545
LL | unsf();
4646
| ^^^^^^ call to unsafe function
4747
|
4848
note: the lint level is defined here
49-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:23:8
49+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:22:8
5050
|
5151
LL | #[deny(warnings)]
5252
| ^^^^^^^^
5353
= note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]`
5454
= note: consult the function's documentation for information on how to avoid undefined behavior
5555

5656
error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
57-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5
57+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:5
5858
|
5959
LL | *PTR;
6060
| ^^^^ dereference of raw pointer
6161
|
6262
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
6363

6464
error: use of mutable static is unsafe and requires unsafe block (error E0133)
65-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5
65+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5
6666
|
6767
LL | VOID = ();
6868
| ^^^^^^^^^ use of mutable static
6969
|
7070
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
7171

7272
error: unnecessary `unsafe` block
73-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5
73+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:30:5
7474
|
7575
LL | unsafe {}
7676
| ^^^^^^ unnecessary `unsafe` block
7777

7878
error: unnecessary `unsafe` block
79-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:45:14
79+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:44:14
8080
|
8181
LL | unsafe { unsafe { unsf() } }
8282
| ------ ^^^^^^ unnecessary `unsafe` block
8383
| |
8484
| because it's nested under this `unsafe` block
8585

8686
error: unnecessary `unsafe` block
87-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:56:5
87+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:55:5
8888
|
8989
LL | unsafe fn allow_level() {
9090
| ----------------------- because it's nested under this `unsafe` fn
@@ -93,7 +93,7 @@ LL | unsafe { unsf() }
9393
| ^^^^^^ unnecessary `unsafe` block
9494

9595
error: unnecessary `unsafe` block
96-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:68:9
96+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:67:9
9797
|
9898
LL | unsafe fn nested_allow_level() {
9999
| ------------------------------ because it's nested under this `unsafe` fn
@@ -102,15 +102,15 @@ LL | unsafe { unsf() }
102102
| ^^^^^^ unnecessary `unsafe` block
103103

104104
error[E0133]: call to unsafe function is unsafe and requires unsafe block
105-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:74:5
105+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:73:5
106106
|
107107
LL | unsf();
108108
| ^^^^^^ call to unsafe function
109109
|
110110
= note: consult the function's documentation for information on how to avoid undefined behavior
111111

112112
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
113-
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:9
113+
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:77:9
114114
|
115115
LL | unsf();
116116
| ^^^^^^ call to unsafe function

0 commit comments

Comments
 (0)