rust-lang/rust · error · B::Error
Cannot create a zero-sized constant for type
Error message
Cannot create a zero-sized constant for type `{ty_internal}`: Type `{ty_internal}` has {} bytes What it means
Thrown by `try_new_const_zst` (impls.rs:481) when the type's layout is computed successfully but its size is non-zero. A zero-sized constant is only valid for zero-sized types; passing a normal sized type (e.g. `i32`, a struct with fields) triggers this.
Solutions
- Only call `try_new_const_zst` after confirming the type's size is 0.
- For non-ZST types, use the appropriate constructor (`try_new_const_uint`, `new_const_str`, scalar constructors).
- Add a debug assertion / branch on `layout.size().bytes() == 0`.
Example fix
// before let c = ctxt.try_new_const_zst(i32_type)?; // i32 is not ZST // after let c = ctxt.try_new_const_uint(0u128, i32_type)?; // sized type: use real value
Defensive patterns
Strategy: validation
Validate before calling
// Only build a ZST constant when the type is genuinely zero-sized.
let size = ctxt.tcx.layout_of(ctxt.fully_monomorphized().as_query_input(ty))?.size.bytes();
if size != 0 {
// use a sized-type constructor instead
return ctxt.try_new_const_uint(0, ty);
}
ctxt.try_new_const_zst(ty) Type guard
fn is_zst<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, env: TypingEnv<'tcx>) -> bool {
tcx.layout_of(env.as_query_input(ty)).map_or(false, |l| l.size.bytes() == 0)
} Prevention
- Reserve try_new_const_zst strictly for unit-like / zero-sized types.
- Branch on size before choosing a constant constructor.
When it happens
Trigger: Calling `try_new_const_zst` for a type whose `layout_of(...).size.bytes() != 0`, such as any integer/float, a non-empty struct/enum, or a pointer.
Common situations: Misusing `try_new_const_zst` as a generic 'default constant' constructor for arbitrary types; assuming a type is ZST when it is not after a refactor changes its fields.
Related errors
- Cannot create a zero-sized constant for type
- Const ` ` cannot be encoded as u64
- Failed to get ABI for
- Failed to get layout for
- Value overflow: cannot convert
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/8d9b9526c44c9641.
Report an issue: GitHub.
Appendix: source
Thrown at compiler/rustc_public_bridge/src/context/impls.rs:481
}
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)
}
/// Create a caller location constant from a span.
///
/// This produces a `&'static core::panic::Location<'static>` constant,
/// which is the implicit extra argument for `#[track_caller]` functions.
pub fn span_as_caller_location(&self, span: Span) -> MirConst<'tcx> {View on GitHub (pinned to 7088e4b63a)