Skip to content

Commit 42b7153

Browse files
committed
Don't trigger unsafe_op_in_unsafe_fn for deprecated safe fns
Fixes rust-lang#125875.
1 parent 621e957 commit 42b7153

File tree

4 files changed

+110
-35
lines changed

4 files changed

+110
-35
lines changed

compiler/rustc_mir_build/src/check_unsafety.rs

+33-24
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,33 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
8888
}
8989
}
9090

91+
fn emit_deprecated_safe_fn_call(&self, span: Span, kind: &UnsafeOpKind) -> bool {
92+
match kind {
93+
// Allow calls to deprecated-safe unsafe functions if the caller is
94+
// from an edition before 2024.
95+
&UnsafeOpKind::CallToUnsafeFunction(Some(id))
96+
if !span.at_least_rust_2024()
97+
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
98+
{
99+
self.tcx.emit_node_span_lint(
100+
DEPRECATED_SAFE,
101+
self.hir_context,
102+
span,
103+
CallToDeprecatedSafeFnRequiresUnsafe {
104+
span,
105+
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
106+
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
107+
left: span.shrink_to_lo(),
108+
right: span.shrink_to_hi(),
109+
},
110+
},
111+
);
112+
true
113+
}
114+
_ => false,
115+
}
116+
}
117+
91118
fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) {
92119
let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
93120
match self.safety_context {
@@ -100,6 +127,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
100127
*used = true;
101128
}
102129
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
130+
SafetyContext::UnsafeFn if self.emit_deprecated_safe_fn_call(span, &kind) => {}
103131
SafetyContext::UnsafeFn => {
104132
// unsafe_op_in_unsafe_fn is disallowed
105133
kind.emit_unsafe_op_in_unsafe_fn_lint(
@@ -110,34 +138,15 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
110138
);
111139
self.suggest_unsafe_block = false;
112140
}
113-
SafetyContext::Safe => match kind {
114-
// Allow calls to deprecated-safe unsafe functions if the
115-
// caller is from an edition before 2024.
116-
UnsafeOpKind::CallToUnsafeFunction(Some(id))
117-
if !span.at_least_rust_2024()
118-
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
119-
{
120-
self.tcx.emit_node_span_lint(
121-
DEPRECATED_SAFE,
122-
self.hir_context,
123-
span,
124-
CallToDeprecatedSafeFnRequiresUnsafe {
125-
span,
126-
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
127-
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
128-
left: span.shrink_to_lo(),
129-
right: span.shrink_to_hi(),
130-
},
131-
},
132-
)
133-
}
134-
_ => kind.emit_requires_unsafe_err(
141+
SafetyContext::Safe if self.emit_deprecated_safe_fn_call(span, &kind) => {}
142+
SafetyContext::Safe => {
143+
kind.emit_requires_unsafe_err(
135144
self.tcx,
136145
span,
137146
self.hir_context,
138147
unsafe_op_in_unsafe_fn_allowed,
139-
),
140-
},
148+
);
149+
}
141150
}
142151
}
143152

+23-4
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,42 @@
1+
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
2+
--> $DIR/unsafe-env.rs:15:9
3+
|
4+
LL | unsafe_fn();
5+
| ^^^^^^^^^^^ call to unsafe function
6+
|
7+
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
8+
= note: consult the function's documentation for information on how to avoid undefined behavior
9+
note: an unsafe function restricts its caller, but its body is safe by default
10+
--> $DIR/unsafe-env.rs:9:1
11+
|
12+
LL | unsafe fn unsafe_fn() {
13+
| ^^^^^^^^^^^^^^^^^^^^^
14+
note: the lint level is defined here
15+
--> $DIR/unsafe-env.rs:8:8
16+
|
17+
LL | #[deny(unsafe_op_in_unsafe_fn)]
18+
| ^^^^^^^^^^^^^^^^^^^^^^
19+
120
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe function or block
2-
--> $DIR/unsafe-env.rs:23:5
21+
--> $DIR/unsafe-env.rs:33:5
322
|
423
LL | unsafe_fn();
524
| ^^^^^^^^^^^ call to unsafe function
625
|
726
= note: consult the function's documentation for information on how to avoid undefined behavior
827

928
error: unnecessary `unsafe` block
10-
--> $DIR/unsafe-env.rs:26:5
29+
--> $DIR/unsafe-env.rs:36:5
1130
|
1231
LL | unsafe {
1332
| ^^^^^^ unnecessary `unsafe` block
1433
|
1534
note: the lint level is defined here
16-
--> $DIR/unsafe-env.rs:11:8
35+
--> $DIR/unsafe-env.rs:21:8
1736
|
1837
LL | #[deny(unused_unsafe)]
1938
| ^^^^^^^^^^^^^
2039

21-
error: aborting due to 2 previous errors
40+
error: aborting due to 3 previous errors
2241

2342
For more information about this error, try `rustc --explain E0133`.
+43-6
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,76 @@
1+
error[E0133]: call to unsafe function `std::env::set_var` is unsafe and requires unsafe block
2+
--> $DIR/unsafe-env.rs:10:5
3+
|
4+
LL | env::set_var("FOO", "BAR");
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
6+
|
7+
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
8+
= note: consult the function's documentation for information on how to avoid undefined behavior
9+
note: an unsafe function restricts its caller, but its body is safe by default
10+
--> $DIR/unsafe-env.rs:9:1
11+
|
12+
LL | unsafe fn unsafe_fn() {
13+
| ^^^^^^^^^^^^^^^^^^^^^
14+
note: the lint level is defined here
15+
--> $DIR/unsafe-env.rs:8:8
16+
|
17+
LL | #[deny(unsafe_op_in_unsafe_fn)]
18+
| ^^^^^^^^^^^^^^^^^^^^^^
19+
20+
error[E0133]: call to unsafe function `std::env::remove_var` is unsafe and requires unsafe block
21+
--> $DIR/unsafe-env.rs:12:5
22+
|
23+
LL | env::remove_var("FOO");
24+
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
25+
|
26+
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
27+
= note: consult the function's documentation for information on how to avoid undefined behavior
28+
29+
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
30+
--> $DIR/unsafe-env.rs:15:9
31+
|
32+
LL | unsafe_fn();
33+
| ^^^^^^^^^^^ call to unsafe function
34+
|
35+
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
36+
= note: consult the function's documentation for information on how to avoid undefined behavior
37+
138
error[E0133]: call to unsafe function `set_var` is unsafe and requires unsafe block
2-
--> $DIR/unsafe-env.rs:13:5
39+
--> $DIR/unsafe-env.rs:23:5
340
|
441
LL | env::set_var("FOO", "BAR");
542
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
643
|
744
= note: consult the function's documentation for information on how to avoid undefined behavior
845

946
error[E0133]: call to unsafe function `remove_var` is unsafe and requires unsafe block
10-
--> $DIR/unsafe-env.rs:15:5
47+
--> $DIR/unsafe-env.rs:25:5
1148
|
1249
LL | env::remove_var("FOO");
1350
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
1451
|
1552
= note: consult the function's documentation for information on how to avoid undefined behavior
1653

1754
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
18-
--> $DIR/unsafe-env.rs:23:5
55+
--> $DIR/unsafe-env.rs:33:5
1956
|
2057
LL | unsafe_fn();
2158
| ^^^^^^^^^^^ call to unsafe function
2259
|
2360
= note: consult the function's documentation for information on how to avoid undefined behavior
2461

2562
error: unnecessary `unsafe` block
26-
--> $DIR/unsafe-env.rs:26:5
63+
--> $DIR/unsafe-env.rs:36:5
2764
|
2865
LL | unsafe {
2966
| ^^^^^^ unnecessary `unsafe` block
3067
|
3168
note: the lint level is defined here
32-
--> $DIR/unsafe-env.rs:11:8
69+
--> $DIR/unsafe-env.rs:21:8
3370
|
3471
LL | #[deny(unused_unsafe)]
3572
| ^^^^^^^^^^^^^
3673

37-
error: aborting due to 4 previous errors
74+
error: aborting due to 7 previous errors
3875

3976
For more information about this error, try `rustc --explain E0133`.

tests/ui/rust-2024/unsafe-env.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,17 @@
55

66
use std::env;
77

8-
unsafe fn unsafe_fn() {}
8+
#[deny(unsafe_op_in_unsafe_fn)]
9+
unsafe fn unsafe_fn() {
10+
env::set_var("FOO", "BAR");
11+
//[e2024]~^ ERROR call to unsafe function `std::env::set_var` is unsafe
12+
env::remove_var("FOO");
13+
//[e2024]~^ ERROR call to unsafe function `std::env::remove_var` is unsafe
14+
if false {
15+
unsafe_fn();
16+
//~^ ERROR call to unsafe function `unsafe_fn` is unsafe
17+
}
18+
}
919
fn safe_fn() {}
1020

1121
#[deny(unused_unsafe)]

0 commit comments

Comments
 (0)