rust-lang/rust · error
Sized/MetaSized is never const
Error message
Sized/MetaSized is never const
What it means
At effect_goals.rs:256, `consider_builtin_sizedness_candidates` is marked `unreachable!` because the `Sized`/`MetaSized` built-in impl is intentionally never `const` in the host-effect (const-trait) system. The compiler should never ask `T: const Sized` — if it does, an upstream goal was assembled incorrectly. It is part of the `HostEffectPredicate` `GoalKind` assembly, so reaching it means a `const Sized` (or `const MetaSized`) goal reached candidate enumeration.
Source
Thrown at compiler/rustc_next_trait_solver/src/solve/effect_goals.rs:256
)
});
// While you could think of trait aliases to have a single builtin impl
// which uses its implied trait bounds as where-clauses, using
// `GoalSource::ImplWhereClause` here would be incorrect, as we also
// impl them, which means we're "stepping out of the impl constructor"
// again. To handle this, we treat these cycles as ambiguous for now.
ecx.add_goals(GoalSource::Misc, where_clause_bounds)?;
ecx.add_goals(GoalSource::Misc, const_conditions)?;
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
fn consider_builtin_sizedness_candidates(
_ecx: &mut EvalCtxt<'_, D>,
_goal: Goal<I, Self>,
_sizedness: SizedTraitKind,
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
unreachable!("Sized/MetaSized is never const")
}
fn consider_builtin_copy_clone_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
let cx = ecx.cx();
let self_ty = goal.predicate.self_ty();
let constituent_tys =
structural_traits::instantiate_constituent_tys_for_copy_clone_trait(ecx, self_ty)?;
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
ecx.enter_forall_with_assumptions(constituent_tys, goal.param_env, |ecx, tys| {
ecx.add_goals(
GoalSource::ImplWhereBound,
tys.into_iter().map(|ty| {
goal.with(View on GitHub (pinned to 22057b88b0)
Solutions
- Verify you are not indirectly requiring `const Sized` (e.g. via a `~const` where-clause on a const trait); remove or relax the bound.
- Disable `-Znext-solver` and/or `const_trait_impl` to confirm the feature-gated path is responsible.
- Reduce to a minimal `const fn`/`const trait` reproducer and report against the const-effects tracking issue on the Rust repo.
- Upgrade nightly; const-effects is under active development and such ICEs are fixed frequently.
Example fix
// before: ~const Sized leaking into host-effect assembly
const trait C { fn f(); }
const fn use_c<T: ~const C + Sized>(x: T) { T::f(); }
// after: drop the redundant Sized host-effect obligation
const trait C { fn f(); }
const fn use_c<T: ~const C>(x: T) { T::f(); } Defensive patterns
Strategy: validation
Validate before calling
// Sized/MetaSized is provably non-const; reject any const context that depends on it.
const fn assert_not_sized_bound<T>() where T: Sized {} // compile error only if you try this in const-eval
// Static rule enforced at review time: no `const fn` may have an implicit or explicit `Sized` bound that participates in const evaluation. Type guard
// Guard a const-eval entry point against Sized-dependent code.
fn const_entry_safe<T: ?Sized>() -> bool { false } // conservatively reject ?Sized in const paths Prevention
- Do not place `T: Sized` (or rely on the implicit Sized bound) inside `const fn` or `const { ... }` blocks that the next solver must evaluate.
- Mark const entry points `where T: ?Sized` only if you also avoid any operation requiring Sized in the body.
- Gate const-generic crates behind the next solver feature only where you have a concrete (non-Sized-bound) proof obligation.
When it happens
Trigger: Triggered when the next solver evaluates a `HostEffectPredicate` whose trait is `Sized` (lang item) with a const host effect — i.e. an internal goal like `T: const Sized` — and reaches the built-in sizedness candidate branch (effect_goals.rs:251).
Common situations: Nightly with `#![feature(host_effects)]` / `const_trait_impl` and a const trait bound that transitively forces a `const Sized` obligation (e.g. a `const fn` whose argument is `Sized`); mixing `~const` bounds with auto-trait assembly; regressions in how const conditions of const-callable items are propagated.
Related errors
- AsyncFnKindHelper is not const
- Tuple trait is not const
- Pointee is not const
- Future is not const
- Fn* are not yet const
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/df4b02777f40888b.json.
Report an issue: GitHub.