{"id":"c710bb6f79261d19","repo":"rust-lang/rust","slug":"cannot-create-a-zero-sized-constant-for-type-ty","errorCode":null,"errorMessage":"Cannot create a zero-sized constant for type `{ty_internal}`: {err}","messagePattern":"Cannot create a zero-sized constant for type `(.+?)`: (.+?)","errorType":"exception","errorClass":"B::Error","httpStatus":null,"severity":"error","filePath":"compiler/rustc_public_bridge/src/context/impls.rs","lineNumber":464,"sourceCode":"\n    /// Evaluate constant as a target usize.\n    pub fn eval_target_usize(&self, cnst: MirConst<'tcx>) -> Result<u64, B::Error> {\n        use crate::context::TypingEnvHelpers;\n        cnst.try_eval_target_usize(self.tcx, self.fully_monomorphized())\n            .ok_or_else(|| B::Error::new(format!(\"Const `{cnst:?}` cannot be encoded as u64\")))\n    }\n\n    pub fn eval_target_usize_ty(&self, cnst: ty::Const<'tcx>) -> Result<u64, B::Error> {\n        cnst.try_to_target_usize(self.tcx)\n            .ok_or_else(|| B::Error::new(format!(\"Const `{cnst:?}` cannot be encoded as u64\")))\n    }\n\n    pub fn try_new_const_zst(&self, ty_internal: Ty<'tcx>) -> Result<MirConst<'tcx>, B::Error> {\n        let size = self\n            .tcx\n            .layout_of(self.fully_monomorphized().as_query_input(ty_internal))\n            .map_err(|err| {\n                B::Error::new(format!(\n                    \"Cannot create a zero-sized constant for type `{ty_internal}`: {err}\"\n                ))\n            })?\n            .size;\n        if size.bytes() != 0 {\n            return Err(B::Error::new(format!(\n                \"Cannot create a zero-sized constant for type `{ty_internal}`: \\\n                Type `{ty_internal}` has {} bytes\",\n                size.bytes()\n            )));\n        }\n\n        Ok(MirConst::Ty(ty_internal, self.const_zero_sized(ty_internal)))\n    }\n\n    pub fn const_zero_sized(&self, ty_internal: Ty<'tcx>) -> ty::Const<'tcx> {\n        ty::Const::zero_sized(self.tcx, ty_internal)\n    }","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_public_bridge/src/context/impls.rs#L446-L482","documentation":"Thrown by `try_new_const_zst` in compiler/rustc_public_bridge/src/context/impls.rs:464 when `tcx.layout_of` fails for the given type. Computing a zero-sized constant requires knowing the type's layout, which fails if the type is not fully monomorphized, contains inference variables, or triggers a layout/normalization error. rustc_public fails fast because without a layout it cannot confirm the type is zero-sized.","triggerScenarios":"Calling `context.try_new_const_zst(ty)` on a generic type that still has free parameters, a type whose layout depends on an unresolved associated type, or any type for which `layout_of` errors under the current typing environment.","commonSituations":"Building a unit-like constant for a generic type before monomorphization. Feeding an inference-variable type or a type with errors into const construction. Using a param env that is not fully monomorphized for a layout-sensitive query.","solutions":["Fully monomorphize the type (substitute concrete args) before calling `try_new_const_zst`.","Resolve any inference variables or associated types the type depends on so `layout_of` succeeds.","If you only ever need a ZST value, substitute a concrete zero-sized type such as unit `()` instead of the generic one."],"exampleFix":"// before\nlet c = cx.try_new_const_zst(generic_ty)?;\n// after\nlet concrete = cx.fully_monomorphized().instantiate(generic_ty, args);\nlet c = cx.try_new_const_zst(concrete)?;","handlingStrategy":"validation","validationCode":"// Before MirConst::try_new_zero_sized(ty):\n// try_new_const_zst calls layout_of internally and surfaces its error here.\n// Pre-compute the layout so the failure is observable as a normal Result\n// rather than inside the ZST constructor.\nlet layout = ty.layout()?; // surfaces layout_of errors explicitly\nlet shape = layout.shape();\nif shape.is_unsized() {\n    return Err(format!(\"type {:?} is unsized; no ZST constant\", ty));\n}\nlet zst = MirConst::try_new_zero_sized(ty)?;","typeGuard":null,"tryCatchPattern":"match MirConst::try_new_zero_sized(ty) {\n    Ok(c) => c,\n    Err(e) if e.to_string().contains(\"Cannot create a zero-sized constant\")\n        && !e.to_string().contains(\"bytes\") => {\n        // layout_of failed: type is generic/recursive/unsized. Do not retry\n        // with the same ty; resolve generics first.\n        return default_const(ty);\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Call `Ty::layout()` first — it returns the same `layout_of` error as a clean `Result` and lets you branch before reaching the ZST constructor.","Layout computation fails for generic (not fully monomorphized) types, recursive types whose layout is being computed, and unsized types; ensure the type is concrete and sized.","Distinguish the layout-failure variant (message has no `bytes`) from the non-ZST variant (message contains `has N bytes`) so your fallback path is correct."],"tags":["rust","const","layout","zst"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}