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

  1. Verify you are not indirectly requiring `const Sized` (e.g. via a `~const` where-clause on a const trait); remove or relax the bound.
  2. Disable `-Znext-solver` and/or `const_trait_impl` to confirm the feature-gated path is responsible.
  3. Reduce to a minimal `const fn`/`const trait` reproducer and report against the const-effects tracking issue on the Rust repo.
  4. 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

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


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