From 1afc7d716cfb7858863754217566b785bac179a4 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 3 Jun 2024 22:27:57 -0300 Subject: [PATCH] Make MISSING_UNSAFE_ON_EXTERN lint emit future compat info with suggestion to prepend unsafe --- compiler/rustc_ast_passes/messages.ftl | 2 ++ .../rustc_ast_passes/src/ast_validation.rs | 19 +++++++++++++------ compiler/rustc_ast_passes/src/errors.rs | 7 +++++++ compiler/rustc_lint/messages.ftl | 1 + .../rustc_lint/src/context/diagnostics.rs | 4 ++-- compiler/rustc_lint/src/lints.rs | 5 ++++- compiler/rustc_lint_defs/src/builtin.rs | 8 ++++++-- compiler/rustc_lint_defs/src/lib.rs | 4 +++- .../extern-items.edition2024.stderr | 4 +--- .../unsafe-extern-blocks/extern-items.rs | 2 +- 10 files changed, 40 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index b90b502c22b..9a8689e27c0 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -177,6 +177,8 @@ ast_passes_match_arm_with_no_body = `match` arm with no body .suggestion = add a body after the pattern +ast_passes_missing_unsafe_on_extern = extern blocks must be unsafe + ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name .help = consider using the `#[path]` attribute to specify filesystem path diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index dc554ba04df..0fbb288cc96 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1044,12 +1044,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if this.features.unsafe_extern_blocks { if &Safety::Default == safety { - this.lint_buffer.buffer_lint( - MISSING_UNSAFE_ON_EXTERN, - item.id, - item.span, - BuiltinLintDiag::MissingUnsafeOnExtern, - ); + if item.span.at_least_rust_2024() { + this.dcx() + .emit_err(errors::MissingUnsafeOnExtern { span: item.span }); + } else { + this.lint_buffer.buffer_lint( + MISSING_UNSAFE_ON_EXTERN, + item.id, + item.span, + BuiltinLintDiag::MissingUnsafeOnExtern { + suggestion: item.span.shrink_to_lo(), + }, + ); + } } } else if let &Safety::Unsafe(span) = safety { this.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" }); diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 05e99a3d636..260c182bd9e 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -494,6 +494,13 @@ pub struct UnsafeItem { pub kind: &'static str, } +#[derive(Diagnostic)] +#[diag(ast_passes_missing_unsafe_on_extern)] +pub struct MissingUnsafeOnExtern { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(ast_passes_fieldless_union)] pub struct FieldlessUnion { diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index bb6ad7c945b..522f2f84cca 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -463,6 +463,7 @@ lint_metavariable_wrong_operator = meta-variable repeats with different Kleene o lint_missing_fragment_specifier = missing fragment specifier lint_missing_unsafe_on_extern = extern blocks should be unsafe + .suggestion = needs `unsafe` before the extern keyword lint_mixed_script_confusables = the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index f824e02dcf9..c38804e7714 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -205,8 +205,8 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & }; lints::DeprecatedWhereClauseLocation { suggestion }.decorate_lint(diag); } - BuiltinLintDiag::MissingUnsafeOnExtern => { - lints::MissingUnsafeOnExtern.decorate_lint(diag); + BuiltinLintDiag::MissingUnsafeOnExtern { suggestion } => { + lints::MissingUnsafeOnExtern { suggestion }.decorate_lint(diag); } BuiltinLintDiag::SingleUseLifetime { param_span, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 01b455c588b..985b66a54e1 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2740,7 +2740,10 @@ pub enum DeprecatedWhereClauseLocationSugg { #[derive(LintDiagnostic)] #[diag(lint_missing_unsafe_on_extern)] -pub struct MissingUnsafeOnExtern; +pub struct MissingUnsafeOnExtern { + #[suggestion(code = "unsafe ", applicability = "machine-applicable")] + pub suggestion: Span, +} #[derive(LintDiagnostic)] #[diag(lint_single_use_lifetime)] diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index ec124c3224c..7082a068c48 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4858,8 +4858,9 @@ declare_lint! { /// /// ### Example /// - /// ```rust,edition2024,ignore + /// ```rust /// #![feature(unsafe_extern_blocks)] + /// #![warn(missing_unsafe_on_extern)] /// #![allow(dead_code)] /// /// extern "C" { @@ -4883,5 +4884,8 @@ declare_lint! { pub MISSING_UNSAFE_ON_EXTERN, Allow, "detects missing unsafe keyword on extern declarations", - @edition Edition2024 => Deny; + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), + reference: "issue #123743 ", + }; } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 0f13046923e..67e1bfee620 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -630,7 +630,9 @@ pub enum BuiltinLintDiag { UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>), UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>), DeprecatedWhereclauseLocation(Span, Option<(Span, String)>), - MissingUnsafeOnExtern, + MissingUnsafeOnExtern { + suggestion: Span, + }, SingleUseLifetime { /// Span of the parameter which declares this lifetime. param_span: Span, diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr index 8e1ec814635..d456cfc6829 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr @@ -1,4 +1,4 @@ -error: extern blocks should be unsafe +error: extern blocks must be unsafe --> $DIR/extern-items.rs:9:1 | LL | / extern "C" { @@ -7,8 +7,6 @@ LL | | static TEST1: i32; LL | | fn test1(i: i32); LL | | } | |_^ - | - = note: `#[deny(missing_unsafe_on_extern)]` on by default error: aborting due to 1 previous error diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs index 905d1434155..16fa1bbb8a4 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs @@ -7,7 +7,7 @@ #![feature(unsafe_extern_blocks)] extern "C" { - //[edition2024]~^ ERROR extern blocks should be unsafe + //[edition2024]~^ ERROR extern blocks must be unsafe static TEST1: i32; fn test1(i: i32); }