rust-lang/rust · error · B::Error
Cannot create a zero-sized constant for type `{ty_internal}`
Error message
Cannot create a zero-sized constant for type `{ty_internal}`: {err} What it means
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.
Source
Thrown at compiler/rustc_public_bridge/src/context/impls.rs:464
/// Evaluate constant as a target usize.
pub fn eval_target_usize(&self, cnst: MirConst<'tcx>) -> Result<u64, B::Error> {
use crate::context::TypingEnvHelpers;
cnst.try_eval_target_usize(self.tcx, self.fully_monomorphized())
.ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
}
pub fn eval_target_usize_ty(&self, cnst: ty::Const<'tcx>) -> Result<u64, B::Error> {
cnst.try_to_target_usize(self.tcx)
.ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
}
pub fn try_new_const_zst(&self, ty_internal: Ty<'tcx>) -> Result<MirConst<'tcx>, B::Error> {
let size = self
.tcx
.layout_of(self.fully_monomorphized().as_query_input(ty_internal))
.map_err(|err| {
B::Error::new(format!(
"Cannot create a zero-sized constant for type `{ty_internal}`: {err}"
))
})?
.size;
if size.bytes() != 0 {
return Err(B::Error::new(format!(
"Cannot create a zero-sized constant for type `{ty_internal}`: \
Type `{ty_internal}` has {} bytes",
size.bytes()
)));
}
Ok(MirConst::Ty(ty_internal, self.const_zero_sized(ty_internal)))
}
pub fn const_zero_sized(&self, ty_internal: Ty<'tcx>) -> ty::Const<'tcx> {
ty::Const::zero_sized(self.tcx, ty_internal)
}View on GitHub (pinned to 22057b88b0)
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.
Example fix
// before let c = cx.try_new_const_zst(generic_ty)?; // after let concrete = cx.fully_monomorphized().instantiate(generic_ty, args); let c = cx.try_new_const_zst(concrete)?;
Defensive patterns
Strategy: validation
Validate before calling
// Before MirConst::try_new_zero_sized(ty):
// try_new_const_zst calls layout_of internally and surfaces its error here.
// Pre-compute the layout so the failure is observable as a normal Result
// rather than inside the ZST constructor.
let layout = ty.layout()?; // surfaces layout_of errors explicitly
let shape = layout.shape();
if shape.is_unsized() {
return Err(format!("type {:?} is unsized; no ZST constant", ty));
}
let zst = MirConst::try_new_zero_sized(ty)?; Try / catch
match MirConst::try_new_zero_sized(ty) {
Ok(c) => c,
Err(e) if e.to_string().contains("Cannot create a zero-sized constant")
&& !e.to_string().contains("bytes") => {
// layout_of failed: type is generic/recursive/unsized. Do not retry
// with the same ty; resolve generics first.
return default_const(ty);
}
Err(e) => return Err(e.into()),
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Cannot create a zero-sized constant for type `{ty_internal}`
- Const `{cnst:?}` cannot be encoded as u64
- Value overflow: cannot convert `{value}` to `{ty_internal}`.
- aggregates can't have `FieldsShape::Primitive`
- assignment does not match variant
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/c710bb6f79261d19.json.
Report an issue: GitHub.