rust-lang/rust · critical
Field is not const
Error message
Field is not const
What it means
Internal `unreachable!` in the next-gen trait solver's const-effect candidate assembly for the built-in `Field` trait (`core::marker::Field`, part of the unsafe field-access / `proj` machinery). `Field` has no const implementation, so `consider_builtin_field_candidate` is a never-executed stub; reaching it means the solver routed a `T: const Field<...>` goal into built-in candidate assembly and the compiler ICEs.
Source
Thrown at compiler/rustc_next_trait_solver/src/solve/effect_goals.rs:472
fn consider_builtin_try_as_dyn_candidate(
_ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
unreachable!("`TryAsDynCompat` is not const: {:?}", goal)
}
fn consider_structural_builtin_unsize_candidates(
_ecx: &mut EvalCtxt<'_, D>,
_goal: Goal<I, Self>,
) -> Result<Vec<Candidate<I>>, RerunNonErased> {
unreachable!("Unsize is not const")
}
fn consider_builtin_field_candidate(
_ecx: &mut EvalCtxt<'_, D>,
_goal: Goal<<D as SolverDelegate>::Interner, Self>,
) -> Result<Candidate<<D as SolverDelegate>::Interner>, NoSolutionOrRerunNonErased> {
unreachable!("Field is not const")
}
}
impl<D, I> EvalCtxt<'_, D>
where
D: SolverDelegate<Interner = I>,
I: Interner,
{
#[instrument(level = "trace", skip(self))]
pub(super) fn compute_host_effect_goal(
&mut self,
goal: Goal<I, ty::HostEffectPredicate<I>>,
) -> QueryResultOrRerunNonErased<I> {
let (_, proven_via) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
let trait_goal: Goal<I, ty::TraitPredicate<I>> =
goal.with(ecx.cx(), goal.predicate.trait_ref);
ecx.compute_trait_goal(trait_goal).map_err(Into::into)
})?;View on GitHub (pinned to 22057b88b0)
Solutions
- Remove the const/`~const Field` bound — field projection is not const.
- Audit `#[const_trait]` traits for `Field` in their implied bounds.
- Report the ICE upstream with a minimal reproducer and the `-Znext-solver`/`proj` feature flags.
- Bisect nightlies; the Field trait and its const routing are highly unstable.
Example fix
// before
const fn get<S, F>(s: &S) -> &F::Type where S: const Field<F> { unimplemented!() }
// after
fn get<S, F>(s: &S) -> &F::Type where S: Field<F> { unimplemented!() } Defensive patterns
Strategy: validation
Validate before calling
// build.rs: reject const Field (field-offset projection) bounds
fn main() {
let src = std::fs::read_to_string("src/lib.rs").unwrap_or_default();
for banned in ["~const Field", "const Field", "core::field::Field"] {
assert!(!src.contains(banned), "rejected: {banned} — Field projection is not const");
}
println!("cargo:rerun-if-changed=src/lib.rs");
} Prevention
- The `Field` projection trait (struct field access by name/path, behind `core::field`) has no const candidate (effect_goals.rs:472); do not demand `T: const Field<...>`.
- In const code, access struct fields by direct `s.field` syntax, not through the `Field` trait.
- Avoid generic field-projection helpers in `const fn`; specialize them or move to runtime.
- An ICE here with no explicit `Field` bound means the solver mis-routed — report upstream.
When it happens
Trigger: A host-effect goal resolves to the `Field` lang item: `T: const Field<F>` / `~const Field<F>`, typically via nightly field-projection (`proj`) experiments inside `const fn`, or a `#[const_trait]` whose implied bounds include `Field`.
Common situations: Using nightly field-projection / `unsafe` field-access features together with `const_trait_impl`; `-Znext-solver` on struct-projection-heavy generic code; nightly regression as field-trait routing was wired into effect-goal assembly.
Related errors
- FusedIterator is not const
- AsyncIterator is not const
- Coroutine is not const
- DiscriminantKind is not const
- TransmuteFrom is not const
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/851adc746352cd93.json.
Report an issue: GitHub.