Skip to content

Commit 4f84ea0

Browse files
compiler: plug unsupported ABI leakage from the AST
We elaborate rustc_ast_lowering to prevent unstable, unsupported ABIs from leaking through the HIR without being checked for target support. Previously ad-hoc checking on various HIR items required making sure we check every HIR item which could contain an extern "{abi}" string. This is a losing proposition compared to gating the lowering itself. As a consequence, unstable ABI strings will now hard-error instead of triggering the FCW `unsupported_fn_ptr_calling_conventions`. This FCW was upgraded to warn in dependencies in Rust 1.87 so it has become active within a stable Rust version and it was within the compiler's nightly-feature contract to break this code without warning, so this breakage has likely had a reasonable amount of foreshadowing.
1 parent 852f15c commit 4f84ea0

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

compiler/rustc_ast_lowering/src/stability.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::fmt;
22

33
use rustc_abi::ExternAbi;
4+
use rustc_errors::{E0570, struct_span_code_err};
45
use rustc_feature::Features;
56
use rustc_session::Session;
67
use rustc_session::parse::feature_err;
@@ -31,13 +32,28 @@ pub(crate) fn extern_abi_enabled(
3132

3233
#[allow(rustc::untranslatable_diagnostic)]
3334
pub(crate) fn gate_unstable_abi(sess: &Session, features: &Features, span: Span, abi: ExternAbi) {
34-
match extern_abi_enabled(features, span, abi) {
35-
Ok(_) => (),
36-
Err(unstable_abi) => {
37-
let explain = unstable_abi.to_string();
38-
feature_err(sess, unstable_abi.feature, span, explain).emit();
39-
}
35+
let Err(unstable) = extern_abi_stability(abi) else { return };
36+
// what are we doing here? this is mixing target support with stability?
37+
// well, unfortunately we allowed some ABIs to be used via fn pointers and such on stable,
38+
// so we can't simply error any time someone uses certain ABIs as we want to let the FCW ride.
39+
// however, for a number of *unstable* ABIs, we can simply fix them because they're unstable!
40+
// otherwise it's the same idea as checking during lowering at all: because `extern "ABI"` has to
41+
// be visible during lowering of some crate, we can easily nail use of certain ABIs before we
42+
// get to e.g. attempting to do invalid codegen for the target.
43+
if !sess.target.is_abi_supported(unstable.abi) {
44+
struct_span_code_err!(
45+
sess.dcx(),
46+
span,
47+
E0570,
48+
"`{abi}` is not a supported ABI for the current target",
49+
)
50+
.emit();
51+
}
52+
if features.enabled(unstable.feature) || span.allows_unstable(unstable.feature) {
53+
return;
4054
}
55+
let explain = unstable.to_string();
56+
feature_err(sess, unstable.feature, span, explain).emit();
4157
}
4258

4359
pub struct UnstableAbi {

0 commit comments

Comments
 (0)