Improve the missing_abi lint.

This commit is contained in:
Mara Bos 2024-10-30 13:12:08 +01:00
parent 8b9f0f9c1c
commit cb26fa07bb
7 changed files with 14 additions and 13 deletions

View File

@ -2810,6 +2810,8 @@ pub struct ModSpans {
/// E.g., `extern { .. }` or `extern "C" { .. }`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct ForeignMod {
/// Span of the `extern` keyword.
pub extern_span: Span,
/// `unsafe` keyword accepted syntactically for macro DSLs, but not
/// semantically by Rust.
pub safety: Safety,

View File

@ -525,7 +525,7 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
}
fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
let ForeignMod { safety, abi: _, items } = foreign_mod;
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
visit_safety(vis, safety);
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
}

View File

@ -366,7 +366,7 @@ fn walk<'a, V: Visitor<'a>>(
}
ModKind::Unloaded => {}
},
ItemKind::ForeignMod(ForeignMod { safety: _, abi: _, items }) => {
ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => {
walk_list!(visitor, visit_foreign_item, items);
}
ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),

View File

@ -677,9 +677,8 @@ fn visit_ty_common(&mut self, ty: &'a Ty) {
Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
self.dcx().emit_err(errors::PatternFnPointer { span });
});
if let Extern::Implicit(_) = bfty.ext {
let sig_span = self.sess.source_map().next_point(ty.span.shrink_to_lo());
self.maybe_lint_missing_abi(sig_span, ty.id);
if let Extern::Implicit(extern_span) = bfty.ext {
self.maybe_lint_missing_abi(extern_span, ty.id);
}
}
TyKind::TraitObject(bounds, ..) => {
@ -953,7 +952,7 @@ fn visit_item(&mut self, item: &'a Item) {
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again.
}
ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => {
ItemKind::ForeignMod(ForeignMod { extern_span, abi, safety, .. }) => {
self.with_in_extern_mod(*safety, |this| {
let old_item = mem::replace(&mut this.extern_mod, Some(item.span));
this.visibility_not_permitted(
@ -977,7 +976,7 @@ fn visit_item(&mut self, item: &'a Item) {
}
if abi.is_none() {
this.maybe_lint_missing_abi(item.span, item.id);
this.maybe_lint_missing_abi(*extern_span, item.id);
}
visit::walk_item(this, item);
this.extern_mod = old_item;
@ -1350,13 +1349,13 @@ fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) {
if let FnKind::Fn(
_,
_,
FnSig { span: sig_span, header: FnHeader { ext: Extern::Implicit(_), .. }, .. },
FnSig { header: FnHeader { ext: Extern::Implicit(extern_span), .. }, .. },
_,
_,
_,
) = fk
{
self.maybe_lint_missing_abi(*sig_span, id);
self.maybe_lint_missing_abi(*extern_span, id);
}
// Functions without bodies cannot have patterns.

View File

@ -268,7 +268,7 @@ lint_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edi
lint_extern_without_abi = extern declarations without an explicit ABI are deprecated
.label = ABI should be specified here
.help = the default ABI is {$default_abi}
.suggestion = explicitly specify the {$default_abi} ABI
lint_for_loops_over_fallibles =
for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement

View File

@ -2738,11 +2738,9 @@ pub(crate) struct PatternsInFnsWithoutBodySub {
#[derive(LintDiagnostic)]
#[diag(lint_extern_without_abi)]
#[help]
pub(crate) struct MissingAbi {
#[label]
#[suggestion(code = "extern \"{default_abi}\"", applicability = "machine-applicable")]
pub span: Span,
pub default_abi: &'static str,
}

View File

@ -1194,6 +1194,7 @@ fn parse_item_foreign_mod(
attrs: &mut AttrVec,
mut safety: Safety,
) -> PResult<'a, ItemInfo> {
let extern_span = self.prev_token.uninterpolated_span();
let abi = self.parse_abi(); // ABI?
// FIXME: This recovery should be tested better.
if safety == Safety::Default
@ -1205,6 +1206,7 @@ fn parse_item_foreign_mod(
let _ = self.eat_keyword(kw::Unsafe);
}
let module = ast::ForeignMod {
extern_span,
safety,
abi,
items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,