{"id":"5a3a1b1a2ede1b4d","repo":"rust-lang/rust","slug":"fieldsshape-offset-primitive-s-have-no-fields","errorCode":null,"errorMessage":"FieldsShape::offset: `Primitive`s have no fields","messagePattern":"FieldsShape::offset: `Primitive`s have no fields","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_abi/src/lib.rs","lineNumber":1694,"sourceCode":"    },\n}\n\nimpl<FieldIdx: Idx> FieldsShape<FieldIdx> {\n    #[inline]\n    pub fn count(&self) -> usize {\n        match *self {\n            FieldsShape::Primitive => 0,\n            FieldsShape::Union(count) => count.get(),\n            FieldsShape::Array { count, .. } => count.try_into().unwrap(),\n            FieldsShape::Arbitrary { ref offsets, .. } => offsets.len(),\n        }\n    }\n\n    #[inline]\n    pub fn offset(&self, i: usize) -> Size {\n        match *self {\n            FieldsShape::Primitive => {\n                unreachable!(\"FieldsShape::offset: `Primitive`s have no fields\")\n            }\n            FieldsShape::Union(count) => {\n                assert!(i < count.get(), \"tried to access field {i} of union with {count} fields\");\n                Size::ZERO\n            }\n            FieldsShape::Array { stride, count } => {\n                let i = u64::try_from(i).unwrap();\n                assert!(i < count, \"tried to access field {i} of array with {count} fields\");\n                stride * i\n            }\n            FieldsShape::Arbitrary { ref offsets, .. } => offsets[FieldIdx::new(i)],\n        }\n    }\n\n    /// Gets source indices of the fields by increasing offsets.\n    #[inline]\n    pub fn index_by_increasing_offset(&self) -> impl ExactSizeIterator<Item = usize> {\n        // Primitives don't really have fields in the way that structs do,","sourceCodeStart":1676,"sourceCodeEnd":1712,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_abi/src/lib.rs#L1676-L1712","documentation":"Marked `unreachable!` at compiler/rustc_abi/src/lib.rs:1694 inside `FieldsShape::offset`. `FieldsShape::Primitive` represents scalar types and `!`, which by definition have no fields; asking for the offset of field `i` is therefore a logic error in the caller. The other variants (`Union`, `Array`, `Arbitrary`) all yield a real offset.","triggerScenarios":"Calling `fields.offset(i)` (or any consumer that iterates fields) on a layout whose `FieldsShape` is `Primitive` — i.e. a scalar or `!`-typed value. Reached when field-iteration code does not first check `matches!(fields, FieldsShape::Primitive)` or `fields.count() == 0`.","commonSituations":"Codegen or debug-info passes that walk fields uniformly across all types without short-circuiting scalars; rust-analyzer or other tools replaying layouts; or generic field-walking helpers shared between struct and scalar layouts.","solutions":["Short-circuit on `FieldsShape::Primitive` before iterating fields: `if matches!(fields, FieldsShape::Primitive) { return; }`.","Use `fields.count()` (which returns 0 for `Primitive`) to guard the loop so no offset is ever requested.","If you genuinely expected a fielded layout here, the upstream layout computation is wrong — the type should not have been assigned `Primitive`; investigate why `compute().backend_repr` classified it as scalar."],"exampleFix":"// before\nfor i in 0..fields.count() {\n    let off = fields.offset(i);\n    ...\n}\n\n// after\nif matches!(fields, FieldsShape::Primitive) {\n    return; // scalars and ! have no fields\n}\nfor i in 0..fields.count() {\n    let off = fields.offset(i);\n    ...\n}","handlingStrategy":"type-guard","validationCode":"// FieldsShape::offset panics for Primitive variants. Branch on the variant first.\nfn field_offset(shape: &rustc_abi::FieldsShape, i: usize) -> Option<rustc_abi::Size> {\n    match shape {\n        rustc_abi::FieldsShape::Primitive => None,\n        rustc_abi::FieldsShape::Union(_) => Some(rustc_abi::Size::ZERO),\n        rustc_abi::FieldsShape::Array { stride, count } => {\n            let i = u64::try_from(i).ok()?;\n            (i < *count).then(|| *stride * i)\n        }\n        rustc_abi::FieldsShape::Arbitrary { offsets, .. } => Some(offsets[rustc_field_idx(i)]),\n    }\n}","typeGuard":"fn has_fields(shape: &rustc_abi::FieldsShape) -> bool {\n    !matches!(shape, rustc_abi::FieldsShape::Primitive)\n}","tryCatchPattern":"// unreachable! by design; do not catch. Treat reaching offset() on Primitive as\n// a caller bug to be fixed by the type guard above.","preventionTips":["Primitives have no fields; never index into them. Track whether a layout is Primitive separately from Struct/Array/Union.","If you hold a FieldsShape of unknown variant, always match exhaustively rather than assuming Arbitrary/Array.","Add a debug_assert!(matches!(shape, Primitive => false, _ => true)) at the entry of any field-iteration helper."],"tags":["rustc-abi","fieldsshape","unreachable","layout","scalar"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}