Skip to content

[ICE]: clippy-driver: can't type-check body of DefId for a plain const used in a body, under macroless_generic_const_args #162484

Description

@oknyshuk

ICE: clippy-driver can't type-check body of DefId on any const used in a function body, under macroless_generic_const_args

clippy-driver ICEs on a plain, non-generic const item as soon as it is used inside a body, when macroless_generic_const_args is enabled. rustc compiles the same file cleanly, so this only bites through Clippy.

Code

#![allow(incomplete_features)]
#![feature(generic_const_args, macroless_generic_const_args, min_generic_const_args)]

pub const MAX: usize = 4;

pub fn f(x: usize) -> bool {
    x < 1 || x > MAX
}
$ rustc         --edition 2024 --crate-type lib --emit=metadata a.rs   # clean
$ clippy-driver --edition 2024 --crate-type lib --emit=metadata a.rs   # ICE

Meta

rustc 1.100.0-nightly (cea272fa3 2026-09-07) / clippy 0.1.100 (cea272fa35 2026-09-07), x86_64-unknown-linux-gnu

Regression. Clean on nightly-2026-08-18 (clippy-driver ... -Znext-solver=globally a.rs, exit 0 — the flag is mandatory on that date and became the default later). So this landed in (2026-08-18, 2026-09-07].

Error output

error: internal compiler error: compiler/rustc_hir_typeck/src/lib.rs:124:9: can't type-check body of DefId(0:3 ~ a[b864]::MAX)
 --> a.rs:4:1
  |
4 | pub const MAX: usize = 4;
  | ^^^^^^^^^^^^^^^^^^^^

query stack during panic:
#0 [typeck_root] type-checking `MAX`
#1 [check_match] match-checking `MAX`
#2 [mir_built] building MIR for `MAX`
#3 [trivial_const] checking if `MAX` is a trivial const
#4 [eval_to_const_value_raw] simplifying constant for the type system `MAX`
#5 [analysis] running analysis passes on crate `a`
end of query stack

Under macroless_generic_const_args the const is a type-system const with no typeck-able body, but Clippy's constant folding still drives eval_to_const_value_raw on it, which reaches mir_built -> check_match -> typeck_root -> span_bug!.

Notes from bisecting

  • Feature combination. Minimal set that ICEs is generic_const_args + macroless_generic_const_args + min_generic_const_args. Dropping macroless_generic_const_args makes it clean (generic_const_args + generic_const_items + min_generic_const_args is clean). generic_const_items is not involved.
  • The const need not be generic. A plain pub const MAX: usize = 4; is enough.
  • Only body uses trip it. Array-length position is fine:
    pub static A: [u8; MAX] = [0; MAX];   // clean
    whereas x > MAX, x + MAX, if x == MAX, match x { MAX => .. } all ICE.
  • Not fixable by lint level. -A clippy::nonminimal_bool still ICEs (manual_range_contains takes the same ConstEvalCtxt path). Any lint that const-folds a body expression will reach it.
  • Workaround for affected crates: cargo clippy --no-deps and exclude the crate; --exclude alone is not enough, since a path dependency is still linted.

Possibly related

The last one looks like the same underlying cause; this is the Clippy-visible manifestation of it, still reproducing.

Why it matters in practice

This is the blocker that stops a crate using generic_const_args from being linted at all: the ICE propagates to every crate in the graph that reads its metadata, so a whole workspace loses cargo clippy even though cargo build and cargo test succeed.


Filed with LLM assistance: the reproducers were reduced from a real-world codebase and every command shown was executed by an AI agent under human direction, with output captured verbatim. Please flag anything that looks mis-attributed and I'll re-check it.

@rustbot label +I-ICE +T-compiler +C-bug +F-generic_const_args +F-min_generic_const_args +A-clippy

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-clippyRelevant to the Clippy team.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions