fix(rust): the toolchain's children are told where the toolchain is - #9
Merged
CesarManzoCode merged 1 commit intoSep 5, 2026
Merged
Conversation
The VM closed the previous cause: inside Thalyx, `cargo 1.90.0 from: thalyx`
and `rust-analyzer 1.90.0 from: thalyx`. And the machine still could not
resolve a name. `context('lantern/src/lib.rs')` found `LanternRegistry`;
`context('LanternRegistry')` answered `resolution: nothing, entries: []`, and
a rename at the identifier's own physical position — 8:12, not the outline's
guess — answered `No references found at position`.
Reproduced here with an environment holding exactly what Thalyx hands over and
nothing else, and the cause is in the server's own log:
ERROR FetchWorkspaceError: rust-analyzer failed to load workspace:
Failed to run `cargo metadata …`: No such file or directory (os error 2)
WARN failed to get rustc cfgs e=unable to fetch cfgs via `… "rustc" …`
Caused by: No such file or directory (os error 2)
rust-analyzer is not a program Thalyx runs; it is a program that runs
programs. It spells `cargo metadata`, `cargo locate-project`, `cargo --version`
and `rustc --print cfg` as bare names, which the kernel resolves through PATH
and nothing else — and Thalyx, which finds every tool by absolute path and goes
on doing so, had never given its children one. With no crate graph there is no
semantics; syntax survives because syntax needs no subprocess, which is exactly
the shape the machine showed.
The change is one variable. `toolchain::environment` now hands a managed
toolchain a PATH built by Thalyx out of one directory, its own `bin`: nothing
inherited, no /usr/bin, no ~/.cargo, no ~/.rustup. Measured — adding it and
nothing else turned workspace/symbol, definition and rename from empty to
correct in the same fixture. CARGO, RUSTC and RUST_SRC_PATH are deliberately
not set: PATH alone was sufficient, and a variable added because Rust usually
has it is a variable nobody can remove later. An installed toolchain gets its
`bin` in front of the inherited PATH rather than instead of it, which is also
what sudo's secure_path had been costing verify.sh.
Two instrument defects came with it, and both were worse than the bug.
`dev/verify-agent-rust.sh` printed `PROVEN context('LanternRegistry') came from
rust-analyzer` about `{source: "rust-analyzer", resolution: "nothing",
entries: []}`. `source` says who answered; it has never said that the answer
resolved anything. PROVEN now needs all three: rust-analyzer answered,
resolution is `one`, and the entries carry exactly the declaration asked about,
with the handle a rename would take.
And the control written to demonstrate the defect resolved the symbol anyway.
rust-analyzer looks for cargo in three places — $CARGO, PATH, $CARGO_HOME/bin —
and a rustup machine has the third one full. Inside Thalyx CARGO_HOME is
<store>/state/cargo and has no bin, so the control was modelling a developer's
laptop rather than the guest. It models the guest now.
Separately, the outline placed a documented struct at its doc comment: with
`hierarchicalDocumentSymbolSupport: false` each entry carries one range and
rust-analyzer fills it with the whole item, so `LanternRegistry` came back at
3:1 instead of 8:12. The hierarchical answer carries `selectionRange`, which is
the identifier. Not the blocker — 8:12 failed too — but a position a rename by
handle would have used. The server's real answer is captured verbatim in
tests/samples/document-symbol-hierarchical.json, rule 6.
Proven in the container, with env_clear and only Thalyx's pairs, over
dev/rust-corpus: without PATH the outline finds the struct and every name
resolves to nothing; with it, Resolution::One at lantern/src/lib.rs:8:12, uses
in the other crate, and a real rename across two files. And the chain below —
`cargo` invoked as a bare name with an empty environment compiles the workspace,
so it found its rustc the same way.
Confinement is untouched on purpose. The VM reported analyzer_confined=false
because the kernel is attached but observing, and the provider fell back to an
ordinary process inside Thalyx and the semantics failed anyway. One cause at a
time.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S4ij9nSjMTiCT6sd8DuBgQ
CesarManzoCode
deleted the
claude/rust-analyzer-semantic-resolution-vneio1
branch
September 5, 2026 03:01
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.
The VM closed the previous cause: inside Thalyx,
cargo 1.90.0 from: thalyxandrust-analyzer 1.90.0 from: thalyx. And the machine still could not resolve a name.context('lantern/src/lib.rs')foundLanternRegistry;context('LanternRegistry')answeredresolution: nothing, entries: [], and a rename at the identifier's own physical position — 8:12, not the outline's guess — answeredNo references found at position.Reproduced here with an environment holding exactly what Thalyx hands over and nothing else, and the cause is in the server's own log:
rust-analyzer is not a program Thalyx runs; it is a program that runs programs. It spells
cargo metadata,cargo locate-project,cargo --versionandrustc --print cfgas bare names, which the kernel resolves through PATH and nothing else — and Thalyx, which finds every tool by absolute path and goes on doing so, had never given its children one. With no crate graph there is no semantics; syntax survives because syntax needs no subprocess, which is exactly the shape the machine showed.The change is one variable.
toolchain::environmentnow hands a managed toolchain a PATH built by Thalyx out of one directory, its ownbin: nothing inherited, no /usr/bin, no ~/.cargo, no ~/.rustup. Measured — adding it and nothing else turned workspace/symbol, definition and rename from empty to correct in the same fixture. CARGO, RUSTC and RUST_SRC_PATH are deliberately not set: PATH alone was sufficient, and a variable added because Rust usually has it is a variable nobody can remove later. An installed toolchain gets itsbinin front of the inherited PATH rather than instead of it, which is also what sudo's secure_path had been costing verify.sh.Two instrument defects came with it, and both were worse than the bug.
dev/verify-agent-rust.shprintedPROVEN context('LanternRegistry') came from rust-analyzerabout{source: "rust-analyzer", resolution: "nothing", entries: []}.sourcesays who answered; it has never said that the answer resolved anything. PROVEN now needs all three: rust-analyzer answered, resolution isone, and the entries carry exactly the declaration asked about, with the handle a rename would take.And the control written to demonstrate the defect resolved the symbol anyway. rust-analyzer looks for cargo in three places — $CARGO, PATH, $CARGO_HOME/bin — and a rustup machine has the third one full. Inside Thalyx CARGO_HOME is /state/cargo and has no bin, so the control was modelling a developer's laptop rather than the guest. It models the guest now.
Separately, the outline placed a documented struct at its doc comment: with
hierarchicalDocumentSymbolSupport: falseeach entry carries one range and rust-analyzer fills it with the whole item, soLanternRegistrycame back at 3:1 instead of 8:12. The hierarchical answer carriesselectionRange, which is the identifier. Not the blocker — 8:12 failed too — but a position a rename by handle would have used. The server's real answer is captured verbatim in tests/samples/document-symbol-hierarchical.json, rule 6.Proven in the container, with env_clear and only Thalyx's pairs, over dev/rust-corpus: without PATH the outline finds the struct and every name resolves to nothing; with it, Resolution::One at lantern/src/lib.rs:8:12, uses in the other crate, and a real rename across two files. And the chain below —
cargoinvoked as a bare name with an empty environment compiles the workspace, so it found its rustc the same way.Confinement is untouched on purpose. The VM reported analyzer_confined=false because the kernel is attached but observing, and the provider fell back to an ordinary process inside Thalyx and the semantics failed anyway. One cause at a time.
Claude-Session: https://claude.ai/code/session_01S4ij9nSjMTiCT6sd8DuBgQ