diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 41ad14f550ab..aafb124986e1 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -290,7 +290,19 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// function call isn't allowed (a.k.a. `va_list`). /// /// This function handles transparent types automatically. - pub fn pass_indirectly_in_non_rustic_abis(mut self, cx: &C) -> bool + pub fn pass_indirectly_in_non_rustic_abis(self, cx: &C) -> bool + where + Ty: TyAbiInterface<'a, C> + Copy, + { + let base = self.peel_transparent_wrappers(cx); + Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(base) + } + + /// Recursively peel away transparent wrappers, returning the inner value. + /// + /// The return value is not `repr(transparent)` and/or does + /// not have a non-1zst field. + pub fn peel_transparent_wrappers(mut self, cx: &C) -> Self where Ty: TyAbiInterface<'a, C> + Copy, { @@ -300,7 +312,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { self = field; } - Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(self) + self } /// Finds the one field that is not a 1-ZST. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 6b8c2e4d0610..58c296d92c24 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -160,7 +160,7 @@ fn is_valid_cmse_output<'tcx>( } /// Returns whether the output will fit into the available registers -fn is_valid_cmse_output_layout<'tcx>(cx: LayoutCx<'tcx>, mut layout: TyAndLayout<'tcx>) -> bool { +fn is_valid_cmse_output_layout<'tcx>(cx: LayoutCx<'tcx>, layout: TyAndLayout<'tcx>) -> bool { let size = layout.layout.size().bytes(); if size <= 4 { @@ -169,21 +169,9 @@ fn is_valid_cmse_output_layout<'tcx>(cx: LayoutCx<'tcx>, mut layout: TyAndLayout return false; } - // Find the wrapped inner type of a transparent wrapper. - loop { - match layout.ty.kind() { - ty::Adt(adt_def, _) if adt_def.repr().transparent() => { - // Find the non-1-ZST field, and recurse. - (_, layout) = layout.non_1zst_field(&cx).unwrap(); - } - // Not a transparent type, no further unfolding. - _ => break, - } - } - // Accept (transparently wrapped) scalar 64-bit primitives. matches!( - layout.ty.kind(), + layout.peel_transparent_wrappers(&cx).ty.kind(), ty::Int(ty::IntTy::I64) | ty::Uint(ty::UintTy::U64) | ty::Float(ty::FloatTy::F64) ) }