Skip to content

Commit cbae5b2

Browse files
compiler: limit in-HIR ABI support checks to stable ABIs
We already gated unstable, unsupported ABIs during AST lowering. If we check all ABIs for target support during HIR lowering, then we risk duplicate errors in code that uses unstable extern "{abi}"s. Limiting the ABI support checks to stable ABIs reduces this, and remains correct because of gating all unstable ABIs already. This code complication can be reduced when we switch the FCW to error.
1 parent 4f84ea0 commit cbae5b2

File tree

7 files changed

+37
-26
lines changed

7 files changed

+37
-26
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3815,6 +3815,7 @@ dependencies = [
38153815
"rustc_abi",
38163816
"rustc_arena",
38173817
"rustc_ast",
3818+
"rustc_ast_lowering",
38183819
"rustc_attr_data_structures",
38193820
"rustc_data_structures",
38203821
"rustc_errors",

compiler/rustc_ast_lowering/src/stability.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ pub(crate) fn extern_abi_enabled(
2020
features: &rustc_feature::Features,
2121
span: Span,
2222
abi: ExternAbi,
23-
) -> Result<(), UnstableAbi> {
23+
) -> Result<ExternAbi, UnstableAbi> {
2424
extern_abi_stability(abi).or_else(|unstable @ UnstableAbi { feature, .. }| {
2525
if features.enabled(feature) || span.allows_unstable(feature) {
26-
Ok(())
26+
Ok(abi)
2727
} else {
2828
Err(unstable)
2929
}
@@ -81,7 +81,7 @@ impl fmt::Display for UnstableAbi {
8181
}
8282
}
8383

84-
pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> {
84+
pub fn extern_abi_stability(abi: ExternAbi) -> Result<ExternAbi, UnstableAbi> {
8585
match abi {
8686
// stable ABIs
8787
ExternAbi::Rust
@@ -94,7 +94,7 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> {
9494
| ExternAbi::Win64 { .. }
9595
| ExternAbi::SysV64 { .. }
9696
| ExternAbi::System { .. }
97-
| ExternAbi::EfiApi => Ok(()),
97+
| ExternAbi::EfiApi => Ok(abi),
9898
ExternAbi::Unadjusted => {
9999
Err(UnstableAbi { abi, feature: sym::abi_unadjusted, explain: GateReason::ImplDetail })
100100
}

compiler/rustc_hir_analysis/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ itertools = "0.12"
1313
rustc_abi = { path = "../rustc_abi" }
1414
rustc_arena = { path = "../rustc_arena" }
1515
rustc_ast = { path = "../rustc_ast" }
16+
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
1617
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
1718
rustc_data_structures = { path = "../rustc_data_structures" }
1819
rustc_errors = { path = "../rustc_errors" }

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::cell::LazyCell;
22
use std::ops::ControlFlow;
33

44
use rustc_abi::FieldIdx;
5+
use rustc_ast_lowering::stability::extern_abi_stability;
56
use rustc_attr_data_structures::ReprAttr::ReprPacked;
67
use rustc_data_structures::unord::{UnordMap, UnordSet};
78
use rustc_errors::MultiSpan;
@@ -35,25 +36,33 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir};
3536
use super::compare_impl_item::check_type_bounds;
3637
use super::*;
3738

38-
pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) {
39-
if !tcx.sess.target.is_abi_supported(abi) {
40-
struct_span_code_err!(
41-
tcx.dcx(),
42-
span,
43-
E0570,
44-
"`{abi}` is not a supported ABI for the current target",
45-
)
46-
.emit();
39+
/// check if a stable ABI passes e.g. target support
40+
///
41+
/// we are gating unstable target-unsupported ABIs in rustc_ast_lowering which is more foolproof.
42+
/// but until we finish the FCW associated with check_abi_fn_ptr we can't simply consolidate them.
43+
pub fn gate_stable_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) {
44+
if let Ok(abi) = extern_abi_stability(abi) {
45+
if !tcx.sess.target.is_abi_supported(abi) {
46+
struct_span_code_err!(
47+
tcx.dcx(),
48+
span,
49+
E0570,
50+
"`{abi}` is not a supported ABI for the current target",
51+
)
52+
.emit();
53+
}
4754
}
4855
}
4956

50-
pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) {
51-
if !tcx.sess.target.is_abi_supported(abi) {
52-
tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
53-
lint.primary_message(format!(
54-
"the calling convention {abi} is not supported on this target"
55-
));
56-
});
57+
pub fn gate_stable_fn_ptr_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) {
58+
if let Ok(abi) = extern_abi_stability(abi) {
59+
if !tcx.sess.target.is_abi_supported(abi) {
60+
tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
61+
lint.primary_message(format!(
62+
"the calling convention {abi} is not supported on this target"
63+
));
64+
});
65+
}
5766
}
5867
}
5968

@@ -779,7 +788,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
779788
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
780789
return;
781790
};
782-
check_abi(tcx, it.span, abi);
791+
gate_stable_abi(tcx, it.span, abi);
783792

784793
for item in items {
785794
let def_id = item.id.owner_id.def_id;

compiler/rustc_hir_analysis/src/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub mod wfcheck;
7272

7373
use std::num::NonZero;
7474

75-
pub use check::{check_abi, check_abi_fn_ptr};
75+
pub use check::{gate_stable_abi, gate_stable_fn_ptr_abi};
7676
use rustc_abi::{ExternAbi, VariantIdx};
7777
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
7878
use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err};

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds;
5050
use rustc_trait_selection::traits::{self, ObligationCtxt};
5151
use tracing::{debug, instrument};
5252

53-
use crate::check::check_abi_fn_ptr;
53+
use crate::check::gate_stable_fn_ptr_abi;
5454
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation};
5555
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
5656
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
@@ -2739,7 +2739,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
27392739
if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(bare_fn_ty), span, .. }) =
27402740
tcx.hir_node(hir_id)
27412741
{
2742-
check_abi_fn_ptr(tcx, hir_id, *span, bare_fn_ty.abi);
2742+
gate_stable_fn_ptr_abi(tcx, hir_id, *span, bare_fn_ty.abi);
27432743
}
27442744

27452745
// reject function types that violate cmse ABI requirements

compiler/rustc_hir_typeck/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_e
4848
use rustc_hir as hir;
4949
use rustc_hir::def::{DefKind, Res};
5050
use rustc_hir::{HirId, HirIdMap, Node};
51-
use rustc_hir_analysis::check::check_abi;
51+
use rustc_hir_analysis::check::gate_stable_abi;
5252
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
5353
use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc};
5454
use rustc_middle::query::Providers;
@@ -149,7 +149,7 @@ fn typeck_with_inspect<'tcx>(
149149
tcx.fn_sig(def_id).instantiate_identity()
150150
};
151151

152-
check_abi(tcx, span, fn_sig.abi());
152+
gate_stable_abi(tcx, span, fn_sig.abi());
153153

154154
// Compute the function signature from point of view of inside the fn.
155155
let mut fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);

0 commit comments

Comments
 (0)