diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 80754a8f65a69..d3636ef061e4a 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -24,8 +24,6 @@ ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetim .label = {ast_passes_auto_super_lifetime} .suggestion = remove the super traits or lifetime bounds -ast_passes_bad_c_variadic = only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg - ast_passes_bare_fn_invalid_safety = function pointers cannot be declared with `safe` safety qualifier .suggestion = remove safe from this item @@ -36,6 +34,13 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect +ast_passes_c_variadic_bad_calling_convention = + only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + +ast_passes_c_variadic_safe_foreign_function = + foreign functions with a C-variadic argument cannot be safe + .suggestion = remove the `safe` keyword from this definition + ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic .const = `const` because of this .variadic = C-variadic because of this diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index d6fe04d2994b5..c4d8e9d954545 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -554,7 +554,21 @@ impl<'a> AstValidator<'a> { } match (fk.ctxt(), fk.header()) { - (Some(FnCtxt::Foreign), _) => return, + (Some(FnCtxt::Foreign), Some(header)) => match header.safety { + Safety::Default | Safety::Unsafe(_) => return, + Safety::Safe(span) => { + self.dcx().emit_err(errors::CVariadicSafeForeignFunction { + // The span of the "safe " string that should be removed. + safe_span: self + .sess + .psess + .source_map() + .span_until_non_whitespace(span.until(fk.decl().output.span())), + }); + return; + } + }, + (Some(FnCtxt::Free), Some(header)) => match header.ext { Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }, _) | Extern::Explicit(StrLit { symbol_unescaped: sym::C_dash_unwind, .. }, _) diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 6f9737e08314e..e6dc83b291158 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -308,12 +308,25 @@ pub(crate) struct ExternItemAscii { } #[derive(Diagnostic)] -#[diag(ast_passes_bad_c_variadic)] +#[diag(ast_passes_c_variadic_bad_calling_convention)] pub(crate) struct BadCVariadic { #[primary_span] pub span: Vec, } +#[derive(Diagnostic)] +#[diag(ast_passes_c_variadic_safe_foreign_function)] +pub(crate) struct CVariadicSafeForeignFunction { + #[primary_span] + #[suggestion( + ast_passes_suggestion, + applicability = "machine-applicable", + code = "", + style = "verbose" + )] + pub safe_span: Span, +} + #[derive(Diagnostic)] #[diag(ast_passes_item_underscore)] pub(crate) struct ItemUnderscore<'a> { diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 211e2a92f73d8..c15d7d6f732c9 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -1,6 +1,7 @@ use std::{fmt, iter, mem}; use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; +use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; use rustc_index::Idx; use rustc_middle::mir::*; @@ -254,8 +255,19 @@ where // impl_item_refs may be empty if drop fn is not implemented in 'impl AsyncDrop for ...' // (#140974). // Such code will report error, so just generate sync drop here and return - let Some(drop_fn_def_id) = - tcx.associated_item_def_ids(drop_trait).into_iter().nth(0).copied() + let Some(drop_fn_def_id) = tcx + .associated_item_def_ids(drop_trait) + .first() + .and_then(|def_id| { + if tcx.def_kind(def_id) == DefKind::AssocFn + && tcx.check_args_compatible(*def_id, trait_args) + { + Some(def_id) + } else { + None + } + }) + .copied() else { tcx.dcx().span_delayed_bug( self.elaborator.body().span, diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index cfeaee0777610..71aba1e60647b 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -35,8 +35,6 @@ fn do_check_simd_vector_abi<'tcx>( is_call: bool, loc: impl Fn() -> (Span, HirId), ) { - // We check this on all functions, including those using the "Rust" ABI. - // For the "Rust" ABI it would be a bug if the lint ever triggered, but better safe than sorry. let feature_def = tcx.sess.target.features_for_correct_vector_abi(); let codegen_attrs = tcx.codegen_fn_attrs(def_id); let have_feature = |feat: Symbol| { @@ -123,8 +121,9 @@ fn do_check_wasm_abi<'tcx>( is_call: bool, loc: impl Fn() -> (Span, HirId), ) { - // Only proceed for `extern "C" fn` on wasm32-unknown-unknown (same check as what `adjust_for_foreign_abi` uses to call `compute_wasm_abi_info`), - // and only proceed if `wasm_c_abi_opt` indicates we should emit the lint. + // Only proceed for `extern "C" fn` on wasm32-unknown-unknown (same check as what + // `adjust_for_foreign_abi` uses to call `compute_wasm_abi_info`), and only proceed if + // `wasm_c_abi_opt` indicates we should emit the lint. if !(tcx.sess.target.arch == "wasm32" && tcx.sess.target.os == "unknown" && tcx.wasm_c_abi_opt() == WasmCAbi::Legacy { with_lint: true } @@ -157,8 +156,15 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { else { // An error will be reported during codegen if we cannot determine the ABI of this // function. + tcx.dcx().delayed_bug("ABI computation failure should lead to compilation failure"); return; }; + // Unlike the call-site check, we do also check "Rust" ABI functions here. + // This should never trigger, *except* if we start making use of vector registers + // for the "Rust" ABI and the user disables those vector registers (which should trigger a + // warning as that's clearly disabling a "required" target feature for this target). + // Using such a function is where disabling the vector register actually can start leading + // to soundness issues, so erroring here seems good. let loc = || { let def_id = instance.def_id(); ( @@ -179,7 +185,8 @@ fn check_call_site_abi<'tcx>( loc: impl Fn() -> (Span, HirId) + Copy, ) { if callee.fn_sig(tcx).abi().is_rustic_abi() { - // we directly handle the soundness of Rust ABIs + // We directly handle the soundness of Rust ABIs -- so let's skip the majority of + // call sites to avoid a perf regression. return; } let typing_env = ty::TypingEnv::fully_monomorphized(); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 970faf2997c5b..4e842a8f93a8f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -937,8 +937,10 @@ symbols! { external_doc, f, f128, + f128_epsilon, f128_nan, f16, + f16_epsilon, f16_nan, f16c_target_feature, f32, diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 907614520a2cf..4449cf4e5f21e 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -8,7 +8,7 @@ use rustc_abi::{ }; use rustc_macros::HashStable_Generic; -use crate::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, RustcAbi, WasmCAbi}; +use crate::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, WasmCAbi}; mod aarch64; mod amdgpu; @@ -733,24 +733,6 @@ impl<'a, Ty> FnAbi<'a, Ty> { _ => {} }; - // Decides whether we can pass the given SIMD argument via `PassMode::Direct`. - // May only return `true` if the target will always pass those arguments the same way, - // no matter what the user does with `-Ctarget-feature`! In other words, whatever - // target features are required to pass a SIMD value in registers must be listed in - // the `abi_required_features` for the current target and ABI. - let can_pass_simd_directly = |arg: &ArgAbi<'_, Ty>| match &*spec.arch { - // On x86, if we have SSE2 (which we have by default for x86_64), we can always pass up - // to 128-bit-sized vectors. - "x86" if spec.rustc_abi == Some(RustcAbi::X86Sse2) => arg.layout.size.bits() <= 128, - "x86_64" if spec.rustc_abi != Some(RustcAbi::X86Softfloat) => { - // FIXME once https://github.com/bytecodealliance/wasmtime/issues/10254 is fixed - // accept vectors up to 128bit rather than vectors of exactly 128bit. - arg.layout.size.bits() == 128 - } - // So far, we haven't implemented this logic for any other target. - _ => false, - }; - for (arg_idx, arg) in self .args .iter_mut() @@ -850,9 +832,10 @@ impl<'a, Ty> FnAbi<'a, Ty> { // target feature sets. Some more information about this // issue can be found in #44367. // - // Note that the intrinsic ABI is exempt here as those are not - // real functions anyway, and the backend expects very specific types. - if spec.simd_types_indirect && !can_pass_simd_directly(arg) { + // We *could* do better in some cases, e.g. on x86_64 targets where SSE2 is + // required. However, it turns out that that makes LLVM worse at optimizing this + // code, so we pass things indirectly even there. See #139029 for more on that. + if spec.simd_types_indirect { arg.make_indirect(); } } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 700fb0f386eed..9991b76cd0a3c 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -200,7 +200,7 @@ pub trait Unsize { /// /// Constants are only allowed as patterns if (a) their type implements /// `PartialEq`, and (b) interpreting the value of the constant as a pattern -/// is equialent to calling `PartialEq`. This ensures that constants used as +/// is equivalent to calling `PartialEq`. This ensures that constants used as /// patterns cannot expose implementation details in an unexpected way or /// cause semver hazards. /// diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 6b9b2ba868911..58de62a8be8d8 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -171,6 +171,7 @@ impl f128 { /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon /// [`MANTISSA_DIGITS`]: f128::MANTISSA_DIGITS #[unstable(feature = "f128", issue = "116909")] + #[rustc_diagnostic_item = "f128_epsilon"] pub const EPSILON: f128 = 1.92592994438723585305597794258492732e-34_f128; /// Smallest finite `f128` value. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index eb7af993c60a0..45f402d496717 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -168,6 +168,7 @@ impl f16 { /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon /// [`MANTISSA_DIGITS`]: f16::MANTISSA_DIGITS #[unstable(feature = "f16", issue = "116909")] + #[rustc_diagnostic_item = "f16_epsilon"] pub const EPSILON: f16 = 9.7656e-4_f16; /// Smallest finite `f16` value. diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index 324b5451873bf..a5c3a6c46a433 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -159,8 +159,11 @@ impl OnceLock { /// Gets the mutable reference to the underlying value. /// - /// Returns `None` if the cell is uninitialized, or being initialized. - /// This method never blocks. + /// Returns `None` if the cell is uninitialized. + /// + /// This method never blocks. Since it borrows the `OnceLock` mutably, + /// it is statically guaranteed that no active borrows to the `OnceLock` + /// exist, including from other threads. #[inline] #[stable(feature = "once_cell", since = "1.70.0")] pub fn get_mut(&mut self) -> Option<&mut T> { @@ -315,7 +318,9 @@ impl OnceLock { /// Gets the mutable reference of the contents of the cell, initializing /// it to `f()` if the cell was uninitialized. /// - /// This method never blocks. + /// This method never blocks. Since it borrows the `OnceLock` mutably, + /// it is statically guaranteed that no active borrows to the `OnceLock` + /// exist, including from other threads. /// /// # Panics /// @@ -405,7 +410,9 @@ impl OnceLock { /// it to `f()` if the cell was uninitialized. If the cell was uninitialized /// and `f()` failed, an error is returned. /// - /// This method never blocks. + /// This method never blocks. Since it borrows the `OnceLock` mutably, + /// it is statically guaranteed that no active borrows to the `OnceLock` + /// exist, including from other threads. /// /// # Panics /// @@ -469,7 +476,8 @@ impl OnceLock { /// /// Has no effect and returns `None` if the `OnceLock` was uninitialized. /// - /// Safety is guaranteed by requiring a mutable reference. + /// Since this method borrows the `OnceLock` mutably, it is statically guaranteed that + /// no active borrows to the `OnceLock` exist, including from other threads. /// /// # Examples /// diff --git a/tests/codegen/abi-x86-sse.rs b/tests/codegen/abi-x86-sse.rs index 837bf6134b01c..90757e601af41 100644 --- a/tests/codegen/abi-x86-sse.rs +++ b/tests/codegen/abi-x86-sse.rs @@ -27,8 +27,9 @@ trait Copy {} #[repr(simd)] pub struct Sse([f32; 4]); -// x86-64: <4 x float> @sse_id(<4 x float> {{[^,]*}}) -// x86-32: <4 x float> @sse_id(<4 x float> {{[^,]*}}) +// FIXME: due to #139029 we are passing them all indirectly. +// x86-64: void @sse_id(ptr{{( [^,]*)?}} sret([16 x i8]){{( .*)?}}, ptr{{( [^,]*)?}}) +// x86-32: void @sse_id(ptr{{( [^,]*)?}} sret([16 x i8]){{( .*)?}}, ptr{{( [^,]*)?}}) // x86-32-nosse: void @sse_id(ptr{{( [^,]*)?}} sret([16 x i8]){{( .*)?}}, ptr{{( [^,]*)?}}) #[no_mangle] pub fn sse_id(x: Sse) -> Sse { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs index d3853361de9ed..939461da493c2 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs @@ -1,14 +1,5 @@ // //@ compile-flags: -C no-prepopulate-passes -// LLVM IR isn't very portable and the one tested here depends on the ABI -// which is different between x86 (where we use SSE registers) and others. -// `x86-64` and `x86-32-sse2` are identical, but compiletest does not support -// taking the union of multiple `only` annotations. -//@ revisions: x86-64 x86-32-sse2 other -//@[x86-64] only-x86_64 -//@[x86-32-sse2] only-rustc_abi-x86-sse2 -//@[other] ignore-rustc_abi-x86-sse2 -//@[other] ignore-x86_64 #![crate_type = "lib"] #![allow(non_camel_case_types)] @@ -47,9 +38,7 @@ pub fn build_array_s(x: [f32; 4]) -> S<4> { #[no_mangle] pub fn build_array_transmute_s(x: [f32; 4]) -> S<4> { // CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]] - // x86-32: ret <4 x float> %[[VAL:.+]] - // x86-64: ret <4 x float> %[[VAL:.+]] - // other: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] + // CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] unsafe { std::mem::transmute(x) } } @@ -64,8 +53,6 @@ pub fn build_array_t(x: [f32; 4]) -> T { #[no_mangle] pub fn build_array_transmute_t(x: [f32; 4]) -> T { // CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]] - // x86-32: ret <4 x float> %[[VAL:.+]] - // x86-64: ret <4 x float> %[[VAL:.+]] - // other: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] + // CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] unsafe { std::mem::transmute(x) } } diff --git a/tests/codegen/simd/packed-simd.rs b/tests/codegen/simd/packed-simd.rs index a27d5e3af452a..73e0d29d7d67c 100644 --- a/tests/codegen/simd/packed-simd.rs +++ b/tests/codegen/simd/packed-simd.rs @@ -30,16 +30,18 @@ fn load(v: PackedSimd) -> FullSimd { } } -// CHECK-LABEL: define <3 x float> @square_packed_full(ptr{{[a-z_ ]*}} align 4 {{[^,]*}}) +// CHECK-LABEL: square_packed_full +// CHECK-SAME: ptr{{[a-z_ ]*}} sret([[RET_TYPE:[^)]+]]) [[RET_ALIGN:align (8|16)]]{{[^%]*}} [[RET_VREG:%[_0-9]*]] +// CHECK-SAME: ptr{{[a-z_ ]*}} align 4 #[no_mangle] pub fn square_packed_full(x: PackedSimd) -> FullSimd { - // The unoptimized version of this is not very interesting to check - // since `load` does not get inlined. - // opt3-NEXT: start: - // opt3-NEXT: load <3 x float> + // CHECK-NEXT: start + // noopt: alloca [[RET_TYPE]], [[RET_ALIGN]] + // CHECK: load <3 x float> let x = load(x); - // opt3-NEXT: [[VREG:%[a-z0-9_]+]] = fmul <3 x float> - // opt3-NEXT: ret <3 x float> [[VREG:%[a-z0-9_]+]] + // CHECK: [[VREG:%[a-z0-9_]+]] = fmul <3 x float> + // CHECK-NEXT: store <3 x float> [[VREG]], ptr [[RET_VREG]], [[RET_ALIGN]] + // CHECK-NEXT: ret void unsafe { intrinsics::simd_mul(x, x) } } diff --git a/tests/crashes/140484.rs b/tests/crashes/140484.rs deleted file mode 100644 index 92ec19843982d..0000000000000 --- a/tests/crashes/140484.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #140484 -//@edition:2024 -#![feature(async_drop)] -use std::future::AsyncDrop; -struct a; -impl Drop for a { - fn b() {} -} -impl AsyncDrop for a { - type c; -} -async fn bar() { - a; -} diff --git a/tests/crashes/140500.rs b/tests/crashes/140500.rs deleted file mode 100644 index ee5b93ab82132..0000000000000 --- a/tests/crashes/140500.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #140500 - -#![feature(async_drop)] -use std::future::AsyncDrop; -struct a; -impl Drop for a { - fn b() {} -} -impl AsyncDrop for a { - fn c(d: impl Sized) {} -} -async fn bar() { - a; -} diff --git a/tests/ui/async-await/async-drop/type-parameter.rs b/tests/ui/async-await/async-drop/type-parameter.rs new file mode 100644 index 0000000000000..dde5f9f8e6444 --- /dev/null +++ b/tests/ui/async-await/async-drop/type-parameter.rs @@ -0,0 +1,16 @@ +//@ edition: 2024 +// ex-ice: #140500 +#![crate_type = "lib"] +#![feature(async_drop)] +#![expect(incomplete_features)] +use std::future::AsyncDrop; +struct A; +impl Drop for A { + fn drop(&mut self) {} +} +impl AsyncDrop for A { + fn drop(_wrong: impl Sized) {} //~ ERROR: method `drop` has a `self: Pin<&mut Self>` declaration in the trait, but not in the impl +} +async fn bar() { + A; +} diff --git a/tests/ui/async-await/async-drop/type-parameter.stderr b/tests/ui/async-await/async-drop/type-parameter.stderr new file mode 100644 index 0000000000000..841576b839e68 --- /dev/null +++ b/tests/ui/async-await/async-drop/type-parameter.stderr @@ -0,0 +1,11 @@ +error[E0186]: method `drop` has a `self: Pin<&mut Self>` declaration in the trait, but not in the impl + --> $DIR/type-parameter.rs:12:5 + | +LL | fn drop(_wrong: impl Sized) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `self: Pin<&mut Self>` in impl + | + = note: `drop` from trait: `fn(Pin<&mut Self>) -> impl Future` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0186`. diff --git a/tests/ui/async-await/async-drop/unexpected-sort.rs b/tests/ui/async-await/async-drop/unexpected-sort.rs new file mode 100644 index 0000000000000..659e21eb24119 --- /dev/null +++ b/tests/ui/async-await/async-drop/unexpected-sort.rs @@ -0,0 +1,18 @@ +// Ex-ice: #140484 +//@ edition: 2024 +#![crate_type = "lib"] +#![allow(incomplete_features)] +#![allow(non_camel_case_types)] +#![feature(async_drop)] +use std::future::AsyncDrop; +struct a; +impl Drop for a { //~ ERROR: not all trait items implemented, missing: `drop` + fn b() {} //~ ERROR: method `b` is not a member of trait `Drop` +} +impl AsyncDrop for a { //~ ERROR: not all trait items implemented, missing: `drop` + type c = (); + //~^ ERROR: type `c` is not a member of trait `AsyncDrop` +} +async fn bar() { + a; +} diff --git a/tests/ui/async-await/async-drop/unexpected-sort.stderr b/tests/ui/async-await/async-drop/unexpected-sort.stderr new file mode 100644 index 0000000000000..a6e4f9fd57307 --- /dev/null +++ b/tests/ui/async-await/async-drop/unexpected-sort.stderr @@ -0,0 +1,32 @@ +error[E0407]: method `b` is not a member of trait `Drop` + --> $DIR/unexpected-sort.rs:10:5 + | +LL | fn b() {} + | ^^^^^^^^^ not a member of trait `Drop` + +error[E0437]: type `c` is not a member of trait `AsyncDrop` + --> $DIR/unexpected-sort.rs:13:5 + | +LL | type c = (); + | ^^^^^^^^^^^^ not a member of trait `AsyncDrop` + +error[E0046]: not all trait items implemented, missing: `drop` + --> $DIR/unexpected-sort.rs:9:1 + | +LL | impl Drop for a { + | ^^^^^^^^^^^^^^^ missing `drop` in implementation + | + = help: implement the missing item: `fn drop(&mut self) { todo!() }` + +error[E0046]: not all trait items implemented, missing: `drop` + --> $DIR/unexpected-sort.rs:12:1 + | +LL | impl AsyncDrop for a { + | ^^^^^^^^^^^^^^^^^^^^ missing `drop` in implementation + | + = help: implement the missing item: `async fn drop(self: Pin<&mut Self>) { todo!() }` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0046, E0407, E0437. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs index 58370bff2200e..e0be6faf40113 100644 --- a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs +++ b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs @@ -13,4 +13,19 @@ fn win(f: extern "win64" fn(usize, ...)) { f(22, 44); } +extern "efiapi" { + fn extern_efiapi(...); + //~^ ERROR using calling conventions other than `C` or `cdecl` for varargs functions is unstable [E0658] +} + +extern "sysv64" { + fn extern_sysv64(...); + //~^ ERROR using calling conventions other than `C` or `cdecl` for varargs functions is unstable [E0658] +} + +extern "win64" { + fn extern_win64(...); + //~^ ERROR using calling conventions other than `C` or `cdecl` for varargs functions is unstable [E0658] +} + fn main() {} diff --git a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr index 9565575dc4279..3f6685faa9d2e 100644 --- a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr +++ b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr @@ -28,6 +28,36 @@ LL | fn win(f: extern "win64" fn(usize, ...)) { = help: add `#![feature(extended_varargs_abi_support)]` 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 3 previous errors +error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable + --> $DIR/feature-gate-extended_varargs_abi_support.rs:17:5 + | +LL | fn extern_efiapi(...); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #100189 for more information + = help: add `#![feature(extended_varargs_abi_support)]` 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]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable + --> $DIR/feature-gate-extended_varargs_abi_support.rs:22:5 + | +LL | fn extern_sysv64(...); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #100189 for more information + = help: add `#![feature(extended_varargs_abi_support)]` 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]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable + --> $DIR/feature-gate-extended_varargs_abi_support.rs:27:5 + | +LL | fn extern_win64(...); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #100189 for more information + = help: add `#![feature(extended_varargs_abi_support)]` 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 6 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index 1cd6d13d56b6b..11ede2cded6fc 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -83,3 +83,12 @@ trait T { //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg //~| ERROR `...` must be the last argument of a C-variadic function } + +unsafe extern "C" { + safe fn s_f1(...); + //~^ ERROR foreign functions with a C-variadic argument cannot be safe + safe fn printf(format: *const u8, ...); + //~^ ERROR foreign functions with a C-variadic argument cannot be safe + safe fn snprintf(s: *mut u8, n: usize, format: *const u8, ...); + //~^ ERROR foreign functions with a C-variadic argument cannot be safe +} diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index b740cef020055..9a4fb5a254647 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -201,6 +201,42 @@ error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` function LL | fn t_f6(..., x: isize); | ^^^ +error: foreign functions with a C-variadic argument cannot be safe + --> $DIR/variadic-ffi-semantic-restrictions.rs:88:5 + | +LL | safe fn s_f1(...); + | ^^^^^ + | +help: remove the `safe` keyword from this definition + | +LL - safe fn s_f1(...); +LL + fn s_f1(...); + | + +error: foreign functions with a C-variadic argument cannot be safe + --> $DIR/variadic-ffi-semantic-restrictions.rs:90:5 + | +LL | safe fn printf(format: *const u8, ...); + | ^^^^^ + | +help: remove the `safe` keyword from this definition + | +LL - safe fn printf(format: *const u8, ...); +LL + fn printf(format: *const u8, ...); + | + +error: foreign functions with a C-variadic argument cannot be safe + --> $DIR/variadic-ffi-semantic-restrictions.rs:92:5 + | +LL | safe fn snprintf(s: *mut u8, n: usize, format: *const u8, ...); + | ^^^^^ + | +help: remove the `safe` keyword from this definition + | +LL - safe fn snprintf(s: *mut u8, n: usize, format: *const u8, ...); +LL + fn snprintf(s: *mut u8, n: usize, format: *const u8, ...); + | + error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:32:43 | @@ -225,6 +261,6 @@ LL | const fn i_f5(x: isize, ...) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 36 previous errors +error: aborting due to 39 previous errors For more information about this error, try `rustc --explain E0493`.