rust-lang/rust · error

struct type

Error message

struct type

What it means

`const_struct` in `common.rs:298-304` builds an anonymous struct type via `self.type_struct(&fields, packed)` then asserts `typ.is_struct().expect("struct type")`. The panic means the type returned by `type_struct` is not recognized as a struct by `is_struct()`. rustc_codegen_gcc relies on the gccjit `Type::is_struct` returning `Some` for freshly-created struct types; if it returns `None`, the codegen cannot construct the struct value. This is a type-system invariant violation in the backend, typically caused by a mismatch between how `type_struct` produces a type and how `is_struct` inspects it (e.g. an opaque/record type, a vectorized type, or a binding version difference).

Source

Thrown at compiler/rustc_codegen_gcc/src/common.rs:302

        let mut const_str_cache = self.const_str_cache.borrow_mut();
        let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| {
            let g = self.global_string(s);
            const_str_cache.insert(s.to_owned(), g);
            g
        });
        let len = s.len();
        let cs = self.const_ptrcast(
            str_global.get_address(None),
            self.type_ptr_to(self.layout_of(self.tcx.types.str_).gcc_type(self)),
        );
        (cs, self.const_usize(len as u64))
    }

    fn const_struct(&self, values: &[RValue<'gcc>], packed: bool) -> RValue<'gcc> {
        let fields: Vec<_> = values.iter().map(|value| value.get_type()).collect();
        // FIXME(antoyo): cache the type? It's anonymous, so probably not.
        let typ = self.type_struct(&fields, packed);
        let struct_type = typ.is_struct().expect("struct type");
        self.context.new_struct_constructor(None, struct_type.as_type(), None, values)
    }

    fn const_vector(&self, values: &[RValue<'gcc>]) -> RValue<'gcc> {
        let typ = self.type_vector(values[0].get_type(), values.len() as u64);
        self.context.new_rvalue_from_vector(None, typ, values)
    }

    fn const_to_opt_uint(&self, _v: RValue<'gcc>) -> Option<u64> {
        // FIXME(antoyo)
        None
    }

    fn const_to_opt_u128(&self, _v: RValue<'gcc>, _sign_ext: bool) -> Option<u128> {
        // FIXME(antoyo)
        None
    }

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Inspect the value of `typ` (dump via debug) right before the `is_struct()` call to confirm whether gccjit returns a struct or a different kind (union/opaque/vector).
  2. Reproduce with the matching libgccjit version pinned in the project; the most common cause is a libgccjit/gccjit-crate version skew — align them.
  3. If `type_struct` legitimately returns a non-struct for some inputs, guard `const_struct`: short-circuit single-field or empty cases instead of forcing `is_struct`.
  4. Report upstream to rustc_codegen_gcc with the field type list and libgccjit version, since `is_struct` returning `None` for a just-created struct is a backend contract break.

Example fix

// before
let struct_type = typ.is_struct().expect("struct type");
self.context.new_struct_constructor(None, struct_type.as_type(), None, values)

// after (diagnose instead of asserting blindly)
let struct_type = typ.is_struct().unwrap_or_else(|| {
    panic!("const_struct: type_struct did not yield a struct (kind={:?}, fields={}, packed={})",
        typ, values.len(), packed);
});
self.context.new_struct_constructor(None, struct_type.as_type(), None, values)
Defensive patterns

Strategy: type-guard

Type guard

// common.rs:302 -> typ.is_struct().expect("struct type") inside const_struct.
// Narrow before constructing so a mismatch yields a Result, not a panic.
fn safe_const_struct<'gcc>(
    cx: &CodegenCx<'gcc, '_>,
    values: &[RValue<'gcc>],
    packed: bool,
) -> Option<RValue<'gcc>> {
    let fields: Vec<_> = values.iter().map(|v| v.get_type()).collect();
    let typ = cx.type_struct(&fields, packed);
    let struct_type = typ.is_struct()?;
    Some(cx.context.new_struct_constructor(None, struct_type.as_type(), None, values))
}

Prevention

When it happens

Trigger: Calling `const_struct(values, packed)` where `type_struct` yields a type for which `Type::is_struct()` returns `None`. Likely with zero fields, a single field that gccjit represents as a non-record, very large field counts, or when the gccjit bindings version changed the representation of anonymous structs.

Common situations: Encountered after upgrading the `gccjit` crate / libgccjit version where struct-type representation changed; building a crate with anonymous struct constants whose field shape trips an edge case in `type_struct`; deviating local patches to `type_of.rs`/`type.rs` that break the struct-type contract.

Related errors


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