rust-lang/rust · error · B::Error

Failed to get layout for `{ty}`: {err}

Error message

Failed to get layout for `{ty}`: {err}

What it means

Emitted by CompilerCtxt::handle_layout_err (compiler/rustc_public_bridge/src/context/mod.rs:59), the LayoutOfHelpers impl for CompilerCtxt. It converts the ty::layout::LayoutError produced by rustc's layout_of query into a Bridge::Error string so external consumers of rustc_public receive a typed Result::Err instead of a panic. The LayoutError variants it can wrap are Unknown (no sensible layout, e.g. unsized field or unsatisfiable Sized bound), SizeOverflow (larger than isize::MAX bytes), InvalidSimd (zero-length or too many lanes), TooGeneric (layout depends on a still-generic parameter), NormalizationFailure (alias failed to normalize after opaque-type revelation), and ReferencesError (a non-layout error was already reported elsewhere).

Source

Thrown at compiler/rustc_public_bridge/src/context/mod.rs:59

        err: ty::layout::FnAbiError<'tcx>,
        _span: rustc_span::Span,
        fn_abi_request: ty::layout::FnAbiRequest<'tcx>,
    ) -> B::Error {
        B::Error::new(format!("Failed to get ABI for `{fn_abi_request:?}`: {err:?}"))
    }
}

impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for CompilerCtxt<'tcx, B> {
    type LayoutOfResult = Result<ty::layout::TyAndLayout<'tcx>, B::Error>;

    #[inline]
    fn handle_layout_err(
        &self,
        err: ty::layout::LayoutError<'tcx>,
        _span: rustc_span::Span,
        ty: Ty<'tcx>,
    ) -> B::Error {
        B::Error::new(format!("Failed to get layout for `{ty}`: {err}"))
    }
}

impl<'tcx, B: Bridge> HasTypingEnv<'tcx> for CompilerCtxt<'tcx, B> {
    fn typing_env(&self) -> ty::TypingEnv<'tcx> {
        ty::TypingEnv::fully_monomorphized()
    }
}

impl<'tcx, B: Bridge> HasTyCtxt<'tcx> for CompilerCtxt<'tcx, B> {
    fn tcx(&self) -> TyCtxt<'tcx> {
        self.tcx
    }
}

impl<'tcx, B: Bridge> HasDataLayout for CompilerCtxt<'tcx, B> {
    fn data_layout(&self) -> &rustc_abi::TargetDataLayout {
        self.tcx.data_layout()

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Before calling ty_layout, filter out types that cannot have a fixed layout: check ty.has_param() / ty.has_infer() / ty.has_placeholders() and skip those.
  2. Read the embedded LayoutError variant and route accordingly: TooGeneric/Unknown -> expected, skip the type; SizeOverflow/InvalidSimd -> reject the input as malformed; NormalizationFailure -> the target crate must type-check first; ReferencesError -> a prior error must be fixed before layout queries are meaningful.
  3. Ensure the analyzed crate type-checks cleanly (cargo check with no errors) before driving layout queries; rustc cannot compute layouts for error-tainted types.
  4. Restrict iteration to items whose body is available (ctxt.has_body(def_id)) and whose instances are fully monomorphized before requesting their layout.
  5. Pin the exact nightly toolchain that matches your rustc_public consumer crate version, since rustc_public_bridge's LayoutError surface and TypingEnv semantics change across versions.

Example fix

// before
let layout = ctxt.ty_layout(ty)?;

// after: skip generic/inference-bearing types instead of erroring
use rustc_middle::ty::TypeVisitableExt;
if ty.has_param() || ty.has_infer() || ty.has_placeholders() {
    // layout is not fixed; skip this type
    continue;
}
let layout = ctxt.ty_layout(ty)?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Before ty_layout() (and the const constructors that call it internally:
// try_new_const_zst, try_new_const_uint, try_new_ty_const_uint): reject types the bridge cannot lay out.
if ty.has_param() {
    return Err(MyError::NotMonomorphized(format!("{ty:?} still has generic parameters")));
}
if ty.has_escape_bound_vars() {
    return Err(MyError::BoundVars(format!("{ty:?} has escaping bound vars")));
}
if ty.references_error() {
    return Err(MyError::TypeError(format!("{ty:?} contains Ty::Error")));
}

Type guard

/// True iff `ty` is layout-computable through CompilerCtxt::ty_layout
/// (fully monomorphized, no escaping bound vars, no Ty::Error).
fn ty_layout_safe<'tcx>(ty: rustc_middle::ty::Ty<'tcx>) -> bool {
    !ty.has_param() && !ty.has_escape_bound_vars() && !ty.references_error()
}

Try / catch

// ty_layout() returns Result<Layout, B::Error>; treat failure as 'layout unknown', not fatal.
// Enrich with the offending type before propagating.
let layout = ctxt
    .ty_layout(ty)
    .map_err(|e| MyError::LayoutUnavailable {
        ty: format!("{ty:?}"),
        source: e,
    })?;

Prevention

When it happens

Trigger: Calling CompilerCtxt::ty_layout(ty) (impls.rs:767) on a type that still contains generic parameters or inference variables; computing layout of an opaque/impl Trait whose concrete type is not revealed under TypingEnv::fully_monomorphized(); a recursive type whose representation is not yet finalized; an array/Vec-like type whose evaluated length exceeds the target object-size bound; a SIMD type with zero elements or more lanes than the target limit; an alias that cannot normalize post-monomorphization.

Common situations: Tools built on the unstable rustc_public crate (ABI extractors, code generators, binding emitters, rustdoc-json consumers) iterating over all DefIds of a crate and requesting layouts for Self, generics, or trait-object-related types that legitimately have no monomorphic layout; using a TypingEnv other than fully_monomorphized when querying through CompilerCtxt; toolchain/nightly version skew between rustc_public and rustc_public_bridge; analyzing a crate that emitted type-check errors, leaving LayoutError::ReferencesError behind.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/cb2d2e645336fc96.json. Report an issue: GitHub.