Rollup merge of #125925 - tbu-:pr_unsafe_env_unsafe_op_in_unsafe_fn, r=Nadrieril

Don't trigger `unsafe_op_in_unsafe_fn` for deprecated safe fns

Fixes #125875.

Tracking:

- #124866
This commit is contained in:
Matthias Krüger 2024-06-06 04:17:26 +02:00 committed by GitHub
commit 8f04878dee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 124 additions and 45 deletions

View File

@ -88,6 +88,33 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
}
}
fn emit_deprecated_safe_fn_call(&self, span: Span, kind: &UnsafeOpKind) -> bool {
match kind {
// Allow calls to deprecated-safe unsafe functions if the caller is
// from an edition before 2024.
&UnsafeOpKind::CallToUnsafeFunction(Some(id))
if !span.at_least_rust_2024()
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
{
self.tcx.emit_node_span_lint(
DEPRECATED_SAFE,
self.hir_context,
span,
CallToDeprecatedSafeFnRequiresUnsafe {
span,
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
left: span.shrink_to_lo(),
right: span.shrink_to_hi(),
},
},
);
true
}
_ => false,
}
}
fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) {
let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
match self.safety_context {
@ -101,43 +128,29 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
}
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
SafetyContext::UnsafeFn => {
// unsafe_op_in_unsafe_fn is disallowed
kind.emit_unsafe_op_in_unsafe_fn_lint(
self.tcx,
self.hir_context,
span,
self.suggest_unsafe_block,
);
self.suggest_unsafe_block = false;
}
SafetyContext::Safe => match kind {
// Allow calls to deprecated-safe unsafe functions if the
// caller is from an edition before 2024.
UnsafeOpKind::CallToUnsafeFunction(Some(id))
if !span.at_least_rust_2024()
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
{
self.tcx.emit_node_span_lint(
DEPRECATED_SAFE,
let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind);
if !deprecated_safe_fn {
// unsafe_op_in_unsafe_fn is disallowed
kind.emit_unsafe_op_in_unsafe_fn_lint(
self.tcx,
self.hir_context,
span,
CallToDeprecatedSafeFnRequiresUnsafe {
span,
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
left: span.shrink_to_lo(),
right: span.shrink_to_hi(),
},
},
)
self.suggest_unsafe_block,
);
self.suggest_unsafe_block = false;
}
_ => kind.emit_requires_unsafe_err(
self.tcx,
span,
self.hir_context,
unsafe_op_in_unsafe_fn_allowed,
),
},
}
SafetyContext::Safe => {
let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind);
if !deprecated_safe_fn {
kind.emit_requires_unsafe_err(
self.tcx,
span,
self.hir_context,
unsafe_op_in_unsafe_fn_allowed,
);
}
}
}
}

View File

@ -1,5 +1,24 @@
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:15:9
|
LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function
|
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
= note: consult the function's documentation for information on how to avoid undefined behavior
note: an unsafe function restricts its caller, but its body is safe by default
--> $DIR/unsafe-env.rs:9:1
|
LL | unsafe fn unsafe_fn() {
| ^^^^^^^^^^^^^^^^^^^^^
note: the lint level is defined here
--> $DIR/unsafe-env.rs:8:8
|
LL | #[deny(unsafe_op_in_unsafe_fn)]
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe function or block
--> $DIR/unsafe-env.rs:23:5
--> $DIR/unsafe-env.rs:33:5
|
LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function
@ -7,17 +26,17 @@ LL | unsafe_fn();
= note: consult the function's documentation for information on how to avoid undefined behavior
error: unnecessary `unsafe` block
--> $DIR/unsafe-env.rs:26:5
--> $DIR/unsafe-env.rs:36:5
|
LL | unsafe {
| ^^^^^^ unnecessary `unsafe` block
|
note: the lint level is defined here
--> $DIR/unsafe-env.rs:11:8
--> $DIR/unsafe-env.rs:21:8
|
LL | #[deny(unused_unsafe)]
| ^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0133`.

View File

@ -1,5 +1,42 @@
error[E0133]: call to unsafe function `std::env::set_var` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:10:5
|
LL | env::set_var("FOO", "BAR");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
= note: consult the function's documentation for information on how to avoid undefined behavior
note: an unsafe function restricts its caller, but its body is safe by default
--> $DIR/unsafe-env.rs:9:1
|
LL | unsafe fn unsafe_fn() {
| ^^^^^^^^^^^^^^^^^^^^^
note: the lint level is defined here
--> $DIR/unsafe-env.rs:8:8
|
LL | #[deny(unsafe_op_in_unsafe_fn)]
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0133]: call to unsafe function `std::env::remove_var` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:12:5
|
LL | env::remove_var("FOO");
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:15:9
|
LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function
|
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `set_var` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:13:5
--> $DIR/unsafe-env.rs:23:5
|
LL | env::set_var("FOO", "BAR");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
@ -7,7 +44,7 @@ LL | env::set_var("FOO", "BAR");
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `remove_var` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:15:5
--> $DIR/unsafe-env.rs:25:5
|
LL | env::remove_var("FOO");
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
@ -15,7 +52,7 @@ LL | env::remove_var("FOO");
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:23:5
--> $DIR/unsafe-env.rs:33:5
|
LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function
@ -23,17 +60,17 @@ LL | unsafe_fn();
= note: consult the function's documentation for information on how to avoid undefined behavior
error: unnecessary `unsafe` block
--> $DIR/unsafe-env.rs:26:5
--> $DIR/unsafe-env.rs:36:5
|
LL | unsafe {
| ^^^^^^ unnecessary `unsafe` block
|
note: the lint level is defined here
--> $DIR/unsafe-env.rs:11:8
--> $DIR/unsafe-env.rs:21:8
|
LL | #[deny(unused_unsafe)]
| ^^^^^^^^^^^^^
error: aborting due to 4 previous errors
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0133`.

View File

@ -5,7 +5,17 @@
use std::env;
unsafe fn unsafe_fn() {}
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn unsafe_fn() {
env::set_var("FOO", "BAR");
//[e2024]~^ ERROR call to unsafe function `std::env::set_var` is unsafe
env::remove_var("FOO");
//[e2024]~^ ERROR call to unsafe function `std::env::remove_var` is unsafe
if false {
unsafe_fn();
//~^ ERROR call to unsafe function `unsafe_fn` is unsafe
}
}
fn safe_fn() {}
#[deny(unused_unsafe)]