range-diff of 2bd7a97..edca82f e8e4541..a875e14 in rust-lang/rust

Legend: -  before | +  after
compiler/rustc_codegen_llvm/src/intrinsic.rs before after
 -  @@ compiler/rustc_codegen_llvm/src/intrinsic.rs: use rustc_session::config::CrateType;
 -   use rustc_span::{Span, Symbol, sym};
 -   use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
 -   use rustc_target::callconv::PassMode;
 -  -use rustc_target::spec::Os;
 -  +use rustc_target::spec::{Arch, Os};
 -   use tracing::debug;
 -   
 -   use crate::abi::FnAbiLlvmExt;
    @@ compiler/rustc_codegen_llvm/src/intrinsic.rs: impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 }
                 sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[], &[]),
    +                        emit_va_arg(self, args[0], result.layout.ty)
    +                    }
    +                    Primitive::Int(..) => {
 -  +                        // `va_arg` should not be called on an integer type
 -  +                        // less than c_int (typically i32, but i16 on e.g. avr).
 -  +                        assert!({
 -  +                            let int_width = self.cx().size_of(result.layout.ty).bits();
 -  +                            let target_c_int_width = self.cx().sess().target.options.c_int_width;
 -  +
 -  +                            int_width >= u64::from(target_c_int_width)
 -  +                        });
 +  +                        let int_width = self.cx().size_of(result.layout.ty).bits();
 +  +                        let target_c_int_width = self.cx().sess().target.options.c_int_width;
 +  +                        if int_width < u64::from(target_c_int_width) {
 +  +                            // Smaller integer types are automatically promototed and `va_arg`
 +  +                            // should not be called on them.
 +  +                            bug!(
 +  +                                "va_arg got i{} but needs at least c_int (an i{})",
 +  +                                int_width,
 +  +                                target_c_int_width
 +  +                            );
 +                           }
    +                        emit_va_arg(self, args[0], result.layout.ty)
    +                    }
    +                    Primitive::Float(Float::F16) => {
    +                            emit_va_arg(self, args[0], result.layout.ty)
    +                        } else {
    +                            bug!("the va_arg intrinsic does not support `f32` on this target")
 -                           }
 -                       }
 -  -                    _ => bug!("the va_arg intrinsic does not work with non-scalar types"),
 +  +                        }
 +  +                    }
    +                    Primitive::Float(Float::F64) => {
    +                        // 64-bit floats are always OK.
    +                        emit_va_arg(self, args[0], result.layout.ty)
    +                    }
    +                    Primitive::Float(Float::F128) => {
    +                        bug!("the va_arg intrinsic does not support `f128`")
 -  +                    }
 +                       }
 +  -                    _ => bug!("the va_arg intrinsic does not work with non-scalar types"),
                     }
                 }
     
compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs before after
    +                // We use implementations of VaArgSafe as the source of truth. On some embedded
    +                // targets, c_double is f32 and c_int/c_uing are i16/u16, and these types implement
    +                // VaArgSafe there. On all other targets, these types do not implement VaArgSafe.
 +  +                //
 +  +                // cfg(bootstrap): change the if let to an unwrap.
                     let arg_ty = self.structurally_resolve_type(arg.span, arg_ty);
    +                if let Some(trait_def_id) = tcx.lang_items().va_arg_safe()
    +                    && self
library/core/src/ffi/va_list.rs before after
    @@ library/core/src/ffi/va_list.rs: impl<'f> const Drop for VaList<'f> {
     mod sealed {
         pub trait Sealed {}
     
 -  +    crate::cfg_select! {
 -  +        any(target_arch = "avr", target_arch = "msp430") => {
 -  +            impl Sealed for i16 {}
 -  +            impl Sealed for u16 {}
 -  +        }
 -  +        _ => {}
 -  +    }
 -  +
 +  +    impl Sealed for i16 {}
         impl Sealed for i32 {}
         impl Sealed for i64 {}
         impl Sealed for isize {}
 -  @@ library/core/src/ffi/va_list.rs: mod sealed {
 +   
 +  +    impl Sealed for u16 {}
 +       impl Sealed for u32 {}
         impl Sealed for u64 {}
         impl Sealed for usize {}
     
 -  +    // A c_double is f32 on avr.
 -  +    #[cfg(target_arch = "avr")]
    +    impl Sealed for f32 {}
         impl Sealed for f64 {}
     
    +
    +    va_arg_safe_check::<crate::ffi::c_int>();
    +    va_arg_safe_check::<crate::ffi::c_uint>();
 +  +    va_arg_safe_check::<crate::ffi::c_long>();
 +  +    va_arg_safe_check::<crate::ffi::c_ulong>();
 +  +    va_arg_safe_check::<crate::ffi::c_longlong>();
 +  +    va_arg_safe_check::<crate::ffi::c_ulonglong>();
    +    va_arg_safe_check::<crate::ffi::c_double>();
    +};
    +