Issue #1060: emit: adding tools/grammar_run.nika makes project_members’ fs::Path maps lose TrustedMap

Open and answer this issue on GitHub.

ready, wip · opened 2026-10-31 · updated 2026-10-31 · 1 comment

What happened

b070adb9 (GR: the parser’s build and run move into Nikaia, Part of #125) added crates/nikaia-std/src/tools/grammar_run.nika. With that file in the tools package, lower-std writes project_members.rs differently, although project_members.nika did not change:

-    let mut seen: collections::TrustedMap<fs::Path, String> = collections::TrustedMap::default();
+    let mut seen: collections::HashMap<fs::Path, String> = collections::HashMap::<_, _>::default();

The same happens for here, renames_in’s parameter type, and at_of in dependencies_first (project_members.nika lines 118, 124, 184, 238, 282, all collections::HashMap[fs::Path, ...]). The committed file was not re-lowered, so three sysroot tests went red on develop (the_committed_rust_is_what_this_compiler_lowers, stds_nikaia_half_lowers_the_same_at_both_switches, the_tools_lower_the_same_on_one_thread_as_on_every_core).

Re-lowering would have locked in a regression: the maps lose the fast hasher that ADR-010 D5/D9 chooses for them. So b070adb9 was reverted in 0fbe3d6b. The GR move lands again together with the fix for this issue.

Bisect: b070adb9^ lowers clean, b070adb9 drifts. The drift persists with a fresh NIKAIA_LOWER_CACHE_SALT, so it is not a cache effect. Reverting ee225513 or 0788a29c alone does not remove it.

Likely cause: the D9 hasher decision runs once the whole package is read. A map whose key is fs::Path is probably unified with a map in grammar_run.nika that crosses the package boundary or feeds an untrusted input. Another possibility is that grammar_run.nika’s host trait (GrammarRunHost, methods returning fs::Path) makes fs::Path-keyed maps count as one type across the package.

To build

  1. Reproduce: apply b070adb9 again on develop and run NIKAIA_LOWER_CACHE_SALT=f$RANDOM NIKAIA_SYSROOT=$PWD/crates target/fast/nikaia lower-std. project_members.rs drifts.
  2. Find which D9 rule demotes the maps, and fix it in the emitter or in check. If the demotion is correct by D9, say why in the report, and get an architect decision before re-lowering.
  3. Add a tests/compiler/ test: two modules, one with a trusted HashMap[fs::Path, T], the other with the construct from grammar_run.nika that triggered the demotion. The first must stay TrustedMap.
  4. Re-land the GR move (b070adb9’s content) on top, re-lowered, with the sysroot tests green.

The gate did not see it (separate fix, same build)

gate.nika --all runs lower-std before the tests. That rewrites the drifted files in the suite worktree, so the sysroot tests passed: the suite at 63b3bf6b was green while CI was red.

  1. gate.nika --all (and --full): first check that the committed lowered files are what this compiler lowers, without writing them (fail the step on drift), and only then run anything that rewrites them. Alternatively, run git diff --exit-code crates/nikaia-std after lower-std and fail on a difference. Update the gate’s dry-run tests.

Comments

keywan-ghadami, 2026-10-31

Briefed for the bug lane as docs/briefs/bugs/b15-1060-trusted-map-name-collision.md (steps 1-3 and 5, Part: #1060). Suspected cause: trust.nika trusted_maps :282-290 adds the last :: segment of every untrusted library function to env.sources, so GrammarRunHost::manifest makes the parameter manifest in project_members_packages_of an untrusted source. Step 4 (GR re-land) returns to the main lane after the fix.


Generated by Claude Code

Back to Open Issues