Skip to content

Commit c4a8d7f

Browse files
Introduce missing ABI lint on extern blocks
1 parent 9f3998b commit c4a8d7f

File tree

7 files changed

+68
-7
lines changed

7 files changed

+68
-7
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3896,6 +3896,7 @@ dependencies = [
38963896
"rustc_macros",
38973897
"rustc_serialize",
38983898
"rustc_span",
3899+
"rustc_target",
38993900
"tracing",
39003901
]
39013902

compiler/rustc_ast_lowering/src/item.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
317317
})
318318
}
319319
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
320-
ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod {
321-
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
322-
items: self
323-
.arena
324-
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
325-
},
320+
ItemKind::ForeignMod(ref fm) => {
321+
if fm.abi.is_none() {
322+
self.maybe_lint_missing_abi(span, id, abi::Abi::C);
323+
}
324+
hir::ItemKind::ForeignMod {
325+
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
326+
items: self
327+
.arena
328+
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
329+
}
330+
}
326331
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
327332
ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => {
328333
// We lower

compiler/rustc_ast_lowering/src/lib.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,15 @@ use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
5353
use rustc_hir::intravisit;
5454
use rustc_hir::{ConstArg, GenericArg, ParamName};
5555
use rustc_index::vec::{Idx, IndexVec};
56-
use rustc_session::lint::{builtin::BARE_TRAIT_OBJECTS, BuiltinLintDiagnostics, LintBuffer};
56+
use rustc_session::lint::builtin::{BARE_TRAIT_OBJECTS, MISSING_ABI};
57+
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
5758
use rustc_session::parse::ParseSess;
5859
use rustc_session::Session;
5960
use rustc_span::hygiene::ExpnId;
6061
use rustc_span::source_map::{respan, DesugaringKind};
6162
use rustc_span::symbol::{kw, sym, Ident, Symbol};
6263
use rustc_span::Span;
64+
use rustc_target::spec::abi::Abi;
6365

6466
use smallvec::{smallvec, SmallVec};
6567
use std::collections::BTreeMap;
@@ -2777,6 +2779,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
27772779
)
27782780
}
27792781
}
2782+
2783+
fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId, default: Abi) {
2784+
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
2785+
// call site which do not have a macro backtrace. See #61963.
2786+
let is_macro_callsite = self
2787+
.sess
2788+
.source_map()
2789+
.span_to_snippet(span)
2790+
.map(|snippet| snippet.starts_with("#["))
2791+
.unwrap_or(true);
2792+
if !is_macro_callsite {
2793+
self.resolver.lint_buffer().buffer_lint_with_diagnostic(
2794+
MISSING_ABI,
2795+
id,
2796+
span,
2797+
"extern declarations without an explicit ABI are deprecated",
2798+
BuiltinLintDiagnostics::MissingAbi(span, default),
2799+
)
2800+
}
2801+
}
27802802
}
27812803

27822804
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'_>>) -> Vec<hir::BodyId> {

compiler/rustc_lint/src/context.rs

+4
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,10 @@ pub trait LintContext: Sized {
600600
BuiltinLintDiagnostics::PatternsInFnsWithoutBody(span, ident) => {
601601
db.span_suggestion(span, "remove `mut` from the parameter", ident.to_string(), Applicability::MachineApplicable);
602602
}
603+
BuiltinLintDiagnostics::MissingAbi(span, default_abi) => {
604+
db.span_label(span, "ABI should be specified here");
605+
db.help(&format!("the default ABI is {}", default_abi.name()));
606+
}
603607
}
604608
// Rewrap `db`, and pass control to the user.
605609
decorate(LintDiagnosticBuilder::new(db));

compiler/rustc_lint_defs/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ rustc_data_structures = { path = "../rustc_data_structures" }
1111
rustc_span = { path = "../rustc_span" }
1212
rustc_serialize = { path = "../rustc_serialize" }
1313
rustc_macros = { path = "../rustc_macros" }
14+
rustc_target = { path = "../rustc_target" }

compiler/rustc_lint_defs/src/builtin.rs

+26
Original file line numberDiff line numberDiff line change
@@ -2917,6 +2917,7 @@ declare_lint_pass! {
29172917
FUNCTION_ITEM_REFERENCES,
29182918
USELESS_DEPRECATED,
29192919
UNSUPPORTED_NAKED_FUNCTIONS,
2920+
MISSING_ABI,
29202921
]
29212922
}
29222923

@@ -2944,3 +2945,28 @@ declare_lint! {
29442945
}
29452946

29462947
declare_lint_pass!(UnusedDocComment => [UNUSED_DOC_COMMENTS]);
2948+
2949+
declare_lint! {
2950+
/// The `missing_abi` lint detects cases where the ABI is omitted from
2951+
/// extern declarations.
2952+
///
2953+
/// ### Example
2954+
///
2955+
/// ```rust,compile_fail
2956+
/// #![deny(missing_abi)]
2957+
///
2958+
/// extern fn foo() {}
2959+
/// ```
2960+
///
2961+
/// {{produces}}
2962+
///
2963+
/// ### Explanation
2964+
///
2965+
/// Historically, Rust implicitly selected C as the ABI for extern
2966+
/// declarations. We expect to add new ABIs, like `C-unwind`, in the future,
2967+
/// though this has not yet happened, and especially with their addition
2968+
/// seeing the ABI easily will make code review easier.
2969+
pub MISSING_ABI,
2970+
Allow,
2971+
"No declared ABI for extern declaration"
2972+
}

compiler/rustc_lint_defs/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_ast::node_id::{NodeId, NodeMap};
66
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
77
use rustc_span::edition::Edition;
88
use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
9+
use rustc_target::spec::abi::Abi;
910

1011
pub mod builtin;
1112

@@ -252,6 +253,7 @@ pub enum BuiltinLintDiagnostics {
252253
UnusedImports(String, Vec<(Span, String)>),
253254
RedundantImport(Vec<(Span, bool)>, Ident),
254255
DeprecatedMacro(Option<Symbol>, Span),
256+
MissingAbi(Span, Abi),
255257
UnusedDocComment(Span),
256258
PatternsInFnsWithoutBody(Span, Ident),
257259
}

0 commit comments

Comments
 (0)