Receiver-binding phantom: a read of pkg.digest binds a same-named pub field in another crate, and localising the receiver does not move it #270
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
h-dv/code-index#270
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while dogfooding during I066 (#269 follow-up). Not blocking that branch — it was worked around — but the defect is live on master.
What happened
crates/indexer/tests/manifest_layering.rsrefuses a RESOLVED edge across a crate boundary Cargo does not declare. It went red on a new test file incrates/cli/tests/because areadofpkg.digestresolved toStaged::digest, apubfield incrates/plugin-host/tests/support/pkg.rs.crates/clidoes not depend oncrates/plugin-host. The bind is a phantom.Why it is a receiver-binding defect and not a name collision
Two measurements make that specific:
digestis ambiguous" — the resolver got it right at some sites and wrong at another.let pin = pkg.digest.clone();produced the same phantom. If the receiver's type were being carried through the local, the bind would have followed it.That points at tier-1R receiver resolution rather than at the bare-name pools.
Why it matters beyond one test
The gate that caught this exists to refuse cross-crate resolved edges, so in this instance the tree was protected. The general case is not: a
read/member_accessthat binds to a same-named field in an unrelated crate is a wrong answer thatfind_referencesandchange_impactwill repeat with no signal, andmanifest_layeringonly sees it when the two crates have no declared edge. Two crates that do have an edge would hide it entirely.Repro shape
pubfield named<name>on a struct in crate A's test support;receiver.<name>in crate B, in a file where other reads of the same expression bind correctly.Workaround applied on the I066 branch
Fixture::digestrenamed topackage_digest, which is also the honest vocabulary — it is whatplugin packprints and what the distribution catalog calls it. The measurement is recorded on the field's doc so the rename is not read as cosmetic.Suggested first step
Reproduce on master with a minimal fixture, then inspect the binds rather than the counts — diff
(path, line, col, kind, occurrence)against the prior binary and split byresolved_by, since position alone fans out. If the wrong bind is attributed to a tier-1R rule, the question is which evidence admitted a receiver whose type is not in scope.Filed by the I066 distribution-truth work; the gate that caught it is
crates/indexer/tests/manifest_layering.rs.