diff options
Diffstat (limited to 'compiler/rustc_ty_utils')
| -rw-r--r-- | compiler/rustc_ty_utils/src/abi.rs | 102 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/assoc.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/consts.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/layout.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/layout/invariant.rs (renamed from compiler/rustc_ty_utils/src/layout_sanity_check.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/lib.rs | 1 |
6 files changed, 22 insertions, 103 deletions
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 7354ea5fb6a..48149a08de8 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -1,8 +1,7 @@ use std::iter; -use rustc_abi::Float::*; -use rustc_abi::Primitive::{Float, Pointer}; -use rustc_abi::{Abi, AddressSpace, PointerKind, Scalar, Size}; +use rustc_abi::Primitive::Pointer; +use rustc_abi::{Abi, PointerKind, Scalar, Size}; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_middle::bug; @@ -14,8 +13,7 @@ use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::def_id::DefId; use rustc_target::abi::call::{ - ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind, - RiscvInterruptKind, + ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, RiscvInterruptKind, }; use rustc_target::spec::abi::Abi as SpecAbi; use tracing::debug; @@ -679,6 +677,8 @@ fn fn_abi_adjust_for_abi<'tcx>( let tcx = cx.tcx(); if abi == SpecAbi::Rust || abi == SpecAbi::RustCall || abi == SpecAbi::RustIntrinsic { + fn_abi.adjust_for_rust_abi(cx, abi); + // Look up the deduced parameter attributes for this function, if we have its def ID and // we're optimizing in non-incremental mode. We'll tag its parameters with those attributes // as appropriate. @@ -689,88 +689,9 @@ fn fn_abi_adjust_for_abi<'tcx>( &[] }; - let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>, arg_idx: Option<usize>| { + for (arg_idx, arg) in fn_abi.args.iter_mut().enumerate() { if arg.is_ignore() { - return; - } - - // Avoid returning floats in x87 registers on x86 as loading and storing from x87 - // registers will quiet signalling NaNs. - if tcx.sess.target.arch == "x86" - && arg_idx.is_none() - // Intrinsics themselves are not actual "real" functions, so theres no need to - // change their ABIs. - && abi != SpecAbi::RustIntrinsic - { - match arg.layout.abi { - // Handle similar to the way arguments with an `Abi::Aggregate` abi are handled - // below, by returning arguments up to the size of a pointer (32 bits on x86) - // cast to an appropriately sized integer. - Abi::Scalar(s) if s.primitive() == Float(F32) => { - // Same size as a pointer, return in a register. - arg.cast_to(Reg::i32()); - return; - } - Abi::Scalar(s) if s.primitive() == Float(F64) => { - // Larger than a pointer, return indirectly. - arg.make_indirect(); - return; - } - Abi::ScalarPair(s1, s2) - if matches!(s1.primitive(), Float(F32 | F64)) - || matches!(s2.primitive(), Float(F32 | F64)) => - { - // Larger than a pointer, return indirectly. - arg.make_indirect(); - return; - } - _ => {} - }; - } - - match arg.layout.abi { - Abi::Aggregate { .. } => {} - - // This is a fun case! The gist of what this is doing is - // that we want callers and callees to always agree on the - // ABI of how they pass SIMD arguments. If we were to *not* - // make these arguments indirect then they'd be immediates - // in LLVM, which means that they'd used whatever the - // appropriate ABI is for the callee and the caller. That - // means, for example, if the caller doesn't have AVX - // enabled but the callee does, then passing an AVX argument - // across this boundary would cause corrupt data to show up. - // - // This problem is fixed by unconditionally passing SIMD - // arguments through memory between callers and callees - // which should get them all to agree on ABI regardless of - // target feature sets. Some more information about this - // issue can be found in #44367. - // - // Note that the intrinsic ABI is exempt here as - // that's how we connect up to LLVM and it's unstable - // anyway, we control all calls to it in libstd. - Abi::Vector { .. } - if abi != SpecAbi::RustIntrinsic && tcx.sess.target.simd_types_indirect => - { - arg.make_indirect(); - return; - } - - _ => return, - } - // Compute `Aggregate` ABI. - - let is_indirect_not_on_stack = - matches!(arg.mode, PassMode::Indirect { on_stack: false, .. }); - assert!(is_indirect_not_on_stack, "{:?}", arg); - - let size = arg.layout.size; - if !arg.layout.is_unsized() && size <= Pointer(AddressSpace::DATA).size(cx) { - // We want to pass small aggregates as immediates, but using - // an LLVM aggregate type for this leads to bad optimizations, - // so we pick an appropriately sized integer type instead. - arg.cast_to(Reg { kind: RegKind::Integer, size }); + continue; } // If we deduced that this parameter was read-only, add that to the attribute list now. @@ -778,9 +699,7 @@ fn fn_abi_adjust_for_abi<'tcx>( // The `readonly` parameter only applies to pointers, so we can only do this if the // argument was passed indirectly. (If the argument is passed directly, it's an SSA // value, so it's implicitly immutable.) - if let (Some(arg_idx), &mut PassMode::Indirect { ref mut attrs, .. }) = - (arg_idx, &mut arg.mode) - { + if let &mut PassMode::Indirect { ref mut attrs, .. } = &mut arg.mode { // The `deduced_param_attrs` list could be empty if this is a type of function // we can't deduce any parameters for, so make sure the argument index is in // bounds. @@ -791,11 +710,6 @@ fn fn_abi_adjust_for_abi<'tcx>( } } } - }; - - fixup(&mut fn_abi.ret, None); - for (arg_idx, arg) in fn_abi.args.iter_mut().enumerate() { - fixup(arg, Some(arg_idx)); } } else { fn_abi diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index a057caa9329..a3210dd80d7 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -181,7 +181,7 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> { // don't synthesize the associated type even if the user has written `const_trait` // if the effects feature is disabled. - if !tcx.features().effects { + if !tcx.features().effects() { return None; } let (feed, parent_did) = match tcx.def_kind(def_id) { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 391985ce88a..4b770d9938c 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -406,7 +406,7 @@ fn thir_abstract_const<'tcx>( tcx: TyCtxt<'tcx>, def: LocalDefId, ) -> Result<Option<ty::EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed> { - if !tcx.features().generic_const_exprs { + if !tcx.features().generic_const_exprs() { return Ok(None); } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index afdfa2e80c1..e755e90aa65 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -30,7 +30,8 @@ use {rustc_abi as abi, rustc_hir as hir}; use crate::errors::{ MultipleArrayFieldsSimdType, NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType, }; -use crate::layout_sanity_check::sanity_check_layout; + +mod invariant; pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { layout_of, ..*providers }; @@ -79,7 +80,7 @@ fn layout_of<'tcx>( record_layout_for_printing(&cx, layout); } - sanity_check_layout(&cx, &layout); + invariant::partially_check_layout(&cx, &layout); Ok(layout) } @@ -115,6 +116,11 @@ fn map_error<'tcx>( cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}")); LayoutError::Unknown(ty) } + LayoutCalculatorError::ReprConflict => { + // packed enums are the only known trigger of this, but others might arise + cx.tcx().dcx().delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}")); + LayoutError::Unknown(ty) + } }; error(cx, err) } @@ -170,12 +176,12 @@ fn layout_of_uncached<'tcx>( if let Abi::Scalar(scalar) | Abi::ScalarPair(scalar, _) = &mut layout.abi { if let Some(start) = start { scalar.valid_range_mut().start = start - .try_eval_bits(tcx, param_env) + .try_to_bits(tcx, param_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; } if let Some(end) = end { let mut end = end - .try_eval_bits(tcx, param_env) + .try_to_bits(tcx, param_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; if !include_end { end = end.wrapping_sub(1); @@ -315,7 +321,7 @@ fn layout_of_uncached<'tcx>( } let count = count - .try_eval_target_usize(tcx, param_env) + .try_to_target_usize(tcx) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; let element = cx.layout_of(element)?; let size = element diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index be0a7c5ee89..6cf114b74c1 100644 --- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -5,7 +5,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, TyAndLayout}; use rustc_target::abi::*; /// Enforce some basic invariants on layouts. -pub(super) fn sanity_check_layout<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) { +pub(super) fn partially_check_layout<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) { let tcx = cx.tcx(); // Type-level uninhabitedness should always imply ABI uninhabitedness. diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index dc5303317a8..8be1611bb9a 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -29,7 +29,6 @@ mod errors; mod implied_bounds; mod instance; mod layout; -mod layout_sanity_check; mod needs_drop; mod opaque_types; mod representability; |
