{"id":"8b8bfbd9a73004e8","repo":"rust-lang/rust","slug":"homogeneous-aggregate-should-not-be-called-for-s","errorCode":null,"errorMessage":"`homogeneous_aggregate` should not be called for scalable vectors","messagePattern":"`homogeneous_aggregate` should not be called for scalable vectors","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_abi/src/callconv.rs","lineNumber":89,"sourceCode":"            BackendRepr::Scalar(scalar) => {\n                let kind = match scalar.primitive() {\n                    Primitive::Int(..) | Primitive::Pointer(_) => RegKind::Integer,\n                    Primitive::Float(_) => RegKind::Float,\n                };\n                Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }))\n            }\n\n            BackendRepr::SimdVector { element, count: _ } => {\n                assert!(!self.is_zst());\n\n                Ok(HomogeneousAggregate::Homogeneous(Reg {\n                    kind: RegKind::Vector { hint_vector_elem: element.primitive() },\n                    size: self.size,\n                }))\n            }\n\n            BackendRepr::SimdScalableVector { .. } => {\n                unreachable!(\"`homogeneous_aggregate` should not be called for scalable vectors\")\n            }\n\n            BackendRepr::ScalarPair { .. } | BackendRepr::Memory { sized: true } => {\n                // Helper for computing `homogeneous_aggregate`, allowing a custom\n                // starting offset (used below for handling variants).\n                let from_fields_at =\n                    |layout: Self,\n                     start: Size|\n                     -> Result<(HomogeneousAggregate, Size), Heterogeneous> {\n                        let is_union = match layout.fields {\n                            FieldsShape::Primitive => {\n                                unreachable!(\"aggregates can't have `FieldsShape::Primitive`\")\n                            }\n                            FieldsShape::Array { count, .. } => {\n                                assert_eq!(start, Size::ZERO);\n\n                                let result = if count > 0 {\n                                    layout.field(cx, 0).homogeneous_aggregate(cx)?","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_abi/src/callconv.rs#L71-L107","documentation":"`homogeneous_aggregate` walks an aggregate's leaf fields to detect a single uniform pass-by-register unit, an ABI optimization for things like `(f32, f32, f32)`. Scalable (VL) SIMD vectors (`BackendRepr::SimdScalableVector`) have a runtime-unknown element count, so the question 'are all leaves the same register' is meaningless for them. This `unreachable!` enforces that no calling-convention code path ever asks it.","triggerScenarios":"Calling `TyAndLayout::homogeneous_aggregate(cx)` on a type whose `backend_repr` is `BackendRepr::SimdScalableVector { .. }` — e.g. a Rust scalable-vector type such as `#[repr(simd)]` scalable elements used as a function argument under an ABI that consults homogeneity (AArch64 SVE PCS).","commonSituations":"A calling-convention or codegen change that routes scalable-vector arguments through the generic homogeneous-aggregate path instead of the dedicated vector handling, or a new scalable-vector primitive leaking into a struct/aggregate field that the homogeneity walker then recurses into.","solutions":["Guard the caller so scalable-vector arguments skip `homogeneous_aggregate` and are handled by the target's dedicated SVE/RVV PCS path.","Check the `BackendRepr` before invoking: `if matches!(layout.backend_repr, BackendRepr::SimdScalableVector { .. }) { return dedicated handling }`.","Audit the target-specific callconv to ensure scalable vectors never appear as fields of an aggregate passed to this function.","Add a regression test with a scalable-vector type to lock in the early-return."],"exampleFix":"// before\nlet homo = layout.homogeneous_aggregate(cx)?; // panics for scalable vectors\n\n// after\nif matches!(layout.backend_repr, BackendRepr::SimdScalableVector { .. }) {\n    return Err(Heterogeneous);\n}\nlet homo = layout.homogeneous_aggregate(cx)?;","handlingStrategy":"validation","validationCode":"// homogeneous_aggregate unreachable!() on BackendRepr::SimdScalableVector.\n// Check the layout's backend repr before recursing into it.\nuse rustc_abi::{BackendRepr, LayoutData};\nfn homogeneous_eligible<F, V>(layout: &LayoutData<F, V>) -> bool {\n    !matches!(layout.backend_repr, BackendRepr::SimdScalableVector { .. })\n}\n// caller:\n// if homogeneous_eligible(&ty_layout) { ty_layout.homogeneous_aggregate(cx)? } else { return Err(Heterogeneous); }","typeGuard":"fn is_fixed_simd_or_scalar<F, V>(layout: &LayoutData<F, V>) -> bool {\n    matches!(\n        layout.backend_repr,\n        BackendRepr::Scalar(_) | BackendRepr::ScalarPair { .. } | BackendRepr::Memory { .. }\n    ) || matches!(layout.backend_repr, BackendRepr::SimdVector { .. })\n}","tryCatchPattern":"let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    layout.homogeneous_aggregate(cx)\n}));\nmatch result {\n    Ok(Ok(ha)) => { /* use homogeneous aggregate */ }\n    Ok(Err(_))  => { /* legitimately heterogeneous */ }\n    Err(_)      => { /* scalable vector slipped through; treat as heterogeneous */ }\n}","preventionTips":["Scalable vectors (SVE/RVV) are not homogeneous-aggregate-eligible by construction; short-circuit them before the recursion.","When walking aggregate fields, propagate a 'may contain scalable vector' flag from the type system down to the homogeneous check so you never call it on a layout that could be SimdScalableVector.","Treat SimdScalableVector as its own calling-convention category; do not route it through code paths designed for fixed SIMD."],"tags":["rustc","abi","simd","scalable-vector","ice"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}