Fix #[rustc_deprecated_safe_2024]

It should be considered by the edition of the caller, not the callee.

Technically we still don't do it correctly - we need the span of the method name (if it comes from a macro), but we don't keep it and this is good enough for now.
This commit is contained in:
Chayim Refael Friedman 2025-01-27 14:34:33 +02:00
parent 6862329068
commit 55c63abc59
16 changed files with 274 additions and 100 deletions

View file

@ -1,5 +1,5 @@
use hir::db::ExpandDatabase;
use hir::{HirFileIdExt, UnsafetyReason};
use hir::{HirFileIdExt, UnsafeLint, UnsafetyReason};
use ide_db::text_edit::TextEdit;
use ide_db::{assists::Assist, source_change::SourceChange};
use syntax::{ast, SyntaxNode};
@ -11,10 +11,10 @@ use crate::{fix, Diagnostic, DiagnosticCode, DiagnosticsContext};
//
// This diagnostic is triggered if an operation marked as `unsafe` is used outside of an `unsafe` function or block.
pub(crate) fn missing_unsafe(ctx: &DiagnosticsContext<'_>, d: &hir::MissingUnsafe) -> Diagnostic {
let code = if d.only_lint {
DiagnosticCode::RustcLint("unsafe_op_in_unsafe_fn")
} else {
DiagnosticCode::RustcHardError("E0133")
let code = match d.lint {
UnsafeLint::HardError => DiagnosticCode::RustcHardError("E0133"),
UnsafeLint::UnsafeOpInUnsafeFn => DiagnosticCode::RustcLint("unsafe_op_in_unsafe_fn"),
UnsafeLint::DeprecatedSafe2024 => DiagnosticCode::RustcLint("deprecated_safe_2024"),
};
let operation = display_unsafety_reason(d.reason);
Diagnostic::new_with_syntax_node_ptr(
@ -585,24 +585,58 @@ fn main() {
r#"
//- /ed2021.rs crate:ed2021 edition:2021
#[rustc_deprecated_safe_2024]
unsafe fn safe() -> u8 {
unsafe fn deprecated_safe() -> u8 {
0
}
//- /ed2024.rs crate:ed2024 edition:2024
#[rustc_deprecated_safe_2024]
unsafe fn not_safe() -> u8 {
unsafe fn deprecated_safe() -> u8 {
0
}
//- /main.rs crate:main deps:ed2021,ed2024
//- /dep1.rs crate:dep1 deps:ed2021,ed2024 edition:2021
fn main() {
ed2021::safe();
ed2024::not_safe();
//^^^^^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block
ed2021::deprecated_safe();
ed2024::deprecated_safe();
}
//- /dep2.rs crate:dep2 deps:ed2021,ed2024 edition:2024
fn main() {
ed2021::deprecated_safe();
// ^^^^^^^^^^^^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block
ed2024::deprecated_safe();
// ^^^^^^^^^^^^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block
}
//- /dep3.rs crate:dep3 deps:ed2021,ed2024 edition:2021
#![warn(deprecated_safe)]
fn main() {
ed2021::deprecated_safe();
// ^^^^^^^^^^^^^^^^^^^^^^^^^💡 warn: call to unsafe function is unsafe and requires an unsafe function or block
ed2024::deprecated_safe();
// ^^^^^^^^^^^^^^^^^^^^^^^^^💡 warn: call to unsafe function is unsafe and requires an unsafe function or block
}
"#,
)
}
#[test]
fn orphan_unsafe_format_args() {
// Checks that we don't place orphan arguments for formatting under an unsafe block.
check_diagnostics(
r#"
//- minicore: fmt
fn foo() {
let p = 0xDEADBEEF as *const i32;
format_args!("", *p);
// ^^ error: dereference of raw pointer is unsafe and requires an unsafe function or block
}
"#,
);
}
#[test]
fn unsafe_op_in_unsafe_fn_allowed_by_default_in_edition_2021() {
check_diagnostics(