rust-lang/rust · critical

unexpected associated type {:?} in `Field`

Error message

unexpected associated type {:?} in `Field`

What it means

The `Field` lang-item trait (the experimental named-struct-field-projection / offset_of feature) exposes exactly two associated-type projections, `FieldBase` and `FieldType`. `consider_builtin_field_candidate` (normalizes_to.rs:1073) handles those two via `SolverProjectionLangItem::{FieldBase,FieldType}`; the `_ => panic!` arm fires when the projection's def_id resolves to some other lang item or an unexpected associated type on `Field`. That means a `NormalizesTo` goal was built for an associated type this builtin candidate does not know how to project — an internal-invariant violation.

Source

Thrown at compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs:1073

    }

    fn consider_builtin_field_candidate(
        ecx: &mut EvalCtxt<'_, D>,
        goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        let self_ty = goal.predicate.self_ty();
        let ty::Adt(def, args) = self_ty.kind() else {
            return Err(NoSolution.into());
        };
        let Some(FieldInfo { base, ty, .. }) = def.field_representing_type_info(ecx.cx(), args)
        else {
            return Err(NoSolution.into());
        };
        let def_id = goal.predicate.alias.expect_projection_ty_def_id();
        let ty = match ecx.cx().as_projection_lang_item(def_id) {
            Some(SolverProjectionLangItem::FieldBase) => base,
            Some(SolverProjectionLangItem::FieldType) => ty,
            _ => panic!("unexpected associated type {:?} in `Field`", goal.predicate),
        };
        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
            ecx.instantiate_normalizes_to_term(goal, ty.into())?;
            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
        })
    }

    fn consider_builtin_try_as_dyn_candidate(
        _ecx: &mut EvalCtxt<'_, D>,
        _goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        unreachable!("try_as_dyn helper trait doesn't have assoc types")
    }
}

impl<D, I> EvalCtxt<'_, D>
where
    D: SolverDelegate<Interner = I>,

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Report the ICE at https://github.com/rust-lang/rust/issues with the `<T as Field>::...` projection and the panic line.
  2. Disable `-Znext-solver` and the `field`/`offset_of_enum` nightly feature flags to avoid the path.
  3. Update nightly (`rustup update nightly`).
  4. Minimize: remove custom associated types on the type involved in the `Field` projection and re-test.

Example fix

// before — custom assoc on a type used with field projection
impl<...> Field for S { type FieldBase = ...; type FieldType = ...; type Extra = ...; }
// after — keep only the two well-known associated types
impl<...> Field for S { type FieldBase = ...; type FieldType = ...; }
Defensive patterns

Strategy: type-guard

Validate before calling

// The `Field` trait (struct field projection / offset_of feature) only provides
// types matching real struct fields. Validate that any associated type you name
// corresponds to an actual field before referencing it.
struct Foo { a: i32, b: String }
// Correct:  <Foo as Field<name::a>>::Type  -> i32
// Wrong:    <Foo as Field<name::c>>::Type   -> triggers error
fn check_field_type<T>() -> bool { /* compile-time only */ false }

Type guard

// Only reference Field associated types that are backed by a real named field.
// Use a macro to restrict projections to known field names:
macro_rules! field_type {
    ($struct:ty, $field:ident) => {
        <$struct as core::ops::Field<core::mem::offset_of!($struct, $field)>>::Type
    };
}
// This fails at compile time if `$field` does not exist on `$struct`,
// surfacing a clear E-field-not-found rather than the solver panic.

Prevention

When it happens

Trigger: A projection goal `<T as Field>::Assoc` reaches `consider_builtin_field_candidate` where `as_projection_lang_item(def_id)` returns neither `FieldBase` nor `FieldType` — e.g. a hand-written lang-item trait with extra assoc types, or a mismatch where the def_id maps to a different lang item.

Common situations: Developers experimenting with `core::ops::Field` / field-projection on nightly under `-Znext-solver`, particularly after changes to the `Field` lang item or when mixing the feature with custom assoc types on the same trait.

Related errors


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