Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-diagnostics/src/handlers/missing_unsafe.rs')
| -rw-r--r-- | crates/ide-diagnostics/src/handlers/missing_unsafe.rs | 88 |
1 files changed, 77 insertions, 11 deletions
diff --git a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs index 8117401a53..323a5723d4 100644 --- a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs +++ b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs @@ -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,25 +585,59 @@ 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::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::safe(); - ed2024::not_safe(); - //^^^^^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block + 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( r#" @@ -812,4 +846,36 @@ fn main() { "#, ) } + + #[test] + fn target_feature() { + check_diagnostics( + r#" +#[target_feature(enable = "avx")] +fn foo() {} + +#[target_feature(enable = "avx,avx2")] +fn bar() { + foo(); +} + +fn baz() { + foo(); + // ^^^^^ 💡 error: call to unsafe function is unsafe and requires an unsafe function or block +} + "#, + ); + } + + #[test] + fn unsafe_fn_ptr_call() { + check_diagnostics( + r#" +fn f(it: unsafe fn()){ + it(); + // ^^^^ 💡 error: call to unsafe function is unsafe and requires an unsafe function or block +} + "#, + ); + } } |