Files
codegraph/__tests__
Colby MchenryandClaude Opus 5.5 f76021db22 fix(rust): a local holding a method call's value has the type the method returns (#2716)
A Rust local bound to a method call (`let server = b.port(80).build()`,
`let s = cfg.load()?`, `let conn = c.connect().await`, `if let Some(c) =
arg.get::<Completer>()`) had no type the typed receiver path could read,
so calls on it fell to the name strategies. Those strategies did not read
`?` on a returned `Result`, a `self` method's value or a turbofish, and
picked a same-named method of another type.

The value is now the return type of the method the call reaches on its
receiver's type, read from that method's signature. A receiver is a local,
`self`, or another such call. `.await` hands out an `async fn`'s return
type (read off the source: the extractor's async flag is never set for
Rust) or an `impl Future`'s `Output`, and an `async fn` not awaited is a
future, left unread. A method's own type parameter is the call's turbofish
argument. A parameter the call doesn't write stays opaque: `Standard<W>`
is a `Standard`, but a value that is `W` itself is unread rather than its
bound. A trait's provided method returning `Self` gives the receiver's
own type.

A type with two impls of one trait, `Encoder<Bytes>` and `Encoder<&[u8]>`
or `Service<IncomingStream>` and `Service<Request<B>>`, was ambiguous for
a typed call. The impl whose trait argument is the call's first
argument's type now wins.

A/B with fresh indexes against main on axum, serde, ripgrep, clap, dioxus,
tokio and gleam, every changed edge triaged: 536 calls linked that were
not, 69 removed (calls on std or dependency values a method returns, and
tokio values whose read and write methods come from macro-declared
extension traits), 50 moved to the declared type's method, 565 kept at a
higher confidence. gin, serilog, flask and express are byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 19:41:15 +00:00
..