Auto merge of #151065 - nagisa:add-preserve-none-abi, r=petrochenkov
abi: add a rust-preserve-none calling convention
This is the conceptual opposite of the rust-cold calling convention and is particularly useful in combination with the new `explicit_tail_calls` feature.
For relatively tight loops implemented with tail calling (`become`) each of the function with the regular calling convention is still responsible for restoring the initial value of the preserved registers. So it is not unusual to end up with a situation where each step in the tail call loop is spilling and reloading registers, along the lines of:
foo:
push r12
; do things
pop r12
jmp next_step
This adds up quickly, especially when most of the clobberable registers are already used to pass arguments or other uses.
I was thinking of making the name of this ABI a little less LLVM-derived and more like a conceptual inverse of `rust-cold`, but could not come with a great name (`rust-cold` is itself not a great name: cold in what context? from which perspective? is it supposed to mean that the function is rarely called?)
This commit is contained in:
commit
75963ce795
26 changed files with 241 additions and 5 deletions
|
|
@ -27,6 +27,7 @@ pub enum CanonAbi {
|
|||
C,
|
||||
Rust,
|
||||
RustCold,
|
||||
RustPreserveNone,
|
||||
|
||||
/// An ABI that rustc does not know how to call or define.
|
||||
Custom,
|
||||
|
|
@ -54,7 +55,7 @@ pub enum CanonAbi {
|
|||
impl CanonAbi {
|
||||
pub fn is_rustic_abi(self) -> bool {
|
||||
match self {
|
||||
CanonAbi::Rust | CanonAbi::RustCold => true,
|
||||
CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::RustPreserveNone => true,
|
||||
CanonAbi::C
|
||||
| CanonAbi::Custom
|
||||
| CanonAbi::Arm(_)
|
||||
|
|
@ -74,6 +75,7 @@ impl fmt::Display for CanonAbi {
|
|||
CanonAbi::C => ExternAbi::C { unwind: false },
|
||||
CanonAbi::Rust => ExternAbi::Rust,
|
||||
CanonAbi::RustCold => ExternAbi::RustCold,
|
||||
CanonAbi::RustPreserveNone => ExternAbi::RustPreserveNone,
|
||||
CanonAbi::Custom => ExternAbi::Custom,
|
||||
CanonAbi::Arm(arm_call) => match arm_call {
|
||||
ArmCall::Aapcs => ExternAbi::Aapcs { unwind: false },
|
||||
|
|
|
|||
|
|
@ -42,6 +42,13 @@ pub enum ExternAbi {
|
|||
/// in a platform-agnostic way.
|
||||
RustInvalid,
|
||||
|
||||
/// Preserves no registers.
|
||||
///
|
||||
/// Note, that this ABI is not stable in the registers it uses, is intended as an optimization
|
||||
/// and may fall-back to a more conservative calling convention if the backend does not support
|
||||
/// forcing callers to save all registers.
|
||||
RustPreserveNone,
|
||||
|
||||
/// Unstable impl detail that directly uses Rust types to describe the ABI to LLVM.
|
||||
/// Even normally-compatible Rust types can become ABI-incompatible with this ABI!
|
||||
Unadjusted,
|
||||
|
|
@ -163,6 +170,7 @@ abi_impls! {
|
|||
RustCall =><= "rust-call",
|
||||
RustCold =><= "rust-cold",
|
||||
RustInvalid =><= "rust-invalid",
|
||||
RustPreserveNone =><= "rust-preserve-none",
|
||||
Stdcall { unwind: false } =><= "stdcall",
|
||||
Stdcall { unwind: true } =><= "stdcall-unwind",
|
||||
System { unwind: false } =><= "system",
|
||||
|
|
@ -243,7 +251,7 @@ impl ExternAbi {
|
|||
/// - are subject to change between compiler versions
|
||||
pub fn is_rustic_abi(self) -> bool {
|
||||
use ExternAbi::*;
|
||||
matches!(self, Rust | RustCall | RustCold)
|
||||
matches!(self, Rust | RustCall | RustCold | RustPreserveNone)
|
||||
}
|
||||
|
||||
/// Returns whether the ABI supports C variadics. This only controls whether we allow *imports*
|
||||
|
|
@ -315,7 +323,8 @@ impl ExternAbi {
|
|||
| Self::Thiscall { .. }
|
||||
| Self::Vectorcall { .. }
|
||||
| Self::SysV64 { .. }
|
||||
| Self::Win64 { .. } => true,
|
||||
| Self::Win64 { .. }
|
||||
| Self::RustPreserveNone => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,11 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> {
|
|||
ExternAbi::RustCold => {
|
||||
Err(UnstableAbi { abi, feature: sym::rust_cold_cc, explain: GateReason::Experimental })
|
||||
}
|
||||
ExternAbi::RustPreserveNone => Err(UnstableAbi {
|
||||
abi,
|
||||
feature: sym::rust_preserve_none_cc,
|
||||
explain: GateReason::Experimental,
|
||||
}),
|
||||
ExternAbi::RustInvalid => {
|
||||
Err(UnstableAbi { abi, feature: sym::rustc_attrs, explain: GateReason::ImplDetail })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -400,6 +400,7 @@ impl<'a> AstValidator<'a> {
|
|||
CanonAbi::C
|
||||
| CanonAbi::Rust
|
||||
| CanonAbi::RustCold
|
||||
| CanonAbi::RustPreserveNone
|
||||
| CanonAbi::Arm(_)
|
||||
| CanonAbi::X86(_) => { /* nothing to check */ }
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ pub(crate) fn conv_to_call_conv(
|
|||
CanonAbi::Rust | CanonAbi::C => default_call_conv,
|
||||
CanonAbi::RustCold => CallConv::Cold,
|
||||
|
||||
// Cranelift doesn't currently have anything for this.
|
||||
CanonAbi::RustPreserveNone => default_call_conv,
|
||||
|
||||
// Functions with this calling convention can only be called from assembly, but it is
|
||||
// possible to declare an `extern "custom"` block, so the backend still needs a calling
|
||||
// convention for declaring foreign functions.
|
||||
|
|
|
|||
|
|
@ -243,6 +243,8 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||
pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option<FnAttribute<'gcc>> {
|
||||
let attribute = match conv {
|
||||
CanonAbi::C | CanonAbi::Rust => return None,
|
||||
// gcc/gccjit does not have anything for this.
|
||||
CanonAbi::RustPreserveNone => return None,
|
||||
CanonAbi::RustCold => FnAttribute::Cold,
|
||||
// Functions with this calling convention can only be called from assembly, but it is
|
||||
// possible to declare an `extern "custom"` block, so the backend still needs a calling
|
||||
|
|
|
|||
|
|
@ -694,6 +694,10 @@ pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm:
|
|||
match abi {
|
||||
CanonAbi::C | CanonAbi::Rust => llvm::CCallConv,
|
||||
CanonAbi::RustCold => llvm::PreserveMost,
|
||||
CanonAbi::RustPreserveNone => match &sess.target.arch {
|
||||
Arch::X86_64 | Arch::AArch64 => llvm::PreserveNone,
|
||||
_ => llvm::CCallConv,
|
||||
},
|
||||
// Functions with this calling convention can only be called from assembly, but it is
|
||||
// possible to declare an `extern "custom"` block, so the backend still needs a calling
|
||||
// convention for declaring foreign functions.
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
|
|||
llvm::CreateAttrStringValue(llcx, "alloc-family", "__rust_alloc")
|
||||
}
|
||||
|
||||
/// Helper for `FnAbi::apply_attrs_llfn`:
|
||||
/// Helper for `FnAbiLlvmExt::apply_attrs_llfn`:
|
||||
/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
|
||||
/// attributes.
|
||||
pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ pub(crate) enum CallConv {
|
|||
PreserveMost = 14,
|
||||
PreserveAll = 15,
|
||||
Tail = 18,
|
||||
PreserveNone = 21,
|
||||
X86StdcallCallConv = 64,
|
||||
X86FastcallCallConv = 65,
|
||||
ArmAapcsCallConv = 67,
|
||||
|
|
|
|||
|
|
@ -634,6 +634,8 @@ declare_features! (
|
|||
(unstable, rtm_target_feature, "1.35.0", Some(150258)),
|
||||
/// Allows `extern "rust-cold"`.
|
||||
(unstable, rust_cold_cc, "1.63.0", Some(97544)),
|
||||
/// Allows `extern "rust-preserve-none"`.
|
||||
(unstable, rust_preserve_none_cc, "CURRENT_RUSTC_VERSION", Some(151401)),
|
||||
/// Target features on s390x.
|
||||
(unstable, s390x_target_feature, "1.82.0", Some(150259)),
|
||||
/// Allows the use of the `sanitize` attribute.
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
CanonAbi::C
|
||||
| CanonAbi::Rust
|
||||
| CanonAbi::RustCold
|
||||
| CanonAbi::RustPreserveNone
|
||||
| CanonAbi::Arm(_)
|
||||
| CanonAbi::X86(_) => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1288,7 +1288,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
|
|||
| RiscvInterruptS
|
||||
| RustInvalid
|
||||
| Unadjusted => false,
|
||||
Rust | RustCall | RustCold => tcx.sess.panic_strategy().unwinds(),
|
||||
Rust | RustCall | RustCold | RustPreserveNone => tcx.sess.panic_strategy().unwinds(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -432,6 +432,7 @@ pub enum CallConvention {
|
|||
Cold,
|
||||
PreserveMost,
|
||||
PreserveAll,
|
||||
PreserveNone,
|
||||
|
||||
Custom,
|
||||
|
||||
|
|
|
|||
|
|
@ -1139,6 +1139,7 @@ pub enum Abi {
|
|||
RustCold,
|
||||
RiscvInterruptM,
|
||||
RiscvInterruptS,
|
||||
RustPreserveNone,
|
||||
RustInvalid,
|
||||
Custom,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -615,6 +615,7 @@ impl RustcInternal for Abi {
|
|||
Abi::RustInvalid => rustc_abi::ExternAbi::RustInvalid,
|
||||
Abi::RiscvInterruptM => rustc_abi::ExternAbi::RiscvInterruptM,
|
||||
Abi::RiscvInterruptS => rustc_abi::ExternAbi::RiscvInterruptS,
|
||||
Abi::RustPreserveNone => rustc_abi::ExternAbi::RustPreserveNone,
|
||||
Abi::Custom => rustc_abi::ExternAbi::Custom,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ impl<'tcx> Stable<'tcx> for CanonAbi {
|
|||
CanonAbi::C => CallConvention::C,
|
||||
CanonAbi::Rust => CallConvention::Rust,
|
||||
CanonAbi::RustCold => CallConvention::Cold,
|
||||
CanonAbi::RustPreserveNone => CallConvention::PreserveNone,
|
||||
CanonAbi::Custom => CallConvention::Custom,
|
||||
CanonAbi::Arm(arm_call) => match arm_call {
|
||||
ArmCall::Aapcs => CallConvention::ArmAapcs,
|
||||
|
|
|
|||
|
|
@ -1020,6 +1020,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi {
|
|||
ExternAbi::RustCall => Abi::RustCall,
|
||||
ExternAbi::Unadjusted => Abi::Unadjusted,
|
||||
ExternAbi::RustCold => Abi::RustCold,
|
||||
ExternAbi::RustPreserveNone => Abi::RustPreserveNone,
|
||||
ExternAbi::RustInvalid => Abi::RustInvalid,
|
||||
ExternAbi::RiscvInterruptM => Abi::RiscvInterruptM,
|
||||
ExternAbi::RiscvInterruptS => Abi::RiscvInterruptS,
|
||||
|
|
|
|||
|
|
@ -1918,6 +1918,7 @@ symbols! {
|
|||
rust_future,
|
||||
rust_logo,
|
||||
rust_out,
|
||||
rust_preserve_none_cc,
|
||||
rustc,
|
||||
rustc_abi,
|
||||
// FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ impl AbiMap {
|
|||
|
||||
(ExternAbi::RustCold, _) if self.os == OsKind::Windows => CanonAbi::Rust,
|
||||
(ExternAbi::RustCold, _) => CanonAbi::RustCold,
|
||||
(ExternAbi::RustPreserveNone, _) => CanonAbi::RustPreserveNone,
|
||||
|
||||
(ExternAbi::Custom, _) => CanonAbi::Custom,
|
||||
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ pub enum FnAbi {
|
|||
Win64,
|
||||
Win64Unwind,
|
||||
X86Interrupt,
|
||||
RustPreserveNone,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
|
|
@ -271,6 +272,7 @@ impl FnAbi {
|
|||
s if *s == sym::riscv_dash_interrupt_dash_s => FnAbi::RiscvInterruptS,
|
||||
s if *s == sym::rust_dash_call => FnAbi::RustCall,
|
||||
s if *s == sym::rust_dash_cold => FnAbi::RustCold,
|
||||
s if *s == sym::rust_dash_preserve_dash_none => FnAbi::RustPreserveNone,
|
||||
s if *s == sym::rust_dash_intrinsic => FnAbi::RustIntrinsic,
|
||||
s if *s == sym::Rust => FnAbi::Rust,
|
||||
s if *s == sym::stdcall_dash_unwind => FnAbi::StdcallUnwind,
|
||||
|
|
@ -314,6 +316,7 @@ impl FnAbi {
|
|||
FnAbi::Rust => "Rust",
|
||||
FnAbi::RustCall => "rust-call",
|
||||
FnAbi::RustCold => "rust-cold",
|
||||
FnAbi::RustPreserveNone => "rust-preserve-none",
|
||||
FnAbi::RustIntrinsic => "rust-intrinsic",
|
||||
FnAbi::Stdcall => "stdcall",
|
||||
FnAbi::StdcallUnwind => "stdcall-unwind",
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ define_symbols! {
|
|||
vectorcall_dash_unwind = "vectorcall-unwind",
|
||||
win64_dash_unwind = "win64-unwind",
|
||||
x86_dash_interrupt = "x86-interrupt",
|
||||
rust_dash_preserve_dash_none = "preserve-none",
|
||||
|
||||
@PLAIN:
|
||||
__ra_fixup,
|
||||
|
|
|
|||
33
tests/codegen-llvm/preserve-none.rs
Normal file
33
tests/codegen-llvm/preserve-none.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
//@ add-minicore
|
||||
//@ revisions: X86 AARCH64 UNSUPPORTED
|
||||
//@ [X86] compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu
|
||||
//@ [X86] needs-llvm-components: x86
|
||||
//@ [AARCH64] compile-flags: -C no-prepopulate-passes --target=aarch64-unknown-linux-gnu
|
||||
//@ [AARCH64] needs-llvm-components: aarch64
|
||||
//@ [UNSUPPORTED] compile-flags: -C no-prepopulate-passes --target=i686-unknown-linux-gnu
|
||||
//@ [UNSUPPORTED] needs-llvm-components: x86
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(rust_preserve_none_cc)]
|
||||
#![feature(no_core, lang_items)]
|
||||
#![no_core]
|
||||
|
||||
extern crate minicore;
|
||||
|
||||
// X86: define{{( dso_local)?}} preserve_nonecc void @peach(i16
|
||||
// AARCH64: define{{( dso_local)?}} preserve_nonecc void @peach(i16
|
||||
// UNSUPPORTED: define{{( dso_local)?}} void @peach(i16
|
||||
#[no_mangle]
|
||||
#[inline(never)]
|
||||
pub extern "rust-preserve-none" fn peach(x: u16) {
|
||||
loop {}
|
||||
}
|
||||
|
||||
// X86: call preserve_nonecc void @peach(i16
|
||||
// AARCH64: call preserve_nonecc void @peach(i16
|
||||
// UNSUPPORTED: call void @peach(i16
|
||||
pub fn quince(x: u16) {
|
||||
if let 12345u16 = x {
|
||||
peach(54321);
|
||||
}
|
||||
}
|
||||
67
tests/ui/abi/rust-preserve-none-cc.rs
Normal file
67
tests/ui/abi/rust-preserve-none-cc.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
//@ run-pass
|
||||
//@ needs-unwind
|
||||
|
||||
#![feature(rust_preserve_none_cc)]
|
||||
|
||||
struct CrateOf<'a> {
|
||||
mcintosh: f64,
|
||||
golden_delicious: u64,
|
||||
jonagold: Option<&'a u64>,
|
||||
rome: [u64; 12],
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
extern "rust-preserve-none" fn oven_explosion() {
|
||||
panic!("bad time");
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn bite_into(yummy: u64) -> u64 {
|
||||
let did_it_actually = std::panic::catch_unwind(move || {
|
||||
oven_explosion()
|
||||
});
|
||||
assert!(did_it_actually.is_err());
|
||||
yummy - 25
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
extern "rust-preserve-none" fn lotsa_apples(
|
||||
honeycrisp: u64,
|
||||
gala: u32,
|
||||
fuji: f64,
|
||||
granny_smith: &[u64],
|
||||
pink_lady: (),
|
||||
and_a: CrateOf<'static>,
|
||||
cosmic_crisp: u64,
|
||||
ambrosia: f64,
|
||||
winesap: &[u64],
|
||||
) -> (u64, f64, u64, u64) {
|
||||
assert_eq!(honeycrisp, 220);
|
||||
assert_eq!(gala, 140);
|
||||
assert_eq!(fuji, 210.54201234);
|
||||
assert_eq!(granny_smith, &[180, 210]);
|
||||
assert_eq!(pink_lady, ());
|
||||
assert_eq!(and_a.mcintosh, 150.0);
|
||||
assert_eq!(and_a.golden_delicious, 185);
|
||||
assert_eq!(and_a.jonagold, None); // my scales can't weight these gargantuans.
|
||||
assert_eq!(and_a.rome, [180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202]);
|
||||
assert_eq!(cosmic_crisp, 270);
|
||||
assert_eq!(ambrosia, 193.1);
|
||||
assert_eq!(winesap, &[]);
|
||||
(
|
||||
and_a.rome.iter().sum(),
|
||||
fuji + ambrosia,
|
||||
cosmic_crisp - honeycrisp,
|
||||
bite_into(and_a.golden_delicious)
|
||||
)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let pie = lotsa_apples(220, 140, 210.54201234, &[180, 210], (), CrateOf {
|
||||
mcintosh: 150.0,
|
||||
golden_delicious: 185,
|
||||
jonagold: None,
|
||||
rome: [180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202]
|
||||
}, 270, 193.1, &[]);
|
||||
assert_eq!(pie, (2292, 403.64201234, 50, 160));
|
||||
}
|
||||
21
tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.rs
Normal file
21
tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
extern "rust-preserve-none" fn apple() {} //~ ERROR "rust-preserve-none" ABI is experimental
|
||||
|
||||
trait T {
|
||||
extern "rust-preserve-none" fn banana(); //~ ERROR "rust-preserve-none" ABI is experimental
|
||||
extern "rust-preserve-none" fn citrus() {} //~ ERROR "rust-preserve-none" ABI is experimental
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl T for S {
|
||||
extern "rust-preserve-none" fn banana() {} //~ ERROR "rust-preserve-none" ABI is experimental
|
||||
}
|
||||
|
||||
impl S {
|
||||
extern "rust-preserve-none" fn durian() {} //~ ERROR "rust-preserve-none" ABI is experimental
|
||||
}
|
||||
|
||||
type Fig = extern "rust-preserve-none" fn(); //~ ERROR "rust-preserve-none" ABI is experimental
|
||||
|
||||
extern "rust-preserve-none" {} //~ ERROR "rust-preserve-none" ABI is experimental
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-rust-preserve-none-cc.rs:3:8
|
||||
|
|
||||
LL | extern "rust-preserve-none" fn apple() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #151401 <https://github.com/rust-lang/rust/issues/151401> for more information
|
||||
= help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-rust-preserve-none-cc.rs:6:12
|
||||
|
|
||||
LL | extern "rust-preserve-none" fn banana();
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #151401 <https://github.com/rust-lang/rust/issues/151401> for more information
|
||||
= help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-rust-preserve-none-cc.rs:7:12
|
||||
|
|
||||
LL | extern "rust-preserve-none" fn citrus() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #151401 <https://github.com/rust-lang/rust/issues/151401> for more information
|
||||
= help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-rust-preserve-none-cc.rs:12:12
|
||||
|
|
||||
LL | extern "rust-preserve-none" fn banana() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #151401 <https://github.com/rust-lang/rust/issues/151401> for more information
|
||||
= help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-rust-preserve-none-cc.rs:16:12
|
||||
|
|
||||
LL | extern "rust-preserve-none" fn durian() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #151401 <https://github.com/rust-lang/rust/issues/151401> for more information
|
||||
= help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-rust-preserve-none-cc.rs:19:19
|
||||
|
|
||||
LL | type Fig = extern "rust-preserve-none" fn();
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #151401 <https://github.com/rust-lang/rust/issues/151401> for more information
|
||||
= help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-rust-preserve-none-cc.rs:21:8
|
||||
|
|
||||
LL | extern "rust-preserve-none" {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #151401 <https://github.com/rust-lang/rust/issues/151401> for more information
|
||||
= help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
@ -21,6 +21,7 @@ riscv-interrupt-s
|
|||
rust-call
|
||||
rust-cold
|
||||
rust-invalid
|
||||
rust-preserve-none
|
||||
stdcall
|
||||
stdcall-unwind
|
||||
system
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue