Skip to content

ICE: Found unstable fingerprints for explicit_supertraits_containing_assoc_item on incremental rebuild when any #[derive] is added #158131

@panayang

Description

@panayang

I tried to get the MRE but after a whole afternoon failed to do so, and try to throw claude on to this work of getting the MRE but opus still fails. what we find is basically (these text, some are copied from claude but others are edited/written by myself):

Summary

Running cargo +nightly check (or cargo +nightly clippy) on the
bincode v3-release branch
produces an ICE on the second incremental build after any #[derive(...)]
is added to the crate.

Steps to reproduce

git clone https://github.com/Apich-Organization/bincode
cd bincode
git checkout v3-release

# Step 1 — prime the incremental cache
cargo +nightly check --features alloc,std,derive,serde

# Step 2 — any edit that adds a #[derive]; a plain comment is NOT enough
# #[derive(Copy, Clone)]
# struct _Trigger;
printf '\n#[derive(Copy, Clone)] struct _Trigger;\n' >> src/lib.rs

# Step 3 — ICE on the second incremental build
cargo +nightly check --features alloc,std,derive,serde

ICE output

error: internal compiler error: encountered incremental compilation error with
explicit_supertraits_containing_assoc_item(39269fc2b6d68024-cd3d7d3d559ab5ba)

Found unstable fingerprints for
explicit_supertraits_containing_assoc_item(39269fc2b6d68024-cd3d7d3d559ab5ba):
EarlyBinder { value: [(
  Binder { value: TraitPredicate(<Self as core::marker::MetaSized>, polarity:Positive),
           bound_vars: [] },
  src/config.rs:719:5: 721:6 (#2978)
)], .. }

query stack during panic:
#0 [explicit_supertraits_containing_assoc_item] computing the super traits of
   `config::internal::InternalEndianConfig` with associated type name `Mode`
#1 [typeck_root] type-checking `features::impl_alloc::encode_to_vec`

rustc-ice-2026-06-19T12_59_41-8484.txt

Workaround

CARGO_INCREMENTAL=0 cargo +nightly check --features alloc,std,derive,serde

Toolchain

rustc 1.98.0-nightly (c1b22f44c 2026-06-17)

Both on x86_64 linux and windows.

Related issues

There is a very similar issue under rust-clippy, rust-lang/rust-clippy#17262 but I found it to not only a issue with clippy, so I opened the issue here again.

Notes

  • cargo +nightly clippy and cargo +nightly check both trigger the ICE
  • CARGO_INCREMENTAL=0 is the workaround
  • A truly minimal self-contained reproduction has not been found yet; it appears
    the ICE requires the project to have many existing proc-macro expansions (from
    bincode-derive) before the relevant query fires, so that the synthesized
    MetaSized SyntaxContext is large enough to shift detectably. Contributions to
    further minimization are welcome.

Also here's some analysis coauthored by me and LLM, but, well, myself is not a active member in the rustc project so this could be only for reference:


The explicit_supertraits_containing_assoc_item query for InternalEndianConfig
returns a MetaSized supertrait predicate. MetaSized is synthesized by the
nightly compiler (from the sized_hierarchy feature) with a freshly-allocated
SyntaxContext ID. The ID's value depends on how many macro expansions have
occurred in the current session before the synthesis point.

Between sessions, the number of prior expansions changes when any #[derive(…)]
is added: the new derive proc-macro expansion shifts the SyntaxContext counter by k
before InternalEndianConfig's supertraits are computed. So the cached fingerprint
(SyntaxContext N) differs from the recomputed one (SyntaxContext N+k) → ICE.

Notably, plain comments do NOT reproduce the bug — only items with #[derive]
(or other macro-expanding annotations) do, because only those advance the
SyntaxContext counter.

Relevant trait structure
The essential traits involved (from src/config.rs):

// Trait with NO explicit supertraits — MetaSized is its only implicit supertrait.
// The MetaSized supertrait predicate gets a session-dependent SyntaxContext → ICE.
pub(crate) trait InternalEndianConfig {
    const ENDIAN: Endianness;
}

// Trait that carries the associated type `Mode`
pub(crate) trait InternalFingerprintConfigExt {
    type Mode;
}

// Combined trait
pub(crate) trait Config:
    InternalEndianConfig + … + InternalFingerprintConfigExt + Copy + Clone {}

And the trigger function in src/lib.rs (via features/):

pub fn encode_to_vec<E: Encode, C: Config>(val: E, config: C) -> Result<Vec<u8>, EncodeError>
where
    C::Mode: InternalFingerprintGuard<E, C>,

Resolving C::Mode walks all supertraits of Config — including InternalEndianConfig
— calling explicit_supertraits_containing_assoc_item(InternalEndianConfig, "Mode").
That result (the MetaSized predicate with non-deterministic SyntaxContext) gets cached
in session 1, then mismatches in session 2 when the SyntaxContext counter shifts.


And anyway, I am working on try to find the MRE, but well, a little bit hard...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions