fix(lang): resolve policy field references for lowering#336
Merged
Conversation
A `policy` is tracked in the symbol table before the policies are analyzed, so the stored copy keeps unresolved field expressions. Lowering resolves a policy through that symbol-table entry, so a `hash`/`ref` that references an env var (or any symbol) failed with `MissingAnalyzePhase` — only literal-field policies worked. Re-track the analyzed policy definitions into the scope after `policies.analyze()`, mirroring the type/alias resolution pass, so the symbol table holds policies with resolved fields. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
df6af7b to
1b11c56
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A
policywhosehash/refreferences anenvvar (or any symbol) parses and analyzes cleanly but fails to lower withMissingAnalyzePhase:Only literal-field policies worked — which is why the ref-backed-policy feature (#332/#333/#335) passed its tests but couldn't be used by a real protocol, where the hash and ref are network-specific and supplied via
env.Root cause
Program::analyzetracks every policy into the symbol table (track_policy_def) before runningself.policies.analyze().track_policy_defstores a clone, so the symbol-table copy keeps its field identifiers unresolved. Lowering resolves a referenced policy through that symbol-table entry (Symbol::PolicyDef), so its field expressions have no attached symbols →MissingAnalyzePhase.Fix
After
policies.analyze(), re-track the analyzed policy definitions into the scope — the same re-track-after-analyze patternresolve_types_and_aliasesalready uses. The symbol table then holds policies with resolved fields. One pass suffices (policy fields reference env/fn/other-policy symbols already in scope; no fixpoint needed).Test
policy_def_fields_resolved_in_symbol_table(in theanalyzingmodule) analyzes a program with an env-backed policyP, resolvesPfrom the program scope, and asserts the storedPolicyDef::is_resolved()— i.e. the symbol-table copy has resolved fields. Verified it fails without the fix and passes with it.cargo test -p tx3-lang: 168 passed, 0 failed.This unblocks env-parameterized ref-backed policies (e.g. the GitHoney bounties simplification).
🤖 Generated with Claude Code