Completes the #1125 fix. The same typed-parameter gap fixed for TS/JS existed
in every other language whose localReceiverTypePatterns only matched
keyword-anchored locals (let/var/:=/= new) and never the bare parameter form:
- Rust: the `:`-annotation pattern required `let`, so `fn use(lg: &Logger)`
didn't match. Dropped the `let` anchor (still covers `let lg: Logger`),
keeping the `&?mut?` handling — now covers params and closures `|lg: T|`.
- Go: only `lg := T{}` / `var lg T` matched; a parameter/method-receiver
`func use(lg Logger)` / `func (l Logger) M()` (name-before-type, no keyword)
didn't. Added a PascalCase-guarded `ident Type` pattern — the guard plus the
existing enclosing-scope bound (excludes package-level struct fields) keep
the keyword-free shape from matching unrelated pairs.
- Dart: the type-before-name pattern's trailing `[=;]` missed a parameter's
`)`/`,`. Widened to `[=;,)]`, mirroring Java/C#.
- PHP: only `$lg = new T` matched; a typed param `function use(Logger $lg)`
(also `?Logger`, `\App\Logger`, `&$lg`, `catch (E $e)`) didn't. Added a
type-before-$var pattern. Reserved words can't be class names, so the
looser lowercase-allowing capture yields no wrong edges.
Every pattern still relies on resolveMethodOnType validating the inferred type
actually declares the method (no edge on a mis-inference) — the same safety
net the already-covered languages use. Verified with a deterministic probe:
all four now disambiguate two same-named methods via the typed param (Java +
Kotlin as passing controls), full suite green (1930), no regressions.
Adds a parameterized regression test (Rust/Go/Dart/PHP), associating method to
type by qualifiedName so it holds where the method sits outside the type's
line range (Rust impl, Go decl).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>