Skip to content

Commit 7fbfadb

Browse files
authored
Unrolled build for rust-lang#138028
Rollup merge of rust-lang#138028 - workingjubilee:is-rustic-abi, r=compiler-errors compiler: add `ExternAbi::is_rustic_abi` Various parts of the compiler were hand-rolling this extremely simple check that is nonetheless easy to get wrong as the compiler evolves over time. Discourage them from being so "original" again by replacing it with a single implementation on the type that represents these ABIs. This simplifies a surprising amount of code as a result. Also fixes rust-lang#132981, an ICE that emerged due to other checks being made stricter.
2 parents 4559163 + 8a68987 commit 7fbfadb

File tree

7 files changed

+34
-43
lines changed

7 files changed

+34
-43
lines changed

compiler/rustc_abi/src/extern_abi.rs

+11
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,17 @@ impl StableOrd for ExternAbi {
191191
}
192192

193193
impl ExternAbi {
194+
/// An ABI "like Rust"
195+
///
196+
/// These ABIs are fully controlled by the Rust compiler, which means they
197+
/// - support unwinding with `-Cpanic=unwind`, unlike `extern "C"`
198+
/// - often diverge from the C ABI
199+
/// - are subject to change between compiler versions
200+
pub fn is_rustic_abi(self) -> bool {
201+
use ExternAbi::*;
202+
matches!(self, Rust | RustCall | RustIntrinsic | RustCold)
203+
}
204+
194205
pub fn supports_varargs(self) -> bool {
195206
// * C and Cdecl obviously support varargs.
196207
// * C can be based on Aapcs, SysV64 or Win64, so they must support varargs.

compiler/rustc_lint/src/types.rs

+11-19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::iter;
22
use std::ops::ControlFlow;
33

4-
use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, VariantIdx, Variants, WrappingRange};
4+
use rustc_abi::{BackendRepr, TagEncoding, VariantIdx, Variants, WrappingRange};
55
use rustc_data_structures::fx::FxHashSet;
66
use rustc_errors::DiagMessage;
77
use rustc_hir::intravisit::VisitorExt;
@@ -1349,7 +1349,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
13491349

13501350
ty::FnPtr(sig_tys, hdr) => {
13511351
let sig = sig_tys.with(hdr);
1352-
if self.is_internal_abi(sig.abi()) {
1352+
if sig.abi().is_rustic_abi() {
13531353
return FfiUnsafe {
13541354
ty,
13551355
reason: fluent::lint_improper_ctypes_fnptr_reason,
@@ -1552,13 +1552,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
15521552
self.check_type_for_ffi_and_report_errors(span, ty, true, false);
15531553
}
15541554

1555-
fn is_internal_abi(&self, abi: ExternAbi) -> bool {
1556-
matches!(
1557-
abi,
1558-
ExternAbi::Rust | ExternAbi::RustCall | ExternAbi::RustCold | ExternAbi::RustIntrinsic
1559-
)
1560-
}
1561-
15621555
/// Find any fn-ptr types with external ABIs in `ty`.
15631556
///
15641557
/// For example, `Option<extern "C" fn()>` returns `extern "C" fn()`
@@ -1567,17 +1560,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
15671560
hir_ty: &hir::Ty<'tcx>,
15681561
ty: Ty<'tcx>,
15691562
) -> Vec<(Ty<'tcx>, Span)> {
1570-
struct FnPtrFinder<'a, 'b, 'tcx> {
1571-
visitor: &'a ImproperCTypesVisitor<'b, 'tcx>,
1563+
struct FnPtrFinder<'tcx> {
15721564
spans: Vec<Span>,
15731565
tys: Vec<Ty<'tcx>>,
15741566
}
15751567

1576-
impl<'a, 'b, 'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'a, 'b, 'tcx> {
1568+
impl<'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'tcx> {
15771569
fn visit_ty(&mut self, ty: &'_ hir::Ty<'_, AmbigArg>) {
15781570
debug!(?ty);
15791571
if let hir::TyKind::BareFn(hir::BareFnTy { abi, .. }) = ty.kind
1580-
&& !self.visitor.is_internal_abi(*abi)
1572+
&& !abi.is_rustic_abi()
15811573
{
15821574
self.spans.push(ty.span);
15831575
}
@@ -1586,12 +1578,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
15861578
}
15871579
}
15881580

1589-
impl<'a, 'b, 'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for FnPtrFinder<'a, 'b, 'tcx> {
1581+
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for FnPtrFinder<'tcx> {
15901582
type Result = ();
15911583

15921584
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
15931585
if let ty::FnPtr(_, hdr) = ty.kind()
1594-
&& !self.visitor.is_internal_abi(hdr.abi)
1586+
&& !hdr.abi.is_rustic_abi()
15951587
{
15961588
self.tys.push(ty);
15971589
}
@@ -1600,7 +1592,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
16001592
}
16011593
}
16021594

1603-
let mut visitor = FnPtrFinder { visitor: self, spans: Vec::new(), tys: Vec::new() };
1595+
let mut visitor = FnPtrFinder { spans: Vec::new(), tys: Vec::new() };
16041596
ty.visit_with(&mut visitor);
16051597
visitor.visit_ty_unambig(hir_ty);
16061598

@@ -1615,13 +1607,13 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations {
16151607

16161608
match it.kind {
16171609
hir::ForeignItemKind::Fn(sig, _, _) => {
1618-
if vis.is_internal_abi(abi) {
1610+
if abi.is_rustic_abi() {
16191611
vis.check_fn(it.owner_id.def_id, sig.decl)
16201612
} else {
16211613
vis.check_foreign_fn(it.owner_id.def_id, sig.decl);
16221614
}
16231615
}
1624-
hir::ForeignItemKind::Static(ty, _, _) if !vis.is_internal_abi(abi) => {
1616+
hir::ForeignItemKind::Static(ty, _, _) if !abi.is_rustic_abi() => {
16251617
vis.check_foreign_static(it.owner_id, ty.span);
16261618
}
16271619
hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (),
@@ -1775,7 +1767,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
17751767
};
17761768

17771769
let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition };
1778-
if vis.is_internal_abi(abi) {
1770+
if abi.is_rustic_abi() {
17791771
vis.check_fn(id, decl);
17801772
} else {
17811773
vis.check_foreign_fn(id, decl);

compiler/rustc_mir_transform/src/ffi_unwind_calls.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
5353

5454
// Rust calls cannot themselves create foreign unwinds.
5555
// We assume this is true for intrinsics as well.
56-
if let ExternAbi::RustIntrinsic
57-
| ExternAbi::Rust
58-
| ExternAbi::RustCall
59-
| ExternAbi::RustCold = sig.abi()
60-
{
56+
if sig.abi().is_rustic_abi() {
6157
continue;
6258
};
6359

compiler/rustc_monomorphize/src/mono_checks/abi_check.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! This module ensures that if a function's ABI requires a particular target feature,
22
//! that target feature is enabled both on the callee and all callers.
3-
use rustc_abi::{BackendRepr, ExternAbi, RegKind};
3+
use rustc_abi::{BackendRepr, RegKind};
44
use rustc_hir::CRATE_HIR_ID;
55
use rustc_middle::mir::{self, traversal};
66
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt};
@@ -115,8 +115,8 @@ fn check_call_site_abi<'tcx>(
115115
span: Span,
116116
caller: InstanceKind<'tcx>,
117117
) {
118-
if callee.fn_sig(tcx).abi() == ExternAbi::Rust {
119-
// "Rust" ABI never passes arguments in vector registers.
118+
if callee.fn_sig(tcx).abi().is_rustic_abi() {
119+
// we directly handle the soundness of Rust ABIs
120120
return;
121121
}
122122
let typing_env = ty::TypingEnv::fully_monomorphized();

compiler/rustc_ty_utils/src/abi.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,7 @@ fn fn_abi_sanity_check<'tcx>(
436436
) {
437437
let tcx = cx.tcx();
438438

439-
if spec_abi == ExternAbi::Rust
440-
|| spec_abi == ExternAbi::RustCall
441-
|| spec_abi == ExternAbi::RustCold
442-
{
439+
if spec_abi.is_rustic_abi() {
443440
if arg.layout.is_zst() {
444441
// Casting closures to function pointers depends on ZST closure types being
445442
// omitted entirely in the calling convention.
@@ -687,7 +684,7 @@ fn fn_abi_adjust_for_abi<'tcx>(
687684

688685
let tcx = cx.tcx();
689686

690-
if abi == ExternAbi::Rust || abi == ExternAbi::RustCall || abi == ExternAbi::RustIntrinsic {
687+
if abi.is_rustic_abi() {
691688
fn_abi.adjust_for_rust_abi(cx, abi);
692689

693690
// Look up the deduced parameter attributes for this function, if we have its def ID and

tests/crashes/132981.rs

-11
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//@build-pass
2+
//@compile-flags: -Clink-dead-code=true --crate-type lib
3+
// We used to not handle all "rustic" ABIs in a (relatively) uniform way,
4+
// so we failed to fix up arguments for actually passing through the ABI...
5+
#![feature(rust_cold_cc)]
6+
pub extern "rust-cold" fn foo(_: [usize; 3]) {}

0 commit comments

Comments
 (0)