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
ICE: clippy-driver
can't type-check body of DefIdon anyconstused in a function body, undermacroless_generic_const_argsclippy-driverICEs on a plain, non-genericconstitem as soon as it is used inside a body, whenmacroless_generic_const_argsis enabled.rustccompiles the same file cleanly, so this only bites through Clippy.Code
Meta
rustc 1.100.0-nightly (cea272fa3 2026-09-07)/clippy 0.1.100 (cea272fa35 2026-09-07),x86_64-unknown-linux-gnuRegression. 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
Under
macroless_generic_const_argstheconstis a type-system const with no typeck-able body, but Clippy's constant folding still driveseval_to_const_value_rawon it, which reachesmir_built->check_match->typeck_root->span_bug!.Notes from bisecting
generic_const_args + macroless_generic_const_args + min_generic_const_args. Droppingmacroless_generic_const_argsmakes it clean (generic_const_args + generic_const_items + min_generic_const_argsis clean).generic_const_itemsis not involved.pub const MAX: usize = 4;is enough.x > MAX,x + MAX,if x == MAX,match x { MAX => .. }all ICE.-A clippy::nonminimal_boolstill ICEs (manual_range_containstakes the sameConstEvalCtxtpath). Any lint that const-folds a body expression will reach it.cargo clippy --no-depsand exclude the crate;--excludealone is not enough, since a path dependency is still linted.Possibly related
#[type_const]+ nested generics; that thread notes ICEs could still appear under-Znext-solvercannot call const_of_item on a non-type_const#161523 (open) —cannot call const_of_item on a non-type_const, alsomacroless_generic_const_argscan't type-check body of DefId#153735 (open) — same message butmin_generic_const_args + generic_const_exprsunder plain rustcmir::Const::Ty#150615 (closed) — MGCA: uses oftype_constitems inside of bodies should lower tomir::Const::TyThe 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_argsfrom being linted at all: the ICE propagates to every crate in the graph that reads its metadata, so a whole workspace losescargo clippyeven thoughcargo buildandcargo testsucceed.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