Skip to content

infer: exclude aliasCache scratch bits from TypeDecl hash#2853

Merged
borisbat merged 1 commit into
masterfrom
bbatkin/typedecl-hash-skip-aliascache-bits
May 24, 2026
Merged

infer: exclude aliasCache scratch bits from TypeDecl hash#2853
borisbat merged 1 commit into
masterfrom
bbatkin/typedecl-hash-skip-aliascache-bits

Conversation

@borisbat
Copy link
Copy Markdown
Collaborator

Summary

PR #2849 added aliasCacheValid / aliasCacheHasAlias bits to the TypeDecl::flags union for the lazy findAlias subtree cache. They are runtime scratch state — set on the first findAlias call, retained for later calls — not part of the type's semantic identity. They were leaking into getLookupHash, getSemanticHash, and getOwnSemanticHash via hashmix(hash, flags) / hb.update(flags).

Within a single compile this is deterministic (same input ⇒ same cache lifecycle ⇒ same bit state). Across two semantically equivalent TypeDecls whose findAlias-call lifecycles differ (one cached, one not), the hashes diverge — risky for type interning and AOT semantic hashing across module boundaries.

This adds flagsWithoutAliasCache(td) — save the two bits via const_cast, clear them, read flags, restore — and uses it at the 3 hash sites instead of raw flags.

No ABI change (bits stay in the flags union; the helper only touches them transiently during hash compute).

Test plan

  • daslang.exe dastest/dastest.das -- --test tests/9341 passed, 0 failed
  • daslang.exe -jit tests/jit_tests/array.das + tests/decs/test_bulk_create.das — no verifier errors
  • test_aot.exe -use-aot dastest/dastest.das -- --use-aot --test tests8685 passed, 0 failed
  • No .das files changed (lint/format/detect-dupe not applicable)

🤖 Generated with Claude Code

PR #2849 added aliasCacheValid / aliasCacheHasAlias bits to the
TypeDecl::flags union for the lazy findAlias subtree cache. They are
runtime scratch state set on first findAlias call, not part of the
type's semantic identity. They were leaking into getLookupHash,
getSemanticHash, and getOwnSemanticHash via hashmix(flags) /
hb.update(flags).

Within a single compile this is deterministic (same input -> same
cache lifecycle -> same bit state). Across two semantically equivalent
TypeDecls whose findAlias-call lifecycles differ (one cached, one
not), the hashes diverge -- risky for type interning and AOT semantic
hashing across module boundaries.

Add flagsWithoutAliasCache(td) -- save the two bits via const_cast,
clear them, read flags, restore. Use it at the 3 hash sites.

No ABI change. dastest 9341 pass. AOT test_aot 8685 pass. JIT smoke
clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 24, 2026 13:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prevents TypeDecl hash values from including lazy findAlias cache state, keeping lookup and semantic hashes tied to type identity rather than runtime scratch bits.

Changes:

  • Adds flagsWithoutAliasCache to temporarily exclude aliasCacheValid and aliasCacheHasAlias.
  • Uses the filtered flags in lookup, semantic, and own semantic hash generation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@borisbat borisbat merged commit 8b7ef3d into master May 24, 2026
30 checks passed
@borisbat borisbat deleted the bbatkin/typedecl-hash-skip-aliascache-bits branch May 30, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants