Skip to content

Commit

Permalink
Rollup merge of #132357 - m-ou-se:explicit-abi, r=compiler-errors
Browse files Browse the repository at this point in the history
Improve missing_abi lint

This is for the migration lint for rust-lang/rfcs#3722

It is not yet marked as an edition migration lint, because `Edition2027` doesn't exist yet.

The lint now includes a machine applicable suggestion:

```
warning: extern declarations without an explicit ABI are deprecated
 --> src/main.rs:3:1
  |
3 | extern fn a() {}
  | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
  |
```
  • Loading branch information
workingjubilee authored Nov 1, 2024
2 parents 1219169 + a433ea2 commit 6b0c8cf
Show file tree
Hide file tree
Showing 10 changed files with 17 additions and 19 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ impl WalkItemKind for ItemKind {
}
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)),
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,9 +677,8 @@ impl<'a> AstValidator<'a> {
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, ..) => {
Expand Down Expand Up @@ -953,7 +952,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
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(
Expand All @@ -977,7 +976,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}

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;
Expand Down Expand Up @@ -1350,13 +1349,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,7 @@ impl<'a> Parser<'a> {
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
Expand All @@ -1205,6 +1206,7 @@ impl<'a> Parser<'a> {
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))?,
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/lint/cli-lint-override.forbid_warn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated
--> $DIR/cli-lint-override.rs:12:1
|
LL | extern fn foo() {}
| ^^^^^^^^^^^^^^^ ABI should be specified here
| ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
|
= help: the default ABI is C
= note: requested on the command line with `-F missing-abi`

error: aborting due to 1 previous error
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/lint/cli-lint-override.force_warn_deny.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ warning: extern declarations without an explicit ABI are deprecated
--> $DIR/cli-lint-override.rs:12:1
|
LL | extern fn foo() {}
| ^^^^^^^^^^^^^^^ ABI should be specified here
| ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
|
= help: the default ABI is C
= note: requested on the command line with `--force-warn missing-abi`

warning: 1 warning emitted
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/lint/cli-lint-override.warn_deny.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated
--> $DIR/cli-lint-override.rs:12:1
|
LL | extern fn foo() {}
| ^^^^^^^^^^^^^^^ ABI should be specified here
| ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
|
= help: the default ABI is C
= note: requested on the command line with `-D missing-abi`

error: aborting due to 1 previous error
Expand Down

0 comments on commit 6b0c8cf

Please sign in to comment.