Skip to content

Commit 008c19c

Browse files
committed
Add hard error for extern without explicit ABIs
1 parent 8ed9b1b commit 008c19c

11 files changed

+165
-10
lines changed

Diff for: compiler/rustc_ast_passes/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$de
7979
.suggestion = remove the {$remove_descr}
8080
.label = `extern` block begins here
8181
82+
ast_passes_extern_without_abi = extern declarations without an explicit ABI are disallowed
83+
8284
ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel
8385
.suggestion = remove the attribute
8486
.stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable

Diff for: compiler/rustc_ast_passes/src/ast_validation.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ impl<'a> AstValidator<'a> {
677677
self.dcx().emit_err(errors::PatternFnPointer { span });
678678
});
679679
if let Extern::Implicit(extern_span) = bfty.ext {
680-
self.maybe_lint_missing_abi(extern_span, ty.id);
680+
self.handle_missing_abi(extern_span, ty.id);
681681
}
682682
}
683683
TyKind::TraitObject(bounds, ..) => {
@@ -710,10 +710,12 @@ impl<'a> AstValidator<'a> {
710710
}
711711
}
712712

713-
fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId) {
713+
fn handle_missing_abi(&mut self, span: Span, id: NodeId) {
714714
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
715715
// call site which do not have a macro backtrace. See #61963.
716-
if self
716+
if span.edition().at_least_edition_future() && self.features.explicit_extern_abis() {
717+
self.dcx().emit_err(errors::MissingAbi { span });
718+
} else if self
717719
.sess
718720
.source_map()
719721
.span_to_snippet(span)
@@ -976,7 +978,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
976978
}
977979

978980
if abi.is_none() {
979-
this.maybe_lint_missing_abi(*extern_span, item.id);
981+
this.handle_missing_abi(*extern_span, item.id);
980982
}
981983
visit::walk_item(this, item);
982984
this.extern_mod = old_item;
@@ -1357,7 +1359,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13571359
},
13581360
) = fk
13591361
{
1360-
self.maybe_lint_missing_abi(*extern_span, id);
1362+
self.handle_missing_abi(*extern_span, id);
13611363
}
13621364

13631365
// Functions without bodies cannot have patterns.

Diff for: compiler/rustc_ast_passes/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -823,3 +823,10 @@ pub(crate) struct DuplicatePreciseCapturing {
823823
#[label]
824824
pub bound2: Span,
825825
}
826+
827+
#[derive(Diagnostic)]
828+
#[diag(ast_passes_extern_without_abi)]
829+
pub(crate) struct MissingAbi {
830+
#[primary_span]
831+
pub span: Span,
832+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// This test differs from other feature gate tests.
2+
// Instead of verifying that an error occurs when the feature gate is missing,
3+
// it ensures that only a warning is emitted, not an error.
4+
5+
//@ revisions: current current_feature future future_feature
6+
7+
//@ [current] run-rustfix
8+
//@ [current] check-pass
9+
10+
//@ [current_feature] run-rustfix
11+
//@ [current_feature] check-pass
12+
13+
//@ [future] edition: future
14+
//@ [future] compile-flags: -Z unstable-options
15+
//@ [future] run-rustfix
16+
//@ [future] check-pass
17+
18+
//@ [future_feature] edition: future
19+
//@ [future_feature] compile-flags: -Z unstable-options
20+
21+
#![cfg_attr(future_feature, feature(explicit_extern_abis))]
22+
#![cfg_attr(current_feature, feature(explicit_extern_abis))]
23+
24+
extern "C" fn _foo() {}
25+
//[current]~^ WARN extern declarations without an explicit ABI are deprecated
26+
//[current_feature]~^^ WARN extern declarations without an explicit ABI are deprecated
27+
//[future]~^^^ WARN extern declarations without an explicit ABI are deprecated
28+
//[future_feature]~^^^^ ERROR extern declarations without an explicit ABI are disallowed
29+
30+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
warning: extern declarations without an explicit ABI are deprecated
2+
--> $DIR/feature-gate-explicit-extern-abis.rs:24:1
3+
|
4+
LL | extern fn _foo() {}
5+
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
6+
|
7+
= note: `#[warn(missing_abi)]` on by default
8+
9+
warning: 1 warning emitted
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// This test differs from other feature gate tests.
2+
// Instead of verifying that an error occurs when the feature gate is missing,
3+
// it ensures that only a warning is emitted, not an error.
4+
5+
//@ revisions: current current_feature future future_feature
6+
7+
//@ [current] run-rustfix
8+
//@ [current] check-pass
9+
10+
//@ [current_feature] run-rustfix
11+
//@ [current_feature] check-pass
12+
13+
//@ [future] edition: future
14+
//@ [future] compile-flags: -Z unstable-options
15+
//@ [future] run-rustfix
16+
//@ [future] check-pass
17+
18+
//@ [future_feature] edition: future
19+
//@ [future_feature] compile-flags: -Z unstable-options
20+
21+
#![cfg_attr(future_feature, feature(explicit_extern_abis))]
22+
#![cfg_attr(current_feature, feature(explicit_extern_abis))]
23+
24+
extern "C" fn _foo() {}
25+
//[current]~^ WARN extern declarations without an explicit ABI are deprecated
26+
//[current_feature]~^^ WARN extern declarations without an explicit ABI are deprecated
27+
//[future]~^^^ WARN extern declarations without an explicit ABI are deprecated
28+
//[future_feature]~^^^^ ERROR extern declarations without an explicit ABI are disallowed
29+
30+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
warning: extern declarations without an explicit ABI are deprecated
2+
--> $DIR/feature-gate-explicit-extern-abis.rs:24:1
3+
|
4+
LL | extern fn _foo() {}
5+
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
6+
|
7+
= note: `#[warn(missing_abi)]` on by default
8+
9+
warning: 1 warning emitted
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// This test differs from other feature gate tests.
2+
// Instead of verifying that an error occurs when the feature gate is missing,
3+
// it ensures that only a warning is emitted, not an error.
4+
5+
//@ revisions: current current_feature future future_feature
6+
7+
//@ [current] run-rustfix
8+
//@ [current] check-pass
9+
10+
//@ [current_feature] run-rustfix
11+
//@ [current_feature] check-pass
12+
13+
//@ [future] edition: future
14+
//@ [future] compile-flags: -Z unstable-options
15+
//@ [future] run-rustfix
16+
//@ [future] check-pass
17+
18+
//@ [future_feature] edition: future
19+
//@ [future_feature] compile-flags: -Z unstable-options
20+
21+
#![cfg_attr(future_feature, feature(explicit_extern_abis))]
22+
#![cfg_attr(current_feature, feature(explicit_extern_abis))]
23+
24+
extern "C" fn _foo() {}
25+
//[current]~^ WARN extern declarations without an explicit ABI are deprecated
26+
//[current_feature]~^^ WARN extern declarations without an explicit ABI are deprecated
27+
//[future]~^^^ WARN extern declarations without an explicit ABI are deprecated
28+
//[future_feature]~^^^^ ERROR extern declarations without an explicit ABI are disallowed
29+
30+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
warning: extern declarations without an explicit ABI are deprecated
2+
--> $DIR/feature-gate-explicit-extern-abis.rs:24:1
3+
|
4+
LL | extern fn _foo() {}
5+
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
6+
|
7+
= note: `#[warn(missing_abi)]` on by default
8+
9+
warning: 1 warning emitted
10+

Diff for: tests/ui/feature-gates/feature-gate-explicit-extern-abis.stderr renamed to tests/ui/feature-gates/feature-gate-explicit-extern-abis.future_feature.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
error: extern declarations without an explicit ABI are disallowed
2-
--> $DIR/feature-gate-explicit-extern-abis.rs:3:1
2+
--> $DIR/feature-gate-explicit-extern-abis.rs:24:1
33
|
4-
LL | extern fn foo() {}
4+
LL | extern fn _foo() {}
55
| ^^^^^^
66

77
error: aborting due to 1 previous error
+27-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
1-
#![feature(explicit_extern_abis)]
1+
// This test differs from other feature gate tests.
2+
// Instead of verifying that an error occurs when the feature gate is missing,
3+
// it ensures that only a warning is emitted, not an error.
24

3-
extern fn foo() {}
4-
//~^ ERROR extern declarations without an explicit ABI are disallowed
5+
//@ revisions: current current_feature future future_feature
6+
7+
//@ [current] run-rustfix
8+
//@ [current] check-pass
9+
10+
//@ [current_feature] run-rustfix
11+
//@ [current_feature] check-pass
12+
13+
//@ [future] edition: future
14+
//@ [future] compile-flags: -Z unstable-options
15+
//@ [future] run-rustfix
16+
//@ [future] check-pass
17+
18+
//@ [future_feature] edition: future
19+
//@ [future_feature] compile-flags: -Z unstable-options
20+
21+
#![cfg_attr(future_feature, feature(explicit_extern_abis))]
22+
#![cfg_attr(current_feature, feature(explicit_extern_abis))]
23+
24+
extern fn _foo() {}
25+
//[current]~^ WARN extern declarations without an explicit ABI are deprecated
26+
//[current_feature]~^^ WARN extern declarations without an explicit ABI are deprecated
27+
//[future]~^^^ WARN extern declarations without an explicit ABI are deprecated
28+
//[future_feature]~^^^^ ERROR extern declarations without an explicit ABI are disallowed
529

630
fn main() {}

0 commit comments

Comments
 (0)