From 61da34c350672835bb8a0e32f0b42cba0cebb756 Mon Sep 17 00:00:00 2001 From: ltdk Date: Wed, 16 Sep 2026 13:08:24 -0400 Subject: [PATCH 1/2] Add extra types to `VaArgSafe` --- compiler/rustc_attr_ir/src/lang_items.rs | 1 + .../src/interpret/intrinsics.rs | 158 +++- compiler/rustc_middle/src/ty/sty.rs | 5 + library/core/src/ffi/va_list.rs | 28 +- library/core/src/num/nonzero.rs | 1 + tests/ui/c-variadic/roundtrip.rs | 94 ++- tests/ui/consts/const-eval/c-variadic-fail.rs | 143 +++- .../consts/const-eval/c-variadic-fail.stderr | 785 +++++++++++++++--- tests/ui/consts/const-eval/c-variadic.rs | 20 + 9 files changed, 1027 insertions(+), 208 deletions(-) diff --git a/compiler/rustc_attr_ir/src/lang_items.rs b/compiler/rustc_attr_ir/src/lang_items.rs index 60890f7799290..a4d06e740aebc 100644 --- a/compiler/rustc_attr_ir/src/lang_items.rs +++ b/compiler/rustc_attr_ir/src/lang_items.rs @@ -181,6 +181,7 @@ language_item_table! { DynMetadata, sym::dyn_metadata, dyn_metadata, Target::Struct, GenericRequirement::None; NonNull, sym::non_null, non_null_trait, Target::Struct, GenericRequirement::Exact(1); + NonZero, sym::NonZero, nonzero_trait, Target::Struct, GenericRequirement::Exact(1); Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0); UnsafeUnpin, sym::unsafe_unpin, unsafe_unpin_trait, Target::Trait, GenericRequirement::Exact(0); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index b8b372ad1dab1..3a89f747264e8 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -9,7 +9,7 @@ use std::assert_matches; use rustc_abi::{FieldIdx, HasDataLayout, Size, VariantIdx}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; -use rustc_ast::{IntTy, UintTy}; +use rustc_attr_ir::LangItem; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint}; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::ty; @@ -75,6 +75,21 @@ pub enum VarArgCompatible { CastIntTo { source_is_signed: bool }, } +// Kinds of types that are allowed for var-args +enum CoercibleVarArgTy<'tcx> { + /// Integer type. + /// + /// This represents one of the primitive integer types (`iN`, `uN`, `isize`, `usize`) + /// or one of the ABI-equivalent `NonZero` types (`NonZeroIN`, `NonZeroUN`, `NonZeroIsize`, `NonZeroUsize`) + /// or one of the equivalent `NonZero` types wrapped in `Option`. + Int { signed: bool }, + + /// Pointer type. + /// + /// This represents a raw pointer, a reference, `NonNull`, or `NonNull` wrapped in `Option`. + Ptr { target_ty: Ty<'tcx> }, +} + /// Directly returns an `Allocation` containing an absolute path representation of the given type. pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (AllocId, u64) { let path = crate::util::type_name(tcx, ty); @@ -852,6 +867,80 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } + /// First pass for [`Self::validate_c_variadic_compatible_ty`] that operates on a single type. + /// + /// By this point, we have covered the cases of *identical* types (always compatible) and + /// *differently-sized* types (never compatible), and we're only looking for cases where they + /// don't have to be *exactly* the same type, and might still be compatible. + /// + /// Those particular cases are integer types and pointer types, which can be "coerced" into + /// each other based upon a few rules. + fn coercible_c_variadic_compatible_ty(&self, ty: Ty<'tcx>) -> Option> { + match ty.kind() { + // Integers might be cast into different signs + ty::Int(_) => Some(CoercibleVarArgTy::Int { signed: true }), + ty::Uint(_) => Some(CoercibleVarArgTy::Int { signed: false }), + + // Pointers might be cast into similar types + &ty::RawPtr(target_ty, _) => Some(CoercibleVarArgTy::Ptr { target_ty }), + &ty::Ref(_, target_ty, _) => Some(CoercibleVarArgTy::Ptr { target_ty }), + + // If aliases *aren't* normalized by this point, then we wouldn't be able to distinguish + // aliases like `NonZeroU8` from `NonZero`, which would break the below logic + ty::Alias(_, _) => { + bug!("aliases should be normalized by this point? got {ty:?}"); + } + + // Specifically account for three different ADTs which are all lang items: + // * `Option` + // * `NonNull` + // * `NonZero` + &ty::Adt(mut adt, mut generics) => { + // Both `NonNull` and `NonZero` are valid if wrapped in an `Option`, so, first + // unwrap an `Option` type + if let Some(LangItem::Option) = self.tcx.tcx.as_lang_item(adt.did()) { + (adt, generics) = match generics.type_at(0).kind() { + // `NonNull` and `NonZero` are both themselves ADTs, so, just abuse that to + // directly unwrap the option + &ty::Adt(adt, generics) => (adt, generics), + + // Again, normalization ensures `NonZeroU8` is identified as `NonZero` + // instead of as an alias + ty @ ty::Alias(_, _) => { + bug!("aliases should be normalized by this point? got {ty:?}") + } + + // If the `Option` wraps any other type, it certainly isn't `NonNull` or `NonZero` + _ => return None, + }; + } + + match self.tcx.tcx.as_lang_item(adt.did()) { + // `NonNull` is allowed as just a pointer with fewer an alid values + Some(LangItem::NonNull) => { + Some(CoercibleVarArgTy::Ptr { target_ty: generics.type_at(0) }) + } + + // `NonZero` is allowed as just an integer with fewer valid values + Some(LangItem::NonZero) => match generics.type_at(0).kind() { + ty::Int(_) => Some(CoercibleVarArgTy::Int { signed: true }), + ty::Uint(_) => Some(CoercibleVarArgTy::Int { signed: false }), + + // this could happen for something like `NonZero`, + // so, it's not strictly a bug + _ => None, + }, + + // Any other type is disallowed + _ => None, + } + } + + // All other types are definitely not valid here + _ => None, + } + } + /// Check whether the caller and callee type are compatible for c-variadic calls. Further /// validation of the argument value may be needed to detect all UB. /// @@ -878,29 +967,33 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return interp_ok(VarArgCompatible::Compatible); } - if self.layout_of(caller_type)?.size != self.layout_of(callee_type)?.size { + // All other cases require that the layout of the types match; + // in practice, since the only types that could get to this point are integers and pointers, + // the alignment check isn't necessary, but might as well verify + if self.layout_of(caller_type)?.size != self.layout_of(callee_type)?.size + || self.layout_of(caller_type)?.align != self.layout_of(callee_type)?.align + { return interp_ok(VarArgCompatible::Incompatible); } - // Any character type (`char`, `unsigned char` and `signed char`) is compatible with - // `void*`, so the signedness of `c_char` is irrelevant here. - let is_c_char = |ty: Ty<'_>| matches!(ty.kind(), ty::Uint(UintTy::U8) | ty::Int(IntTy::I8)); + // Since we've already checked for identical types and have narrowed down the layouts as + // being identical, we can filter out any non-integer, non-pointer types and similarly + // normalize integer and pointer types to make matching easier + let Some(caller_type) = self.coercible_c_variadic_compatible_ty(caller_type) else { + return interp_ok(VarArgCompatible::Incompatible); + }; + let Some(callee_type) = self.coercible_c_variadic_compatible_ty(callee_type) else { + return interp_ok(VarArgCompatible::Incompatible); + }; - match (caller_type.kind(), callee_type.kind()) { - // Some types look different but are actually the same for ABI purposes. - (ty::Int(_), ty::Int(_)) | (ty::Uint(_), ty::Uint(_)) => { - // E.g. cast between `usize` and `u64` on a 64-bit platform. - interp_ok(VarArgCompatible::Compatible) - } + match (caller_type, callee_type) { // C allows different types if... // - "both types are pointers to qualified or unqualified versions of compatible types" // - "one type is pointer to qualified or unqualified void and the other is a pointer to a qualified or // unqualified character type" - // - // As usual for the ABI, we treat references and raw pointers alike. ( - ty::RawPtr(caller_target_ty, _) | ty::Ref(_, caller_target_ty, _), - ty::RawPtr(callee_target_ty, _) | ty::Ref(_, callee_target_ty, _), + CoercibleVarArgTy::Ptr { target_ty: caller_target_ty }, + CoercibleVarArgTy::Ptr { target_ty: callee_target_ty }, ) => { // In C, types can be qualified by a combination of `const`, `volatile` and // `restrict`. These properties are irrelevant for the ABI, and don't have an @@ -908,17 +1001,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Accept the cast if one type is pointer to void, and the other is a pointer to // a character type (`char`, `unsigned char` and `signed char`). - if caller_target_ty.is_c_void(self.tcx.tcx) && is_c_char(*callee_target_ty) { - return interp_ok(VarArgCompatible::Compatible); - } - if callee_target_ty.is_c_void(self.tcx.tcx) && is_c_char(*caller_target_ty) { + if (caller_target_ty.is_c_void(self.tcx.tcx) + || callee_target_ty.is_c_void(self.tcx.tcx)) + && (caller_target_ty.is_byte_sized_integral() + || callee_target_ty.is_byte_sized_integral()) + { return interp_ok(VarArgCompatible::Compatible); } // Accept the cast if both types are pointers to compatible types. - match self - .validate_c_variadic_compatible_ty(*caller_target_ty, *callee_target_ty)? - { + match self.validate_c_variadic_compatible_ty(caller_target_ty, callee_target_ty)? { VarArgCompatible::Incompatible => interp_ok(VarArgCompatible::Incompatible), VarArgCompatible::Compatible => interp_ok(VarArgCompatible::Compatible), VarArgCompatible::CastIntTo { source_is_signed: _ } => { @@ -929,16 +1021,26 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } // - "one type is a signed integer type, the other type is the corresponding unsigned integer type, // and the value is representable in both types" - (ty::Int(_), ty::Uint(_)) => { - interp_ok(VarArgCompatible::CastIntTo { source_is_signed: true }) - } - (ty::Uint(_), ty::Int(_)) => { - interp_ok(VarArgCompatible::CastIntTo { source_is_signed: false }) + ( + CoercibleVarArgTy::Int { signed: caller_signed }, + CoercibleVarArgTy::Int { signed: callee_signed }, + ) => { + // Note: we already know that the layout is identical + if caller_signed == callee_signed { + // So, if the signedness is the same, this means that one of the types is + // `usize` or `isize`, which have the same ABI as their same-layout counterparts + interp_ok(VarArgCompatible::Compatible) + } else { + // And if the signedness is different, this means that we're casting by changing + // the sign but not the size of the integer type, which is fine + interp_ok(VarArgCompatible::CastIntTo { source_is_signed: caller_signed }) + } } + // (integer-pointer conversion is explicitly not allowed) + _ => interp_ok(VarArgCompatible::Incompatible), // - "or, the type of the next argument is nullptr_t and type is a pointer type that has the same // representation and alignment requirements as a pointer to a character type" // This one does not have an equivalent form in Rust. - _ => interp_ok(VarArgCompatible::Incompatible), } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 925915c88cdb4..899d8a2d7bfb2 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1523,6 +1523,11 @@ impl<'tcx> Ty<'tcx> { matches!(self.kind(), Int(ty::IntTy::Isize) | Uint(ty::UintTy::Usize)) } + #[inline] + pub fn is_byte_sized_integral(self) -> bool { + matches!(self.kind(), Int(ty::IntTy::I8) | Uint(ty::UintTy::U8)) + } + #[inline] pub fn has_concrete_skeleton(self) -> bool { !matches!(self.kind(), Param(_) | Infer(_) | Error(_)) diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index b308cb7f85df2..36f7dcf396bc7 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -7,6 +7,8 @@ use crate::ffi::c_void; use crate::fmt; use crate::intrinsics::{va_arg, va_copy, va_end}; use crate::marker::PhantomCovariantLifetime; +use crate::num::{NonZero, ZeroablePrimitive}; +use crate::ptr::NonNull; // There are currently three flavors of how a C `va_list` is implemented for // targets that Rust supports: @@ -465,10 +467,23 @@ cfg_select! { _ => { /* unsupported */ } } +#[unstable(feature = "c_variadic_va_arg_safe", issue = "162911", implied_by = "c_variadic")] +unsafe impl VaArgSafe for NonZero {} +#[unstable(feature = "c_variadic_va_arg_safe", issue = "162911", implied_by = "c_variadic")] +unsafe impl VaArgSafe for Option> {} + +#[unstable(feature = "c_variadic_va_arg_safe", issue = "162911", implied_by = "c_variadic")] +unsafe impl VaArgSafe for NonNull {} +#[unstable(feature = "c_variadic_va_arg_safe", issue = "162911", implied_by = "c_variadic")] +unsafe impl VaArgSafe for Option> {} #[unstable(feature = "c_variadic_va_arg_safe", issue = "162911", implied_by = "c_variadic")] unsafe impl VaArgSafe for *mut T {} #[unstable(feature = "c_variadic_va_arg_safe", issue = "162911", implied_by = "c_variadic")] unsafe impl VaArgSafe for *const T {} +#[unstable(feature = "c_variadic_va_arg_safe", issue = "162911", implied_by = "c_variadic")] +unsafe impl VaArgSafe for &mut T {} +#[unstable(feature = "c_variadic_va_arg_safe", issue = "162911", implied_by = "c_variadic")] +unsafe impl VaArgSafe for &T {} // Check that relevant `core::ffi` types implement `VaArgSafe`. const _: () = { @@ -506,15 +521,18 @@ impl<'f> VaList<'f> { /// representable in both types. /// - If `T` is not [`Copy`], then it must not have already been read using `next_arg` /// on a [`clone`][VaList::clone]d copy of this `VaList`. - /// (Currently, all types implementing [`VaArgSafe`] also implement [`Copy`], - /// but this may change in the future.) + /// - The value passed in for `U` must be transmutable to `T`. (e.g., converting a null pointer + /// to `NonNull` is invalid) /// /// Types `T` and `U` are compatible when: /// /// - `T` and `U` are the same type. - /// - `T` and `U` are integer types of the same size. - /// - `T` and `U` are both pointers, and their target types are compatible. - /// - `T` is a pointer to [`c_void`] and `U` is a pointer to [`i8`] or [`u8`], or vice versa. + /// - `T` and `U` are integer types of the same size, + /// which also applies for `NonZero<_>` and `Option>`. + /// - `T` and `U` are both pointer-like, and their target types are compatible. + /// This includes pointers, references, `NonNull<_>`, and `Option>`. + /// - `T` is a pointer to [`c_void`] and `U` is a pointer to a size-1 integer type, + /// or vice versa. /// /// [`c_void`]: core::ffi::c_void #[inline] // Avoid codegen when not used to help backends that don't support VaList. diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index c97e6f4c45395..331ad40bdc39f 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -109,6 +109,7 @@ impl_zeroable_primitive!( #[repr(transparent)] #[rustc_nonnull_optimization_guaranteed] #[rustc_diagnostic_item = "NonZero"] +#[lang = "NonZero"] pub struct NonZero(T::NonZeroInner); macro_rules! impl_nonzero_fmt { diff --git a/tests/ui/c-variadic/roundtrip.rs b/tests/ui/c-variadic/roundtrip.rs index 1fb96ab7cfad7..79c772b35ce47 100644 --- a/tests/ui/c-variadic/roundtrip.rs +++ b/tests/ui/c-variadic/roundtrip.rs @@ -1,16 +1,24 @@ //@ run-pass //@ ignore-backends: gcc -#![feature( - const_c_variadic, - c_variadic_va_arg_safe, - c_variadic_int128, - const_destruct, - const_raw_ptr_comparison, - f128 -)] +// tidy-alphabetical-start +#![feature(c_variadic_int128)] +#![feature(c_variadic_va_arg_safe)] +#![feature(const_c_variadic)] +#![feature(const_cmp)] +#![feature(const_convert)] +#![feature(const_destruct)] +#![feature(const_option_ops)] +#![feature(const_raw_ptr_comparison)] +#![feature(const_trait_impl)] +#![feature(f128)] +// tidy-alphabetical-end +#![allow(static_mut_refs)] #![allow(unused_features)] // c_variadic_int128 is only used on 64-bit targets. +use std::convert::identity; use std::ffi::*; +use std::num::NonZero; +use std::ptr::{self, NonNull}; // In rustc we implement `va_arg` for the callee reading from a VaList, but still rely on LLVM // for exactly how to pass c-variadic arguments and for constructing the VaList. Here we test @@ -44,37 +52,59 @@ macro_rules! roundtrip { }; } +macro_rules! roundtrip_zeroable { + ($ty:ty, $a:expr, $b:expr) => { + roundtrip!($ty, $a, $b); + roundtrip!(NonZero<$ty>, NonZero::new($a).unwrap(), NonZero::new($b).unwrap()); + roundtrip!(Option>, None, NonZero::new($a)); + }; +} + macro_rules! roundtrip_ptr { ($ty:ty, $a:expr, $b:expr) => { + roundtrip_ptr!($ty, $a, $b, identity); + }; + ($ty:ty, $a:expr, $b:expr, $conv:expr) => { const { let a: $ty = $a; let b: $ty = $b; + let conv = $conv; + + // note: we need to convert references to raw pointers to avoid aliasing + let a2 = conv(a); + let b2 = conv(b); let (x, y) = variadic::<$ty>(a, 0xAAAA_AAAAu32, b); - assert!(a.guaranteed_eq(x).unwrap()); - assert!(b.guaranteed_eq(y).unwrap()); + assert!(a2.guaranteed_eq(conv(x)).unwrap()); + assert!(b2.guaranteed_eq(conv(y)).unwrap()); } let a: $ty = $a; let b: $ty = $b; - assert_eq!(variadic::<$ty>(a, 0xAAAA_AAAAu32, b), (a, b)) + let conv = $conv; + + // note: similarly here, we can't alias the original pointers + let a2 = conv(a); + let b2 = conv(b); + let (x, y) = variadic::<$ty>(a, 0xAAAA_AAAAu32, b); + assert_eq!((conv(x), conv(y)), (a2, b2)) }; } fn main() { unsafe { - roundtrip!(i32, -1, -2); - roundtrip!(i64, -1, -2); - roundtrip!(isize, -1, -2); - roundtrip!(c_int, -1, -2); - roundtrip!(c_long, -1, -2); - roundtrip!(c_longlong, -1, -2); - - roundtrip!(u32, 1, 2); - roundtrip!(u64, 1, 2); - roundtrip!(usize, 1, 2); - roundtrip!(c_uint, 1, 2); - roundtrip!(c_ulong, 1, 2); - roundtrip!(c_ulonglong, 1, 2); + roundtrip_zeroable!(i32, -1, -2); + roundtrip_zeroable!(i64, -1, -2); + roundtrip_zeroable!(isize, -1, -2); + roundtrip_zeroable!(c_int, -1, -2); + roundtrip_zeroable!(c_long, -1, -2); + roundtrip_zeroable!(c_longlong, -1, -2); + + roundtrip_zeroable!(u32, 1, 2); + roundtrip_zeroable!(u64, 1, 2); + roundtrip_zeroable!(usize, 1, 2); + roundtrip_zeroable!(c_uint, 1, 2); + roundtrip_zeroable!(c_ulong, 1, 2); + roundtrip_zeroable!(c_ulonglong, 1, 2); roundtrip!(f64, 3.14, 6.28); roundtrip!(c_double, 3.14, 6.28); @@ -83,6 +113,18 @@ fn main() { static mut B: u32 = 2u32; roundtrip_ptr!(*const u32, &raw const A, &raw const B); roundtrip_ptr!(*mut u32, &raw mut A, &raw mut B); + roundtrip_ptr!(&u32, &A, &B, ptr::from_ref); + roundtrip_ptr!(&mut u32, &mut A, &mut B, ptr::from_mut); + roundtrip_ptr!(NonNull, NonNull::from(&A), NonNull::from(&B), NonNull::as_ptr); + const fn option_as_ptr(x: Option>) -> *mut u32 { + x.map_or_else(ptr::null_mut, NonNull::as_ptr) + } + roundtrip_ptr!( + Option>, + NonNull::new(&raw mut A), + NonNull::new(&raw mut B), + option_as_ptr + ); // The 128-bit integers only implement VaArgSafe on some targets, a subset of those that // define `__int128`. We test some of those targets here. @@ -111,8 +153,8 @@ fn main() { )))] compile_error!("unexpected target architecture for 128-bit c-variadic"); - roundtrip!(i128, -1, -2); - roundtrip!(u128, 1, 2); + roundtrip_zeroable!(i128, -1, -2); + roundtrip_zeroable!(u128, 1, 2); } _ => { /* unsupported */ } } diff --git a/tests/ui/consts/const-eval/c-variadic-fail.rs b/tests/ui/consts/const-eval/c-variadic-fail.rs index 8a46a80653ad1..36a2383f9075e 100644 --- a/tests/ui/consts/const-eval/c-variadic-fail.rs +++ b/tests/ui/consts/const-eval/c-variadic-fail.rs @@ -1,12 +1,15 @@ //@ build-fail +//@ compile-flags: -Zextra-const-ub-checks #![feature(c_variadic_va_arg_safe)] #![feature(const_c_variadic)] #![feature(const_trait_impl)] #![feature(const_destruct)] #![feature(const_clone)] -use std::ffi::{VaList, c_char, c_void}; -use std::mem::MaybeUninit; +use std::ffi::{VaList, c_char, c_void, VaArgSafe}; +use std::mem::{self, MaybeUninit}; +use std::num::NonZero; +use std::ptr::{self, NonNull}; const unsafe extern "C" fn read_n(mut ap: ...) { let mut i = N; @@ -32,10 +35,22 @@ unsafe fn read_too_many() { //~^ ERROR more C-variadic arguments read than were passed } -const unsafe extern "C" fn read_as(mut ap: ...) -> T { +const unsafe extern "C" fn read_as(mut ap: ...) -> T { ap.next_arg::() } +type ConcreteUsize = cfg_select! { + target_pointer_width = "16" => u16, + target_pointer_width = "32" => u32, + target_pointer_width = "64" => u64, +}; + +type ConcreteIsize = cfg_select! { + target_pointer_width = "16" => i16, + target_pointer_width = "32" => i32, + target_pointer_width = "64" => i64, +}; + unsafe fn read_cast_numeric() { const { read_as::(1i32) }; const { read_as::(1u32) }; @@ -50,18 +65,6 @@ unsafe fn read_cast_numeric() { const { read_as::(1i32) }; const { read_as::(1u32) }; - type ConcreteUsize = cfg_select! { - target_pointer_width = "16" => u16, - target_pointer_width = "32" => u32, - target_pointer_width = "64" => u64, - }; - - type ConcreteIsize = cfg_select! { - target_pointer_width = "16" => i16, - target_pointer_width = "32" => i32, - target_pointer_width = "64" => i64, - }; - const { read_as::(1usize) }; const { read_as::(1 as ConcreteUsize) }; @@ -90,52 +93,114 @@ unsafe fn read_cast_numeric() { unsafe fn read_cast_pointer() { // A pointer mutability cast is OK. - const { read_as::<*const i32>(std::ptr::dangling_mut::()) }; - const { read_as::<*mut i32>(std::ptr::dangling::()) }; + const { read_as::<*const i32>(ptr::dangling_mut::()) }; + const { read_as::<*mut i32>(ptr::dangling::()) }; // A pointer cast is OK between compatible types. - const { read_as::<*const i32>(std::ptr::dangling::()) }; - const { read_as::<*const i32>(std::ptr::dangling_mut::()) }; - const { read_as::<*mut i32>(std::ptr::dangling::()) }; - const { read_as::<*mut i32>(std::ptr::dangling_mut::()) }; + const { read_as::<*const i32>(ptr::dangling::()) }; + const { read_as::<*const i32>(ptr::dangling_mut::()) }; + const { read_as::<*mut i32>(ptr::dangling::()) }; + const { read_as::<*mut i32>(ptr::dangling_mut::()) }; // Casting between pointers to i8/u8 and c_void is OK. - const { read_as::<*const c_char>(std::ptr::dangling::()) }; - const { read_as::<*const c_void>(std::ptr::dangling::()) }; - const { read_as::<*const i8>(std::ptr::dangling::()) }; - const { read_as::<*const c_void>(std::ptr::dangling::()) }; - const { read_as::<*const u8>(std::ptr::dangling::()) }; - const { read_as::<*const c_void>(std::ptr::dangling::()) }; - - const { read_as::<*const u16>(std::ptr::dangling::()) }; + const { read_as::<*const c_char>(ptr::dangling::()) }; + const { read_as::<*const c_void>(ptr::dangling::()) }; + const { read_as::<*const i8>(ptr::dangling::()) }; + const { read_as::<*const c_void>(ptr::dangling::()) }; + const { read_as::<*const u8>(ptr::dangling::()) }; + const { read_as::<*const c_void>(ptr::dangling::()) }; + + const { read_as::<*const u16>(ptr::dangling::()) }; //~^ ERROR va_arg type mismatch: requested `*const u16` is incompatible with next argument of type `*const c_void` - const { read_as::<*const c_void>(std::ptr::dangling::()) }; + const { read_as::<*const c_void>(ptr::dangling::()) }; //~^ ERROR va_arg type mismatch: requested `*const c_void` is incompatible with next argument of type `*const u16` - const { read_as::<*const u16>(std::ptr::dangling::()) }; + const { read_as::<*const u16>(ptr::dangling::()) }; //~^ ERROR va_arg type mismatch: requested `*const u16` is incompatible with next argument of type `*const i32` const { read_as::<*const u8>(1usize) }; //~^ ERROR requested `*const u8` is incompatible with next argument of type `usize` } +unsafe fn read_cast_null() { + const { read_as::>(ptr::null::()) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(ptr::null_mut::()) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + + // Casting null to `None` is OK. + const { read_as::>>(ptr::null::()) }; + const { read_as::>>(ptr::null_mut::()) }; + const { read_as::<*const c_void>(None::>) }; + const { read_as::<*mut c_void>(None::>) }; +} + +unsafe fn read_cast_zero() { + const { read_as::>(0u32) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(0i32) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(0u32) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(0i32) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(0usize) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(0isize) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(0usize) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(0isize) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + const { read_as::>(None::>) }; + //~^ ERROR encountered 0, but expected something greater or equal to 1 + + // Casting zero to `None` is OK. + const { read_as::>>(0u32) }; + const { read_as::>>(0i32) }; + const { read_as::(None::>) }; + const { read_as::(None::>) }; + const { read_as::>>(0u32) }; + const { read_as::>>(0i32) }; + const { read_as::(None::>) }; + const { read_as::(None::>) }; +} + unsafe fn read_cast_lifetime() { // The types are equal up to free lifetimes. - const { read_as::<*const &'static i32>(std::ptr::dangling::<&i32>()) }; + const { read_as::<*const &'static i32>(ptr::dangling::<&i32>()) }; // Bound lifetimes do matter. - const { read_as::<*const fn(&'static ())>(std::ptr::dangling:: fn(&'a ())>()) }; + const { read_as::<*const fn(&'static ())>(ptr::dangling:: fn(&'a ())>()) }; //~^ ERROR va_arg type mismatch: requested `*const fn(&())` is incompatible with next argument of type `*const for<'a> fn(&'a ())` } fn use_after_free() { const unsafe extern "C" fn helper(ap: ...) -> [u8; size_of::()] { - unsafe { std::mem::transmute(ap) } + unsafe { mem::transmute(ap) } } const { unsafe { let ap = helper(1, 2, 3); - let mut ap = std::mem::transmute::<_, VaList>(ap); + let mut ap = mem::transmute::<_, VaList>(ap); ap.next_arg::(); //~^ ERROR memory access failed: ALLOC$ID has been freed, so this pointer is dangling [E0080] } @@ -148,7 +213,7 @@ fn manual_copy_drop() { let mut copy = ap.clone(); assert!(copy.next_arg::() == 1i32); - let mut copy: VaList = unsafe { std::mem::transmute_copy(&ap) }; + let mut copy: VaList = unsafe { mem::transmute_copy(&ap) }; // Using the copy is actually fine. let _ = copy.next_arg::(); @@ -164,11 +229,11 @@ fn manual_copy_drop() { fn manual_copy_forget() { const unsafe extern "C" fn helper(ap: ...) { - let mut copy: VaList = unsafe { std::mem::transmute_copy(&ap) }; + let mut copy: VaList = unsafe { mem::transmute_copy(&ap) }; // Using the copy is actually fine. let _ = copy.next_arg::(); - std::mem::forget(copy); + mem::forget(copy); // The read (via `copy`) deallocated the original allocation. drop(ap); @@ -180,7 +245,7 @@ fn manual_copy_forget() { fn manual_copy_read() { const unsafe extern "C" fn helper(mut ap: ...) { - let mut copy: VaList = unsafe { std::mem::transmute_copy(&ap) }; + let mut copy: VaList = unsafe { mem::transmute_copy(&ap) }; // Reading from `ap` after reading from `copy` is UB. let _ = copy.next_arg::(); diff --git a/tests/ui/consts/const-eval/c-variadic-fail.stderr b/tests/ui/consts/const-eval/c-variadic-fail.stderr index ccf2936324a9c..bc980350b1db9 100644 --- a/tests/ui/consts/const-eval/c-variadic-fail.stderr +++ b/tests/ui/consts/const-eval/c-variadic-fail.stderr @@ -1,11 +1,11 @@ error[E0080]: more C-variadic arguments read than were passed - --> $DIR/c-variadic-fail.rs:27:13 + --> $DIR/c-variadic-fail.rs:30:13 | LL | const { read_n::<1>() } | ^^^^^^^^^^^^^ evaluation of `read_too_many::{constant#2}` failed inside this call | note: inside `read_n::<1>` - --> $DIR/c-variadic-fail.rs:15:17 + --> $DIR/c-variadic-fail.rs:18:17 | LL | let _ = ap.next_arg::(); | ^^^^^^^^^^^^^^^^^^^^ @@ -13,13 +13,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:27:5 + --> $DIR/c-variadic-fail.rs:30:5 | LL | const { read_n::<1>() } | ^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:27:5 + --> $DIR/c-variadic-fail.rs:30:5 | LL | const { read_n::<1>() } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,13 +27,13 @@ LL | const { read_n::<1>() } = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: more C-variadic arguments read than were passed - --> $DIR/c-variadic-fail.rs:31:13 + --> $DIR/c-variadic-fail.rs:34:13 | LL | const { read_n::<2>(1) } | ^^^^^^^^^^^^^^ evaluation of `read_too_many::{constant#3}` failed inside this call | note: inside `read_n::<2>` - --> $DIR/c-variadic-fail.rs:15:17 + --> $DIR/c-variadic-fail.rs:18:17 | LL | let _ = ap.next_arg::(); | ^^^^^^^^^^^^^^^^^^^^ @@ -41,13 +41,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:31:5 + --> $DIR/c-variadic-fail.rs:34:5 | LL | const { read_n::<2>(1) } | ^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:31:5 + --> $DIR/c-variadic-fail.rs:34:5 | LL | const { read_n::<2>(1) } | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -55,13 +55,13 @@ LL | const { read_n::<2>(1) } = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg value mismatch: value `-1_i32` cannot be represented by type `u32` - --> $DIR/c-variadic-fail.rs:71:13 + --> $DIR/c-variadic-fail.rs:74:13 | LL | const { read_as::(-1i32) }; | ^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_numeric::{constant#12}` failed inside this call | note: inside `read_as::` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:71:5 + --> $DIR/c-variadic-fail.rs:74:5 | LL | const { read_as::(-1i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:71:5 + --> $DIR/c-variadic-fail.rs:74:5 | LL | const { read_as::(-1i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,13 +83,13 @@ LL | const { read_as::(-1i32) }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg value mismatch: value `-2147483648_i32` cannot be represented by type `u32` - --> $DIR/c-variadic-fail.rs:73:13 + --> $DIR/c-variadic-fail.rs:76:13 | LL | const { read_as::(i32::MIN) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_numeric::{constant#13}` failed inside this call | note: inside `read_as::` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -97,13 +97,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:73:5 + --> $DIR/c-variadic-fail.rs:76:5 | LL | const { read_as::(i32::MIN) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:73:5 + --> $DIR/c-variadic-fail.rs:76:5 | LL | const { read_as::(i32::MIN) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,13 +111,13 @@ LL | const { read_as::(i32::MIN) }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg value mismatch: value `4294967295_u32` cannot be represented by type `i32` - --> $DIR/c-variadic-fail.rs:75:13 + --> $DIR/c-variadic-fail.rs:78:13 | LL | const { read_as::(u32::MAX) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_numeric::{constant#14}` failed inside this call | note: inside `read_as::` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -125,13 +125,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:75:5 + --> $DIR/c-variadic-fail.rs:78:5 | LL | const { read_as::(u32::MAX) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:75:5 + --> $DIR/c-variadic-fail.rs:78:5 | LL | const { read_as::(u32::MAX) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,13 +139,13 @@ LL | const { read_as::(u32::MAX) }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg value mismatch: value `2147483648_u32` cannot be represented by type `i32` - --> $DIR/c-variadic-fail.rs:77:13 + --> $DIR/c-variadic-fail.rs:80:13 | LL | const { read_as::(i32::MAX as u32 + 1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_numeric::{constant#15}` failed inside this call | note: inside `read_as::` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -153,13 +153,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:77:5 + --> $DIR/c-variadic-fail.rs:80:5 | LL | const { read_as::(i32::MAX as u32 + 1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:77:5 + --> $DIR/c-variadic-fail.rs:80:5 | LL | const { read_as::(i32::MAX as u32 + 1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -167,13 +167,13 @@ LL | const { read_as::(i32::MAX as u32 + 1) }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg value mismatch: value `18446744073709551615_u64` cannot be represented by type `i64` - --> $DIR/c-variadic-fail.rs:79:13 + --> $DIR/c-variadic-fail.rs:82:13 | LL | const { read_as::(u64::MAX) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_numeric::{constant#16}` failed inside this call | note: inside `read_as::` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -181,13 +181,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:79:5 + --> $DIR/c-variadic-fail.rs:82:5 | LL | const { read_as::(u64::MAX) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:79:5 + --> $DIR/c-variadic-fail.rs:82:5 | LL | const { read_as::(u64::MAX) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -195,13 +195,13 @@ LL | const { read_as::(u64::MAX) }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg value mismatch: value `9223372036854775808_u64` cannot be represented by type `i64` - --> $DIR/c-variadic-fail.rs:81:13 + --> $DIR/c-variadic-fail.rs:84:13 | LL | const { read_as::(i64::MAX as u64 + 1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_numeric::{constant#17}` failed inside this call | note: inside `read_as::` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -209,13 +209,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:81:5 + --> $DIR/c-variadic-fail.rs:84:5 | LL | const { read_as::(i64::MAX as u64 + 1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:81:5 + --> $DIR/c-variadic-fail.rs:84:5 | LL | const { read_as::(i64::MAX as u64 + 1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -223,13 +223,13 @@ LL | const { read_as::(i64::MAX as u64 + 1) }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg type mismatch: requested `i32` is incompatible with next argument of type `u64` - --> $DIR/c-variadic-fail.rs:84:13 + --> $DIR/c-variadic-fail.rs:87:13 | LL | const { read_as::(1u64) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_numeric::{constant#18}` failed inside this call | note: inside `read_as::` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -237,13 +237,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:84:5 + --> $DIR/c-variadic-fail.rs:87:5 | LL | const { read_as::(1u64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:84:5 + --> $DIR/c-variadic-fail.rs:87:5 | LL | const { read_as::(1u64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -251,13 +251,13 @@ LL | const { read_as::(1u64) }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg type mismatch: requested `f64` is incompatible with next argument of type `i32` - --> $DIR/c-variadic-fail.rs:87:13 + --> $DIR/c-variadic-fail.rs:90:13 | LL | const { read_as::(1i32) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_numeric::{constant#19}` failed inside this call | note: inside `read_as::` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -265,13 +265,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:87:5 + --> $DIR/c-variadic-fail.rs:90:5 | LL | const { read_as::(1i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:87:5 + --> $DIR/c-variadic-fail.rs:90:5 | LL | const { read_as::(1i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,13 +279,13 @@ LL | const { read_as::(1i32) }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg type mismatch: requested `*const u16` is incompatible with next argument of type `*const c_void` - --> $DIR/c-variadic-fail.rs:110:13 + --> $DIR/c-variadic-fail.rs:113:13 | -LL | const { read_as::<*const u16>(std::ptr::dangling::()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_pointer::{constant#12}` failed inside this call +LL | const { read_as::<*const u16>(ptr::dangling::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_pointer::{constant#12}` failed inside this call | note: inside `read_as::<*const u16>` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -293,27 +293,27 @@ note: inside `VaList::<'_>::next_arg::<*const u16>` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:110:5 + --> $DIR/c-variadic-fail.rs:113:5 | -LL | const { read_as::<*const u16>(std::ptr::dangling::()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const { read_as::<*const u16>(ptr::dangling::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:110:5 + --> $DIR/c-variadic-fail.rs:113:5 | -LL | const { read_as::<*const u16>(std::ptr::dangling::()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const { read_as::<*const u16>(ptr::dangling::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg type mismatch: requested `*const c_void` is incompatible with next argument of type `*const u16` - --> $DIR/c-variadic-fail.rs:112:13 + --> $DIR/c-variadic-fail.rs:115:13 | -LL | const { read_as::<*const c_void>(std::ptr::dangling::()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_pointer::{constant#13}` failed inside this call +LL | const { read_as::<*const c_void>(ptr::dangling::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_pointer::{constant#13}` failed inside this call | note: inside `read_as::<*const c_void>` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -321,27 +321,27 @@ note: inside `VaList::<'_>::next_arg::<*const c_void>` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:112:5 + --> $DIR/c-variadic-fail.rs:115:5 | -LL | const { read_as::<*const c_void>(std::ptr::dangling::()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const { read_as::<*const c_void>(ptr::dangling::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:112:5 + --> $DIR/c-variadic-fail.rs:115:5 | -LL | const { read_as::<*const c_void>(std::ptr::dangling::()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const { read_as::<*const c_void>(ptr::dangling::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg type mismatch: requested `*const u16` is incompatible with next argument of type `*const i32` - --> $DIR/c-variadic-fail.rs:114:13 + --> $DIR/c-variadic-fail.rs:117:13 | -LL | const { read_as::<*const u16>(std::ptr::dangling::()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_pointer::{constant#14}` failed inside this call +LL | const { read_as::<*const u16>(ptr::dangling::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_pointer::{constant#14}` failed inside this call | note: inside `read_as::<*const u16>` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -349,27 +349,27 @@ note: inside `VaList::<'_>::next_arg::<*const u16>` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:114:5 + --> $DIR/c-variadic-fail.rs:117:5 | -LL | const { read_as::<*const u16>(std::ptr::dangling::()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const { read_as::<*const u16>(ptr::dangling::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:114:5 + --> $DIR/c-variadic-fail.rs:117:5 | -LL | const { read_as::<*const u16>(std::ptr::dangling::()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const { read_as::<*const u16>(ptr::dangling::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: va_arg type mismatch: requested `*const u8` is incompatible with next argument of type `usize` - --> $DIR/c-variadic-fail.rs:117:13 + --> $DIR/c-variadic-fail.rs:120:13 | LL | const { read_as::<*const u8>(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_pointer::{constant#15}` failed inside this call | note: inside `read_as::<*const u8>` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -377,27 +377,587 @@ note: inside `VaList::<'_>::next_arg::<*const u8>` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:117:5 + --> $DIR/c-variadic-fail.rs:120:5 | LL | const { read_as::<*const u8>(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:117:5 + --> $DIR/c-variadic-fail.rs:120:5 | LL | const { read_as::<*const u8>(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error[E0080]: constructing invalid value of type NonNull: at .pointer, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:125:13 + | +LL | const { read_as::>(ptr::null::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_null::{constant#0}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:125:5 + | +LL | const { read_as::>(ptr::null::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:125:5 + | +LL | const { read_as::>(ptr::null::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonNull: at .pointer, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:127:13 + | +LL | const { read_as::>(ptr::null_mut::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_null::{constant#1}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:127:5 + | +LL | const { read_as::>(ptr::null_mut::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:127:5 + | +LL | const { read_as::>(ptr::null_mut::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonNull: at .pointer, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:129:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_null::{constant#2}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:129:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:129:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonNull: at .pointer, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:131:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_null::{constant#3}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:131:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:131:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:142:13 + | +LL | const { read_as::>(0u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#0}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:142:5 + | +LL | const { read_as::>(0u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:142:5 + | +LL | const { read_as::>(0u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:144:13 + | +LL | const { read_as::>(0i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#1}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:144:5 + | +LL | const { read_as::>(0i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:144:5 + | +LL | const { read_as::>(0i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:146:13 + | +LL | const { read_as::>(0u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#2}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:146:5 + | +LL | const { read_as::>(0u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:146:5 + | +LL | const { read_as::>(0u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:148:13 + | +LL | const { read_as::>(0i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#3}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:148:5 + | +LL | const { read_as::>(0i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:148:5 + | +LL | const { read_as::>(0i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:150:13 + | +LL | const { read_as::>(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#4}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:150:5 + | +LL | const { read_as::>(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:150:5 + | +LL | const { read_as::>(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:152:13 + | +LL | const { read_as::>(0isize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#5}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:152:5 + | +LL | const { read_as::>(0isize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:152:5 + | +LL | const { read_as::>(0isize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:154:13 + | +LL | const { read_as::>(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#6}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:154:5 + | +LL | const { read_as::>(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:154:5 + | +LL | const { read_as::>(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:156:13 + | +LL | const { read_as::>(0isize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#7}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:156:5 + | +LL | const { read_as::>(0isize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:156:5 + | +LL | const { read_as::>(0isize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:158:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#8}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:158:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:158:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:160:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#9}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:160:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:160:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:162:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#10}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:162:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:162:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:164:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#11}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:164:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:164:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:166:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#12}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:166:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:166:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:168:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#13}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:168:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:168:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:170:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#14}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:170:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:170:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: constructing invalid value of type NonZero: at .0.0, encountered 0, but expected something greater or equal to 1 + --> $DIR/c-variadic-fail.rs:172:13 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_zero::{constant#15}` failed inside this call + | +note: inside `read_as::>` + --> $DIR/c-variadic-fail.rs:39:5 + | +LL | ap.next_arg::() + | ^^^^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::next_arg::>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:172:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:172:5 + | +LL | const { read_as::>(None::>) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0080]: va_arg type mismatch: requested `*const fn(&())` is incompatible with next argument of type `*const for<'a> fn(&'a ())` - --> $DIR/c-variadic-fail.rs:126:13 + --> $DIR/c-variadic-fail.rs:191:13 | -LL | const { read_as::<*const fn(&'static ())>(std::ptr::dangling:: fn(&'a ())>()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_lifetime::{constant#1}` failed inside this call +LL | const { read_as::<*const fn(&'static ())>(ptr::dangling:: fn(&'a ())>()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast_lifetime::{constant#1}` failed inside this call | note: inside `read_as::<*const fn(&())>` - --> $DIR/c-variadic-fail.rs:36:5 + --> $DIR/c-variadic-fail.rs:39:5 | LL | ap.next_arg::() | ^^^^^^^^^^^^^^^^^^ @@ -405,46 +965,51 @@ note: inside `VaList::<'_>::next_arg::<*const fn(&())>` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:126:5 + --> $DIR/c-variadic-fail.rs:191:5 | -LL | const { read_as::<*const fn(&'static ())>(std::ptr::dangling:: fn(&'a ())>()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const { read_as::<*const fn(&'static ())>(ptr::dangling:: fn(&'a ())>()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:126:5 + --> $DIR/c-variadic-fail.rs:191:5 | -LL | const { read_as::<*const fn(&'static ())>(std::ptr::dangling:: fn(&'a ())>()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const { read_as::<*const fn(&'static ())>(ptr::dangling:: fn(&'a ())>()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0080]: memory access failed: ALLOC$ID has been freed, so this pointer is dangling - --> $DIR/c-variadic-fail.rs:139:13 +error[E0080]: constructing invalid value of type [u8; 24]: at [8], encountered a pointer, but expected an integer + --> $DIR/c-variadic-fail.rs:202:22 | -LL | ap.next_arg::(); - | ^^^^^^^^^^^^^^^^^^^^ evaluation of `use_after_free::{constant#0}` failed inside this call +LL | let ap = helper(1, 2, 3); + | ^^^^^^^^^^^^^^^ evaluation of `use_after_free::{constant#0}` failed inside this call | -note: inside `VaList::<'_>::next_arg::` - --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + = help: this code performed an operation that depends on the underlying bytes representing a pointer + = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported +note: inside `use_after_free::helper` + --> $DIR/c-variadic-fail.rs:197:18 + | +LL | unsafe { mem::transmute(ap) } + | ^^^^^^^^^^^^^^^^^^ the failure occurred here note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:135:5 + --> $DIR/c-variadic-fail.rs:200:5 | LL | / const { LL | | unsafe { LL | | let ap = helper(1, 2, 3); -LL | | let mut ap = std::mem::transmute::<_, VaList>(ap); +LL | | let mut ap = mem::transmute::<_, VaList>(ap); ... | LL | | }; | |_____^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:135:5 + --> $DIR/c-variadic-fail.rs:200:5 | LL | / const { LL | | unsafe { LL | | let ap = helper(1, 2, 3); -LL | | let mut ap = std::mem::transmute::<_, VaList>(ap); +LL | | let mut ap = mem::transmute::<_, VaList>(ap); ... | LL | | }; | |_____^ @@ -452,13 +1017,13 @@ LL | | }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: using ALLOC$ID as variable argument list pointer but it does not point to a variable argument list - --> $DIR/c-variadic-fail.rs:161:22 + --> $DIR/c-variadic-fail.rs:226:22 | LL | const { unsafe { helper(1, 2, 3) } }; | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_drop::{constant#0}` failed inside this call | note: inside `manual_copy_drop::helper` - --> $DIR/c-variadic-fail.rs:158:9 + --> $DIR/c-variadic-fail.rs:223:9 | LL | drop(ap); | ^^^^^^^^ @@ -470,13 +1035,13 @@ note: inside ` as Drop>::drop` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:161:5 + --> $DIR/c-variadic-fail.rs:226:5 | LL | const { unsafe { helper(1, 2, 3) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:161:5 + --> $DIR/c-variadic-fail.rs:226:5 | LL | const { unsafe { helper(1, 2, 3) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -484,13 +1049,13 @@ LL | const { unsafe { helper(1, 2, 3) } }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: using ALLOC$ID as variable argument list pointer but it does not point to a variable argument list - --> $DIR/c-variadic-fail.rs:177:22 + --> $DIR/c-variadic-fail.rs:242:22 | LL | const { unsafe { helper(1, 2, 3) } }; | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_forget::{constant#0}` failed inside this call | note: inside `manual_copy_forget::helper` - --> $DIR/c-variadic-fail.rs:174:9 + --> $DIR/c-variadic-fail.rs:239:9 | LL | drop(ap); | ^^^^^^^^ @@ -502,13 +1067,13 @@ note: inside ` as Drop>::drop` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:177:5 + --> $DIR/c-variadic-fail.rs:242:5 | LL | const { unsafe { helper(1, 2, 3) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:177:5 + --> $DIR/c-variadic-fail.rs:242:5 | LL | const { unsafe { helper(1, 2, 3) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -516,13 +1081,13 @@ LL | const { unsafe { helper(1, 2, 3) } }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: using ALLOC$ID as variable argument list pointer but it does not point to a variable argument list - --> $DIR/c-variadic-fail.rs:190:22 + --> $DIR/c-variadic-fail.rs:255:22 | LL | const { unsafe { helper(1, 2, 3) } }; | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_read::{constant#0}` failed inside this call | note: inside `manual_copy_read::helper` - --> $DIR/c-variadic-fail.rs:187:17 + --> $DIR/c-variadic-fail.rs:252:17 | LL | let _ = ap.next_arg::(); | ^^^^^^^^^^^^^^^^^^^^ @@ -530,13 +1095,13 @@ note: inside `VaList::<'_>::next_arg::` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:190:5 + --> $DIR/c-variadic-fail.rs:255:5 | LL | const { unsafe { helper(1, 2, 3) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:190:5 + --> $DIR/c-variadic-fail.rs:255:5 | LL | const { unsafe { helper(1, 2, 3) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -544,7 +1109,7 @@ LL | const { unsafe { helper(1, 2, 3) } }; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got null pointer - --> $DIR/c-variadic-fail.rs:198:5 + --> $DIR/c-variadic-fail.rs:263:5 | LL | } | ^ evaluation of `drop_of_invalid::{constant#0}` failed inside this call @@ -555,7 +1120,7 @@ note: inside ` as Drop>::drop` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:195:5 + --> $DIR/c-variadic-fail.rs:260:5 | LL | / const { LL | | let mut invalid: MaybeUninit = MaybeUninit::zeroed(); @@ -564,7 +1129,7 @@ LL | | } | |_____^ note: erroneous constant encountered - --> $DIR/c-variadic-fail.rs:195:5 + --> $DIR/c-variadic-fail.rs:260:5 | LL | / const { LL | | let mut invalid: MaybeUninit = MaybeUninit::zeroed(); @@ -574,6 +1139,6 @@ LL | | } | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 20 previous errors +error: aborting due to 40 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/c-variadic.rs b/tests/ui/consts/const-eval/c-variadic.rs index 6dba6e1af5997..2a74a87e80d9f 100644 --- a/tests/ui/consts/const-eval/c-variadic.rs +++ b/tests/ui/consts/const-eval/c-variadic.rs @@ -7,6 +7,8 @@ #![feature(const_cmp)] #![feature(const_trait_impl)] +use std::num::NonZero; +use std::ptr::NonNull; use std::ffi::*; fn ignores_arguments() { @@ -118,6 +120,12 @@ fn various_types() { continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), "Hello")); continue_if!(ap.next_arg::() == 42); continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), "World")); + continue_if!(*ap.next_arg::<&u32>() == 1); + continue_if!(*ap.next_arg::<&mut u32>() == 27); + continue_if!(*ap.next_arg::>().as_ptr() == 9); + continue_if!(ap.next_arg::>>().is_none()); + continue_if!(ap.next_arg::>() == NonZero::new(43u32).unwrap()); + continue_if!(ap.next_arg::>>().is_none()); } unsafe { @@ -129,6 +137,12 @@ fn various_types() { c"Hello".as_ptr(), 42 as c_int, c"World".as_ptr(), + &1u32, + &mut 27u32, + NonNull::new(&mut 9u32).unwrap(), + None::>, + NonZero::new(43u32).unwrap(), + None::>, ); const { check_list_2( @@ -139,6 +153,12 @@ fn various_types() { c"Hello".as_ptr(), 42 as c_int, c"World".as_ptr(), + &1u32, + &mut 27u32, + NonNull::new(&mut 9u32).unwrap(), + None::>, + NonZero::new(43u32).unwrap(), + None::>, ) }; } From 353c68150d0256f1a87da6bd8d20bbc73e091a64 Mon Sep 17 00:00:00 2001 From: ltdk Date: Thu, 1 Oct 2026 11:21:35 -0400 Subject: [PATCH 2/2] Testing stuff --- tests/ui/c-variadic/roundtrip.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/ui/c-variadic/roundtrip.rs b/tests/ui/c-variadic/roundtrip.rs index 79c772b35ce47..dd90713b05ea2 100644 --- a/tests/ui/c-variadic/roundtrip.rs +++ b/tests/ui/c-variadic/roundtrip.rs @@ -30,12 +30,26 @@ const unsafe extern "C" fn variadic(mut ap: ...) -> (T, T) { // Intersperse a small type to test alignment logic. A `u32` (i.e. `c_uint`) is the smallest // type that implements `VaArgSafe` (except on some 16-bit targets): smaller types would // automatically be promoted. - assert!(ap.next_arg::() == 0xAAAA_AAAA); + assert!(ap.next_arg::() == 0xAAAA_AAAAu32); let y = ap.next_arg::(); (x, y) } +// note: this is only to get better error messages for `assert_eq!` +#[allow(improper_ctypes_definitions)] +unsafe extern "C" fn non_const_variadic(mut ap: ...) -> (T, T) { + let x = ap.next_arg::(); + // Intersperse a small type to test alignment logic. A `u32` (i.e. `c_uint`) is the smallest + // type that implements `VaArgSafe` (except on some 16-bit targets): smaller types would + // automatically be promoted. + let a = ap.next_arg::(); + let y = ap.next_arg::(); + assert_eq!(a, 0xAAAA_AAAAu32, "{:?} {:?} {:?}", x, a, y); + + (x, y) +} + macro_rules! roundtrip { ($ty:ty, $a:expr, $b:expr) => { const { @@ -48,7 +62,7 @@ macro_rules! roundtrip { let a: $ty = $a; let b: $ty = $b; - assert_eq!(variadic::<$ty>(a, 0xAAAA_AAAAu32, b), (a, b)) + assert_eq!(non_const_variadic::<$ty>(a, 0xAAAA_AAAAu32, b), (a, b)) }; }