Repository navigation
Code Analysis Rust Trait Impls
Validated in Draft, not Labs: #1286, final head 7d228fb5c849c370b09ae2d1a2d315b1c9e01ee4, targets the #1283 source branch codex/code-analysis-labs-integration-review-20261108. No merge, approval, release, installation or labs/code-analysis update. Validation commit 38f82efd2 passed run 42467009838 in full. Final head 7d228fb5c (target-column scoring) passed run 42469411573 on attempt 1 with 19 successful jobs; only the two deploy jobs were skipped.
A maintainer changed one method inside impl Trait for Type. Which calls definitely point to that implementation, which only prove use of the trait method, and which remain unknown?
Rust rust-source-direct-v5 / adapter revision 5 captures local trait declarations and impl-method edges.
-
<Type as Trait>::method(...)and unambiguous concrete receivers resolve to the unique captured impl (rust-trait-impl). -
T: Trait,dyn Trait,Trait::methodand generic paths resolve to the trait method declaration only (rust-trait-method-candidate). - Change questions add
traitCandidateswithruntimeTarget: "not-determined", separate from directknownReferences. - A concrete receiver implementing several same-named traits stays unresolved rather than choosing by name; an inherent method with the same name blocks trait selection.
Expectations were frozen in benchmarks/code-analysis-rust-trait-change/source-first.json before either CLI ran. Profile: rustc/cargo 1.89.0, aarch64-apple-darwin, default features, tests excluded, root module only. Call columns are derived from the frozen source text.
The bytes count is reported under both scopes:
| Project | Change | Definite in call inventory | Definite in source answer | Trait-only candidate | Wrong |
|---|---|---|---|---|---|
tokio-rs/bytes d38faf7→c08f876
|
BytesMut::put body |
2/2 | 2/3 | 0 | 0 |
rust-lang/log 761461a→db14597
|
both KVs::into_kvs impls |
0/0 | 0/0 | 1/1 | 0 |
The source-answer miss is src/buf/buf_impl.rs:2374, a definite call inside a Buf default-method body that the current call inventory does not scan. It is a retained product gap, not a wrong target or a trait-resolution miss.
Each returned result is graded on call range, target declaration file:line:column, owning trait and, when determined, implementation type:
| Result | Call range | Target declaration | Owning trait | Impl type | Status |
|---|---|---|---|---|---|
bytes ret.put(&mut self.a)
|
src/buf/chain.rs:184:13-184:33 |
src/bytes_mut.rs:1300:5 |
BufMut |
BytesMut |
correct |
bytes ret.put((&mut self.b).take(...))
|
src/buf/chain.rs:185:13-185:53 |
src/bytes_mut.rs:1300:5 |
BufMut |
BytesMut |
correct |
log kvs.into_kvs()
|
src/__private_api.rs:101:9-101:23 |
src/__private_api.rs:17:12 |
KVs |
unverified | correct |
Per-call CLI targets expose no end position, so target-end stays unverified for all three rather than being inferred from another record. Baseline 0c81af0e reports 0 known references and no candidate coverage. The log result proves KVs::into_kvs use but not the runtime impl, so its implementation type stays unverified.
Example: BytesMut::put at src/bytes_mut.rs:1300 changed; ret.put(&mut self.a) at src/buf/chain.rs:184 reaches that impl because ret is a local crate::BytesMut.
The log reference-self impl (src/__private_api.rs:25) is head-only because its qualname embeds the changed Key token text; its head traitCandidates still contain src/__private_api.rs:101.
- Fixture: two traits with the same method, two types implementing one trait, explicit qualification,
T: Trait,&dyn Trait, and an ambiguous concrete receiver. - Fixture negative control swaps
<A as Left>::acttoRight::act; scoring must fail on declaration range. The runner exits nonzero otherwise. - Real-result same-named wrong target: replace
src/buf/chain.rs:184's target withsrc/buf/buf_mut.rs:202(BufMut::put). The scorer rejects it withdeclaration-rangeandimplementation-type. - Real-result same-line different call: replace
src/buf/chain.rs:185's range with the nested.take(...)call at185:21-185:52, keeping the target. The scorer rejects it withcall-rangeonly. - Real-result target column only: change
src/buf/chain.rs:184's target column from5to6, keeping call range, target file, line, trait and implementation type fixed. The scorer rejects it withdeclaration-rangeonly. - rust-analyzer
1.89.0Go to Definition: both bytes calls go tosrc/bytes_mut.rs:1300; the log generic call goes to the trait declarationsrc/__private_api.rs:17, not an impl. - Unpacked
archify.zipSHA2565c9687d0fb0fe1ade96defa923e6f7d1c7eb2822d29b12b647b8d9b1d31e35e1reproduces the source run exactly. Rebuilding at38f82efd2with Node 22.23.3 produced the identical hash.
Run 42465518271 at 3a1ac77a first failed in full-regression (2) because the self-bootstrap test's spawnSync hit its 20 s limit (ETIMEDOUT, assertion null !== 0); no byte or schema comparison ran. The same commit passed on rerun, including the downstream test (22) gate. Validation commit 38f82efd2 passed run 42467009838 in full. Intermediate report commit 0e1fe6f4c passed run 42467648337 on attempt 2 after one browser layout flake. Final head 7d228fb5c passed run 42469411573 on attempt 1 with 19 successful jobs. The module-suite timeout cause and the intermediate browser first-attempt cause remain unknown. The failure excerpt is in benchmarks/code-analysis-rust-trait-change/evidence/ci-full-regression-2-attempt1.txt.
Local captured traits only; external, macro-generated, blanket and supertrait impls remain unknown. Receiver typing covers parameters, local let initializers and literal/constructor paths; fields, chained calls and reassigned locals remain unknown. Trait default bodies are outside the call inventory, including src/buf/buf_impl.rs:2374. Same-type same-method impls in different traits share a qualname slot (duplicate-slot) while their head candidates stay inspectable. Source navigation is not compiler, runtime or complete-impact proof.
Reproduction: benchmarks/code-analysis-rust-trait-change/run.py with both pinned sample pairs, the baseline checkout and the source or unpacked ZIP CLI; it reports per-item results, dual bytes scopes and real-result controls. audit.py reproduces the language-server rows. evidence/ holds the normalized run, ZIP, CI and audit summaries.
Decision input: keep improving the built-in Rust source model. Explicit and uniquely typed concrete calls can be separated from trait-only candidates without adopting rust-analyzer as a product dependency.