diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 7da726ef40868..667803388a2a8 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -71,6 +71,8 @@ ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have quali .suggestion = remove this qualifier ast_passes_extern_invalid_safety = items in unadorned `extern` blocks cannot have safety qualifiers + +ast_passes_extern_invalid_safety_with_suggestion = items in unadorned `extern` blocks cannot have safety qualifiers .suggestion = add unsafe to this `extern` block ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index d02b8510975fc..ab2c6a9e5d300 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -459,13 +459,15 @@ impl<'a> AstValidator<'a> { fn check_item_safety(&self, span: Span, safety: Safety) { match self.extern_mod_safety { Some(extern_safety) => { - if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_)) - && (extern_safety == Safety::Default || !self.features.unsafe_extern_blocks) - { - self.dcx().emit_err(errors::InvalidSafetyOnExtern { - item_span: span, - block: self.current_extern_span().shrink_to_lo(), - }); + if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_)) { + if extern_safety == Safety::Default { + self.dcx().emit_err(errors::InvalidSafetyOnExternWithSuggestion { + item_span: span, + block: self.current_extern_span().shrink_to_lo(), + }); + } else if !self.features.unsafe_extern_blocks { + self.dcx().emit_err(errors::InvalidSafetyOnExtern { item_span: span }); + } } } None => { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 965d8fac712ae..abd5c4f6333e1 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -221,6 +221,13 @@ pub enum ExternBlockSuggestion { pub struct InvalidSafetyOnExtern { #[primary_span] pub item_span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_extern_invalid_safety_with_suggestion)] +pub struct InvalidSafetyOnExternWithSuggestion { + #[primary_span] + pub item_span: Span, #[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")] pub block: Span, } diff --git a/tests/ui/parser/unsafe-foreign-mod-2.stderr b/tests/ui/parser/unsafe-foreign-mod-2.stderr index 07dbd5568d053..8bd592b5d4311 100644 --- a/tests/ui/parser/unsafe-foreign-mod-2.stderr +++ b/tests/ui/parser/unsafe-foreign-mod-2.stderr @@ -19,11 +19,6 @@ error: items in unadorned `extern` blocks cannot have safety qualifiers | LL | unsafe fn foo(); | ^^^^^^^^^^^^^^^^ - | -help: add unsafe to this `extern` block - | -LL | unsafe extern "C" unsafe { - | ++++++ error: aborting due to 3 previous errors