mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Introduce missing ABI lint on extern blocks
This commit is contained in:
parent
9f3998b4aa
commit
c4a8d7f86a
@ -3896,6 +3896,7 @@ dependencies = [
|
|||||||
"rustc_macros",
|
"rustc_macros",
|
||||||
"rustc_serialize",
|
"rustc_serialize",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
|
"rustc_target",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -317,12 +317,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
|
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
|
||||||
ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod {
|
ItemKind::ForeignMod(ref fm) => {
|
||||||
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
|
if fm.abi.is_none() {
|
||||||
items: self
|
self.maybe_lint_missing_abi(span, id, abi::Abi::C);
|
||||||
.arena
|
}
|
||||||
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
|
hir::ItemKind::ForeignMod {
|
||||||
},
|
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
|
||||||
|
items: self
|
||||||
|
.arena
|
||||||
|
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
|
||||||
|
}
|
||||||
|
}
|
||||||
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
|
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
|
||||||
ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => {
|
ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => {
|
||||||
// We lower
|
// We lower
|
||||||
|
@ -53,13 +53,15 @@ use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
|
|||||||
use rustc_hir::intravisit;
|
use rustc_hir::intravisit;
|
||||||
use rustc_hir::{ConstArg, GenericArg, ParamName};
|
use rustc_hir::{ConstArg, GenericArg, ParamName};
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_session::lint::{builtin::BARE_TRAIT_OBJECTS, BuiltinLintDiagnostics, LintBuffer};
|
use rustc_session::lint::builtin::{BARE_TRAIT_OBJECTS, MISSING_ABI};
|
||||||
|
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::hygiene::ExpnId;
|
use rustc_span::hygiene::ExpnId;
|
||||||
use rustc_span::source_map::{respan, DesugaringKind};
|
use rustc_span::source_map::{respan, DesugaringKind};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
@ -2777,6 +2779,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId, default: Abi) {
|
||||||
|
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
|
||||||
|
// call site which do not have a macro backtrace. See #61963.
|
||||||
|
let is_macro_callsite = self
|
||||||
|
.sess
|
||||||
|
.source_map()
|
||||||
|
.span_to_snippet(span)
|
||||||
|
.map(|snippet| snippet.starts_with("#["))
|
||||||
|
.unwrap_or(true);
|
||||||
|
if !is_macro_callsite {
|
||||||
|
self.resolver.lint_buffer().buffer_lint_with_diagnostic(
|
||||||
|
MISSING_ABI,
|
||||||
|
id,
|
||||||
|
span,
|
||||||
|
"extern declarations without an explicit ABI are deprecated",
|
||||||
|
BuiltinLintDiagnostics::MissingAbi(span, default),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'_>>) -> Vec<hir::BodyId> {
|
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'_>>) -> Vec<hir::BodyId> {
|
||||||
|
@ -600,6 +600,10 @@ pub trait LintContext: Sized {
|
|||||||
BuiltinLintDiagnostics::PatternsInFnsWithoutBody(span, ident) => {
|
BuiltinLintDiagnostics::PatternsInFnsWithoutBody(span, ident) => {
|
||||||
db.span_suggestion(span, "remove `mut` from the parameter", ident.to_string(), Applicability::MachineApplicable);
|
db.span_suggestion(span, "remove `mut` from the parameter", ident.to_string(), Applicability::MachineApplicable);
|
||||||
}
|
}
|
||||||
|
BuiltinLintDiagnostics::MissingAbi(span, default_abi) => {
|
||||||
|
db.span_label(span, "ABI should be specified here");
|
||||||
|
db.help(&format!("the default ABI is {}", default_abi.name()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Rewrap `db`, and pass control to the user.
|
// Rewrap `db`, and pass control to the user.
|
||||||
decorate(LintDiagnosticBuilder::new(db));
|
decorate(LintDiagnosticBuilder::new(db));
|
||||||
|
@ -11,3 +11,4 @@ rustc_data_structures = { path = "../rustc_data_structures" }
|
|||||||
rustc_span = { path = "../rustc_span" }
|
rustc_span = { path = "../rustc_span" }
|
||||||
rustc_serialize = { path = "../rustc_serialize" }
|
rustc_serialize = { path = "../rustc_serialize" }
|
||||||
rustc_macros = { path = "../rustc_macros" }
|
rustc_macros = { path = "../rustc_macros" }
|
||||||
|
rustc_target = { path = "../rustc_target" }
|
||||||
|
@ -2917,6 +2917,7 @@ declare_lint_pass! {
|
|||||||
FUNCTION_ITEM_REFERENCES,
|
FUNCTION_ITEM_REFERENCES,
|
||||||
USELESS_DEPRECATED,
|
USELESS_DEPRECATED,
|
||||||
UNSUPPORTED_NAKED_FUNCTIONS,
|
UNSUPPORTED_NAKED_FUNCTIONS,
|
||||||
|
MISSING_ABI,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2944,3 +2945,28 @@ declare_lint! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare_lint_pass!(UnusedDocComment => [UNUSED_DOC_COMMENTS]);
|
declare_lint_pass!(UnusedDocComment => [UNUSED_DOC_COMMENTS]);
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `missing_abi` lint detects cases where the ABI is omitted from
|
||||||
|
/// extern declarations.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust,compile_fail
|
||||||
|
/// #![deny(missing_abi)]
|
||||||
|
///
|
||||||
|
/// extern fn foo() {}
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// Historically, Rust implicitly selected C as the ABI for extern
|
||||||
|
/// declarations. We expect to add new ABIs, like `C-unwind`, in the future,
|
||||||
|
/// though this has not yet happened, and especially with their addition
|
||||||
|
/// seeing the ABI easily will make code review easier.
|
||||||
|
pub MISSING_ABI,
|
||||||
|
Allow,
|
||||||
|
"No declared ABI for extern declaration"
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ use rustc_ast::node_id::{NodeId, NodeMap};
|
|||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
|
use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
|
||||||
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
pub mod builtin;
|
pub mod builtin;
|
||||||
|
|
||||||
@ -252,6 +253,7 @@ pub enum BuiltinLintDiagnostics {
|
|||||||
UnusedImports(String, Vec<(Span, String)>),
|
UnusedImports(String, Vec<(Span, String)>),
|
||||||
RedundantImport(Vec<(Span, bool)>, Ident),
|
RedundantImport(Vec<(Span, bool)>, Ident),
|
||||||
DeprecatedMacro(Option<Symbol>, Span),
|
DeprecatedMacro(Option<Symbol>, Span),
|
||||||
|
MissingAbi(Span, Abi),
|
||||||
UnusedDocComment(Span),
|
UnusedDocComment(Span),
|
||||||
PatternsInFnsWithoutBody(Span, Ident),
|
PatternsInFnsWithoutBody(Span, Ident),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user