rust-lang/rust · critical
expected pointee to have a layout
Error message
expected pointee to have a layout
What it means
This fires in Cranelift codegen when processing the `CopyNonOverlapping` non-diverging intrinsic. The code extracts the pointee type from the destination raw pointer (`dst.layout().ty`) and calls `fx.tcx.layout_of(pointee).expect("expected pointee to have a layout")`. If the pointee type doesn't have a computable layout (e.g., it's unsized in an unsupported way, it's an extern type, or it's an error type from a prior compilation failure), `layout_of` returns `Err` and this panics.
Source
Thrown at compiler/rustc_codegen_cranelift/src/base.rs:953
StatementKind::Coverage { .. } => unreachable!(),
StatementKind::Intrinsic(intrinsic) => match &**intrinsic {
// We ignore `assume` intrinsics, they are only useful for optimizations
NonDivergingIntrinsic::Assume(_) => {}
NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
src,
dst,
count,
}) => {
let dst = codegen_operand(fx, dst);
let &ty::RawPtr(pointee, _) = dst.layout().ty.kind() else {
bug!("expected pointer")
};
let pointee_layout = fx
.tcx
.layout_of(fx.typing_env().as_query_input(pointee))
.expect("expected pointee to have a layout");
let elem_size: u64 = pointee_layout.layout.size().bytes();
let dst = dst.load_scalar(fx);
let src = codegen_operand(fx, src).load_scalar(fx);
let count = codegen_operand(fx, count).load_scalar(fx);
let bytes = if elem_size != 1 {
fx.bcx.ins().imul_imm_u(count, elem_size as i64)
} else {
count
};
fx.bcx.call_memcpy(fx.target_config, dst, src, bytes);
}
},
}
}
View on GitHub (pinned to 7088e4b63a)
Solutions
- Fix any preceding compilation errors first — a `ty::Error` leaking to codegen is often the root cause.
- Avoid `copy_nonoverlapping` with pointers to extern types or unsupported unsized types; use a concrete sized type instead.
- If the pointee is legitimately sized, file a bug — `layout_of` should succeed for all sized types at codegen time.
- Use the LLVM backend (`-Zcodegen-backend=llvm`) to check if this is cg_clif-specific.
- If contributing to cg_clif, handle `layout_of` errors with a proper diagnostic instead of panicking.
Example fix
// before (extern type pointee → no layout → panic)
extern "C" { type Opaque; }
unsafe fn copy(ptr: *const Opaque, dst: *mut Opaque) {
std::ptr::copy_nonoverlapping(ptr, dst, 1);
}
// after (use a concrete sized type or byte buffer)
unsafe fn copy(ptr: *const u8, dst: *mut u8, len: usize) {
std::ptr::copy_nonoverlapping(ptr, dst, len);
} Defensive patterns
Strategy: validation
Validate before calling
// Before calling copy_nonoverlapping, ensure the pointee is sized
// and has a valid layout:
fn safe_copy_nonoverlapping<T: Sized>(src: *const T, dst: *mut T, count: usize) {
// T: Sized guarantees layout_of succeeds
unsafe { std::ptr::copy_nonoverlapping(src, dst, count); }
}
// Never call with pointers to extern types or ty::Error Type guard
// Type guard: only allow copy_nonoverlapping on Sized types
fn is_sized_pointee<T: ?Sized>() -> bool {
std::mem::size_of_val(&()) > 0 // placeholder
}
// Better: use a trait bound
trait SafeCopy: Sized {}
impl<T: Sized> SafeCopy for T {}
fn copy_safe<T: SafeCopy>(src: *const T, dst: *mut T, len: usize) {
unsafe { std::ptr::copy_nonoverlapping(src, dst, len) }
} Prevention
- Always use T: Sized bounds on functions that call copy_nonoverlapping with raw pointers.
- Never create raw pointers to extern types for use with copy intrinsics.
- Fix all preceding compilation errors before investigating codegen ICEs.
- Use the LLVM backend as a fallback for code with unusual unsized types.
When it happens
Trigger: Calling `core::intrinsics::copy_nonoverlapping` (or code that desugars to the `CopyNonOverlapping` MIR intrinsic) with a raw pointer whose pointee type has no valid layout — extern types, `?Sized` types that aren't slices/str/trait objects, or types containing errors from failed compilation.
Common situations: Using raw pointers to extern types (`extern type`) or custom unsized types with `copy_nonoverlapping`. Also triggered when an earlier type-check error produces a type error (ty::Error) that propagates to codegen — the error type has no layout.
Related errors
- Non terminating drop_in_place_real???
- expected monomorphic const in codegen
- erroneous constant missed by mono item collection
- expected monomorphic const in codegen
- not implemented
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/81dfdc95b2a56459.
Report an issue: GitHub.