{"id":"733063913c2e6907","repo":"rust-lang/rust","slug":"aggregates-can-t-have-fieldsshape-primitive","errorCode":null,"errorMessage":"aggregates can't have `FieldsShape::Primitive`","messagePattern":"aggregates can't have `FieldsShape::Primitive`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_abi/src/callconv.rs","lineNumber":101,"sourceCode":"                    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)?\n                                } else {\n                                    HomogeneousAggregate::NoData\n                                };\n                                return Ok((result, layout.size));\n                            }\n                            FieldsShape::Union(_) => true,\n                            FieldsShape::Arbitrary { .. } => false,\n                        };\n\n                        let mut result = HomogeneousAggregate::NoData;\n                        let mut total = start;\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_abi/src/callconv.rs#L83-L119","documentation":"While computing whether a memory-sized or scalar-pair aggregate is homogeneous, the walker matches on `layout.fields`. `FieldsShape::Primitive` is reserved for types whose layout is a bare primitive (scalars) and which therefore never enter the aggregate-walking branch — by the time the code reaches this match the type is `ScalarPair` or `Memory { sized: true }`, which must have Array/Union/Arbitrary fields. Seeing `Primitive` here means the layout was built inconsistently.","triggerScenarios":"`homogeneous_aggregate` reaching `from_fields_at` for a `BackendRepr::ScalarPair` or `BackendRepr::Memory { sized: true }` type whose `fields` shape is `FieldsShape::Primitive` — a state that should be impossible given how `LayoutData` is constructed.","commonSituations":"An internal layout-computation bug that produced a `Memory`/`ScalarPair` `BackendRepr` together with a `FieldsShape::Primitive`, a hand-constructed `LayoutData` in a codegen backend or test harness that mixes the two, or a refactor that stopped upgrading a primitive-shaped type to a real aggregate shape.","solutions":["Find where the `LayoutData` was assembled (search for `FieldsShape::Primitive` producers) and ensure scalar types keep `Scalar` repr while real aggregates get `Array`/`Union`/`Arbitrary`.","Run `rustc` with `-Zprint-layout` / `RUSTC_LOG` to dump the offending type's layout before the panic.","If you maintain a custom `TyAbiInterface` impl, validate that `fields` is consistent with `backend_repr` before returning a layout.","File an ICE with the type definition that triggers it."],"exampleFix":"// before\nLayoutData {\n    backend_repr: BackendRepr::Memory { sized: true },\n    fields: FieldsShape::Primitive, // inconsistent — panics in homogeneous_aggregate\n    ..\n}\n\n// after\nLayoutData {\n    backend_repr: BackendRepr::Memory { sized: true },\n    fields: FieldsShape::Arbitrary { offsets, in_memory_order },\n    ..\n}","handlingStrategy":"validation","validationCode":"// homogeneous_aggregate unreachable!() when an aggregate's FieldsShape is Primitive.\nuse rustc_abi::{FieldsShape, LayoutData};\nfn aggregate_has_real_fields<F, V>(layout: &LayoutData<F, V>) -> bool {\n    !matches!(layout.fields, FieldsShape::Primitive)\n}\n// caller: assert/branch on aggregate_has_real_fields before computing field offsets\n// for a memory/union/array/scalar-pair layout.","typeGuard":"fn is_fielded_aggregate<F, V>(layout: &LayoutData<F, V>) -> bool {\n    matches!(\n        layout.fields,\n        FieldsShape::Union(_) | FieldsShape::Array { .. } | FieldsShape::Arbitrary { .. }\n    )\n}","tryCatchPattern":"let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    /* the field-walking homogeneous_aggregate inner closure */\n}));\nif result.is_err() {\n    // A Primitive FieldsShape was handed to aggregate logic; recover by treating\n    // the value as a single opaque scalar instead of recursing into 'fields'.\n}","preventionTips":["FieldsShape::Primitive means the type has no addressable fields; never feed such a layout into a field-walking algorithm.","Before calling layout.field(cx, i) in a loop, gate on the FieldsShape variant — Primitive layouts have no field index space.","If you synthesize LayoutData yourself (e.g. for a foreign type), never pair BackendRepr::Memory-sized with FieldsShape::Primitive; that combination is contradictory and will trip this panic in any consumer."],"tags":["rustc","abi","layout","aggregate","ice"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}