Skip to content

Commit 3ba8de0

Browse files
committed
Make extern blocks without unsafe warn in edition 2024
1 parent 46cd80b commit 3ba8de0

File tree

10 files changed

+78
-7
lines changed

10 files changed

+78
-7
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use rustc_data_structures::fx::FxIndexMap;
1515
use rustc_feature::Features;
1616
use rustc_parse::validate_attr;
1717
use rustc_session::lint::builtin::{
18-
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
18+
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN,
19+
PATTERNS_IN_FNS_WITHOUT_BODY,
1920
};
2021
use rustc_session::lint::{BuiltinLintDiag, LintBuffer};
2122
use rustc_session::Session;
@@ -1016,12 +1017,22 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10161017
walk_list!(self, visit_attribute, &item.attrs);
10171018
return; // Avoid visiting again.
10181019
}
1019-
ItemKind::ForeignMod(ForeignMod { abi, .. }) => {
1020+
ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => {
10201021
let old_item = mem::replace(&mut self.extern_mod, Some(item));
10211022
self.visibility_not_permitted(
10221023
&item.vis,
10231024
errors::VisibilityNotPermittedNote::IndividualForeignItems,
10241025
);
1026+
1027+
if &Safety::Default == safety {
1028+
self.lint_buffer.buffer_lint(
1029+
MISSING_UNSAFE_ON_EXTERN,
1030+
item.id,
1031+
item.span,
1032+
BuiltinLintDiag::MissingUnsafeOnExtern,
1033+
);
1034+
}
1035+
10251036
if abi.is_none() {
10261037
self.maybe_lint_missing_abi(item.span, item.id);
10271038
}

compiler/rustc_lint/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,8 @@ lint_metavariable_wrong_operator = meta-variable repeats with different Kleene o
462462
463463
lint_missing_fragment_specifier = missing fragment specifier
464464
465+
lint_missing_unsafe_on_extern = extern blocks should be unsafe
466+
465467
lint_mixed_script_confusables =
466468
the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables
467469
.includes_note = the usage includes {$includes}

compiler/rustc_lint/src/context/diagnostics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
205205
};
206206
lints::DeprecatedWhereClauseLocation { suggestion }.decorate_lint(diag);
207207
}
208+
BuiltinLintDiag::MissingUnsafeOnExtern => {
209+
lints::MissingUnsafeOnExtern.decorate_lint(diag);
210+
}
208211
BuiltinLintDiag::SingleUseLifetime {
209212
param_span,
210213
use_span: Some((use_span, elide)),

compiler/rustc_lint/src/lints.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2738,6 +2738,10 @@ pub enum DeprecatedWhereClauseLocationSugg {
27382738
},
27392739
}
27402740

2741+
#[derive(LintDiagnostic)]
2742+
#[diag(lint_missing_unsafe_on_extern)]
2743+
pub struct MissingUnsafeOnExtern;
2744+
27412745
#[derive(LintDiagnostic)]
27422746
#[diag(lint_single_use_lifetime)]
27432747
pub struct SingleUseLifetime {

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ declare_lint_pass! {
6666
META_VARIABLE_MISUSE,
6767
MISSING_ABI,
6868
MISSING_FRAGMENT_SPECIFIER,
69+
MISSING_UNSAFE_ON_EXTERN,
6970
MUST_NOT_SUSPEND,
7071
NAMED_ARGUMENTS_USED_POSITIONALLY,
7172
NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
@@ -4851,3 +4852,33 @@ declare_lint! {
48514852
reference: "issue #27970 <https://github.com/rust-lang/rust/issues/27970>",
48524853
};
48534854
}
4855+
4856+
declare_lint! {
4857+
/// The `missing_unsafe_on_extern` lint detects missing unsafe keyword on extern declarations.
4858+
///
4859+
/// ### Example
4860+
///
4861+
/// ```rust,edition2024
4862+
/// extern "C" {
4863+
/// fn foo(_: i32);
4864+
/// }
4865+
///
4866+
/// fn main() {}
4867+
/// ```
4868+
///
4869+
/// {{produces}}
4870+
///
4871+
/// ### Explanation
4872+
///
4873+
/// Declaring extern items, even without ever using them, can cause Undefined Behavior. We
4874+
/// should consider all sources of Undefined Behavior to be unsafe.
4875+
///
4876+
/// This is a [future-incompatible] lint to transition this to a
4877+
/// hard error in the future.
4878+
///
4879+
/// [future-incompatible]: ../index.md#future-incompatible-lints
4880+
pub MISSING_UNSAFE_ON_EXTERN,
4881+
Allow,
4882+
"detects missing unsafe keyword on extern declarations",
4883+
@edition Edition2024 => Warn;
4884+
}

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ pub enum BuiltinLintDiag {
630630
UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>),
631631
UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>),
632632
DeprecatedWhereclauseLocation(Span, Option<(Span, String)>),
633+
MissingUnsafeOnExtern,
633634
SingleUseLifetime {
634635
/// Span of the parameter which declares this lifetime.
635636
param_span: Span,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
warning: extern blocks should be unsafe
2+
--> $DIR/extern-items.rs:7:1
3+
|
4+
LL | / extern "C" {
5+
LL | |
6+
LL | | static TEST1: i32;
7+
LL | | fn test1(i: i32);
8+
LL | | }
9+
| |_^
10+
|
11+
= note: `#[warn(missing_unsafe_on_extern)]` on by default
12+
13+
warning: 1 warning emitted
14+

tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
//@ build-pass
1+
//@ revisions: edition2021 edition2024
2+
//@[edition2021] edition:2021
3+
//@[edition2024] edition:2024
4+
//@[edition2024] compile-flags: -Zunstable-options
5+
//@ check-pass
26

37
extern "C" {
8+
//[edition2024]~^ WARN extern blocks should be unsafe [missing_unsafe_on_extern]
49
static TEST1: i32;
510
fn test1(i: i32);
611
}

tests/ui/unpretty/expanded-exhaustive.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,8 @@ mod items {
473473

474474
/// ItemKind::ForeignMod
475475
mod item_foreign_mod {
476-
extern "C++" {}
477-
extern {}
476+
unsafe extern "C++" {}
477+
unsafe extern {}
478478
}
479479

480480
/// ItemKind::GlobalAsm

tests/ui/unpretty/expanded-exhaustive.stdout

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,8 @@ mod items {
451451
mod item_mod { }
452452
/// ItemKind::ForeignMod
453453
mod item_foreign_mod {
454-
extern "C++" {}
455-
extern {}
454+
unsafe extern "C++" {}
455+
unsafe extern {}
456456
}
457457
/// ItemKind::GlobalAsm
458458
mod item_global_asm {

0 commit comments

Comments
 (0)