diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2024-05-21 12:27:21 -0300 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2024-06-04 14:19:42 -0300 |
| commit | 3ba8de0b601ee1eaae710510ee8b0b8a9dbd78d8 (patch) | |
| tree | 0d54ec1a2a419e718a44e79e51699ca84479f287 | |
| parent | 46cd80b691f0e127076b6dcd1bf9285c3e608d4a (diff) | |
| download | rust-3ba8de0b601ee1eaae710510ee8b0b8a9dbd78d8.tar.gz rust-3ba8de0b601ee1eaae710510ee8b0b8a9dbd78d8.zip | |
Make extern blocks without unsafe warn in edition 2024
| -rw-r--r-- | compiler/rustc_ast_passes/src/ast_validation.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_lint/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/context/diagnostics.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lints.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_lint_defs/src/builtin.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_lint_defs/src/lib.rs | 1 | ||||
| -rw-r--r-- | tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr | 14 | ||||
| -rw-r--r-- | tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs | 7 | ||||
| -rw-r--r-- | tests/ui/unpretty/expanded-exhaustive.rs | 4 | ||||
| -rw-r--r-- | tests/ui/unpretty/expanded-exhaustive.stdout | 4 |
10 files changed, 78 insertions, 7 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index c0011fd9c45..7e1094da202 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -15,7 +15,8 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_feature::Features; use rustc_parse::validate_attr; use rustc_session::lint::builtin::{ - DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY, + DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN, + PATTERNS_IN_FNS_WITHOUT_BODY, }; use rustc_session::lint::{BuiltinLintDiag, LintBuffer}; use rustc_session::Session; @@ -1016,12 +1017,22 @@ impl<'a> Visitor<'a> for AstValidator<'a> { walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. } - ItemKind::ForeignMod(ForeignMod { abi, .. }) => { + ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => { let old_item = mem::replace(&mut self.extern_mod, Some(item)); self.visibility_not_permitted( &item.vis, errors::VisibilityNotPermittedNote::IndividualForeignItems, ); + + if &Safety::Default == safety { + self.lint_buffer.buffer_lint( + MISSING_UNSAFE_ON_EXTERN, + item.id, + item.span, + BuiltinLintDiag::MissingUnsafeOnExtern, + ); + } + if abi.is_none() { self.maybe_lint_missing_abi(item.span, item.id); } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index fb71cb60140..bb6ad7c945b 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -462,6 +462,8 @@ 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 + lint_mixed_script_confusables = the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables .includes_note = the usage includes {$includes} diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 26f34486a3d..f824e02dcf9 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -205,6 +205,9 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & }; lints::DeprecatedWhereClauseLocation { suggestion }.decorate_lint(diag); } + BuiltinLintDiag::MissingUnsafeOnExtern => { + lints::MissingUnsafeOnExtern.decorate_lint(diag); + } BuiltinLintDiag::SingleUseLifetime { param_span, use_span: Some((use_span, elide)), diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 84d46ef3b65..01b455c588b 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2739,6 +2739,10 @@ pub enum DeprecatedWhereClauseLocationSugg { } #[derive(LintDiagnostic)] +#[diag(lint_missing_unsafe_on_extern)] +pub struct MissingUnsafeOnExtern; + +#[derive(LintDiagnostic)] #[diag(lint_single_use_lifetime)] pub struct SingleUseLifetime { #[label(lint_label_param)] diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a3044489fdc..b4a34b1407d 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -66,6 +66,7 @@ declare_lint_pass! { META_VARIABLE_MISUSE, MISSING_ABI, MISSING_FRAGMENT_SPECIFIER, + MISSING_UNSAFE_ON_EXTERN, MUST_NOT_SUSPEND, NAMED_ARGUMENTS_USED_POSITIONALLY, NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, @@ -4851,3 +4852,33 @@ declare_lint! { reference: "issue #27970 <https://github.com/rust-lang/rust/issues/27970>", }; } + +declare_lint! { + /// The `missing_unsafe_on_extern` lint detects missing unsafe keyword on extern declarations. + /// + /// ### Example + /// + /// ```rust,edition2024 + /// extern "C" { + /// fn foo(_: i32); + /// } + /// + /// fn main() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Declaring extern items, even without ever using them, can cause Undefined Behavior. We + /// should consider all sources of Undefined Behavior to be unsafe. + /// + /// This is a [future-incompatible] lint to transition this to a + /// hard error in the future. + /// + /// [future-incompatible]: ../index.md#future-incompatible-lints + pub MISSING_UNSAFE_ON_EXTERN, + Allow, + "detects missing unsafe keyword on extern declarations", + @edition Edition2024 => Warn; +} diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index c8a9fb02bf2..0f13046923e 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -630,6 +630,7 @@ pub enum BuiltinLintDiag { UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>), UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>), DeprecatedWhereclauseLocation(Span, Option<(Span, String)>), + MissingUnsafeOnExtern, 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 new file mode 100644 index 00000000000..b19369c0a55 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr @@ -0,0 +1,14 @@ +warning: extern blocks should be unsafe + --> $DIR/extern-items.rs:7:1 + | +LL | / extern "C" { +LL | | +LL | | static TEST1: i32; +LL | | fn test1(i: i32); +LL | | } + | |_^ + | + = note: `#[warn(missing_unsafe_on_extern)]` on by default + +warning: 1 warning emitted + 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 fd2cd29fd74..dfb851e276d 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs @@ -1,6 +1,11 @@ -//@ build-pass +//@ revisions: edition2021 edition2024 +//@[edition2021] edition:2021 +//@[edition2024] edition:2024 +//@[edition2024] compile-flags: -Zunstable-options +//@ check-pass extern "C" { + //[edition2024]~^ WARN extern blocks should be unsafe [missing_unsafe_on_extern] static TEST1: i32; fn test1(i: i32); } diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs index 6aa032d7ed8..29472df897a 100644 --- a/tests/ui/unpretty/expanded-exhaustive.rs +++ b/tests/ui/unpretty/expanded-exhaustive.rs @@ -473,8 +473,8 @@ mod items { /// ItemKind::ForeignMod mod item_foreign_mod { - extern "C++" {} - extern {} + unsafe extern "C++" {} + unsafe extern {} } /// ItemKind::GlobalAsm diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout index 8737063bf3c..0a09a3f6a42 100644 --- a/tests/ui/unpretty/expanded-exhaustive.stdout +++ b/tests/ui/unpretty/expanded-exhaustive.stdout @@ -451,8 +451,8 @@ mod items { mod item_mod { } /// ItemKind::ForeignMod mod item_foreign_mod { - extern "C++" {} - extern {} + unsafe extern "C++" {} + unsafe extern {} } /// ItemKind::GlobalAsm mod item_global_asm { |
