{"id":"01c48eb713080564","repo":"rust-lang/rust","slug":"attempted-to-compute-stable-hash-for-lazyattrtoken","errorCode":null,"errorMessage":"Attempted to compute stable hash for LazyAttrTokenStream","messagePattern":"Attempted to compute stable hash for LazyAttrTokenStream","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_ast/src/tokenstream.rs","lineNumber":162,"sourceCode":"        write!(f, \"LazyAttrTokenStream({:?})\", self.to_attr_token_stream())\n    }\n}\n\nimpl<S: SpanEncoder> Encodable<S> for LazyAttrTokenStream {\n    fn encode(&self, _s: &mut S) {\n        panic!(\"Attempted to encode LazyAttrTokenStream\");\n    }\n}\n\nimpl<D: SpanDecoder> Decodable<D> for LazyAttrTokenStream {\n    fn decode(_d: &mut D) -> Self {\n        panic!(\"Attempted to decode LazyAttrTokenStream\");\n    }\n}\n\nimpl StableHash for LazyAttrTokenStream {\n    fn stable_hash<Hcx: StableHashCtxt>(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) {\n        panic!(\"Attempted to compute stable hash for LazyAttrTokenStream\");\n    }\n}\n\n/// A token range within a `Parser`'s full token stream.\n#[derive(Clone, Debug)]\npub struct ParserRange(pub Range<u32>);\n\n/// A token range within an individual AST node's (lazy) token stream, i.e.\n/// relative to that node's first token. Distinct from `ParserRange` so the two\n/// kinds of range can't be mixed up.\n#[derive(Clone, Debug)]\npub struct NodeRange(pub Range<u32>);\n\n/// Indicates a range of tokens that should be replaced by an `AttrsTarget`\n/// (replacement) or be replaced by nothing (deletion). This is used in two\n/// places during token collection.\n///\n/// 1. Replacement. During the parsing of an AST node that may have a","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_ast/src/tokenstream.rs#L144-L180","documentation":"`panic!(\"Attempted to compute stable hash for LazyAttrTokenStream\")` fires from the `StableHash` impl. Stable hashing feeds incremental-compilation fingerprinting; hashing a lazy stream (whose content depends on live parser cursor state) would produce unstable fingerprints and silently break incr-comp. The panic forces the stream to be converted to a concrete `AttrTokenStream` before it participates in any hash.","triggerScenarios":"Any `StableHash::stable_hash` call on a value still typed as `LazyAttrTokenStream` — typically from incr-comp fingerprinting of an AST node, attribute, or macro token result that retains the lazy variant.","commonSituations":"Refactors that delay forcing of lazy streams past the point where fingerprinting runs. New query inputs that include un-forced `LazyAttrTokenStream`. Incremental compilation ICEs after macro/attribute-related changes.","solutions":["Force the stream to `AttrTokenStream` (`.to_attr_token_stream()`) before storing it in any structure that gets fingerprinted (AST nodes, attributes, query results).","Use `RUST_BACKTRACE=1` to locate the fingerprinting site, then trace back to where the lazy stream should have been forced.","Add a test that hashes the affected node to catch the regression in CI."],"exampleFix":"// before\nstruct Node { tokens: LazyAttrTokenStream }\n// later: stable_hash fails\n\n// after\nstruct Node { tokens: AttrTokenStream }\n// constructed via: lazy.to_attr_token_stream()","handlingStrategy":"validation","validationCode":"// Avoid StableHasher over LazyAttrTokenStream.\n// Hash the materialized form:\nlet stream = lazy.to_attr_token_stream();\nstream.stable_hash(hcx, hasher);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["The `StableHash` impl for `LazyAttrTokenStream` is intentionally a panic; never feed one to a `StableHasher`.","In incremental-compat code paths, materialize via `to_attr_token_stream()` before hashing.","Audit any generic `<T: StableHash>` boundary to ensure a lazy stream can never instantiate it."],"tags":["rustc","internals","tokenstream","stable-hash","incr-comp"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}