Repository navigation
fix(go): an implementer's methods must take and return the interface's types - #3185
Merged
Merged
Conversation
…s types goImplementsEdges matched method names and, since PR #2447, parameter and result counts. Go wants the signatures identical, so a type with the right number of the wrong types passed: caddy's TLS matchers, with `Match(*tls.ClientHelloInfo) bool`, "implemented" its HTTP `RequestMatcher`, whose `Match` takes an `*http.Request`, and every HTTP matcher its TLS `ConnectionMatcher`. Each false entry also sent calls through the interface to a method they never reach, and took a place under the per-interface cap. The fix: at the counts that fit, typesFit compares each parameter's and result's type, read off the stored signature (goItemTypes, goComparableType). A type compares by its name with the package left off, since the two declarations may write `Context` and `caddy.Context` from different packages. Nothing is ruled out by a true alias, by a type parameter of the type or of what it embeds, by a `func`/`struct`/`interface` literal type, or by a method a standard-library embedding brings, whose types the table doesn't hold. A gRPC server keeps crossing to its client interface at the server's counts. Validation: - go-implements-types.test.ts: 4 of 9 cases fail on main, all pass. go-promoted-dispatch.test.ts pinned the old behaviour (two series sets implementing each other's interface by name) and now says what Go says. - A/B against main 4499d00, implementers dropped: caddy 24, prometheus 261, etcd 36, hugo 169. A separate judge reads each dropped pair's signatures through embedded types with qualifiers and names removed: 490 of 490 differ. Calls dropped with them: caddy 24, prometheus 636, etcd 36, hugo 98. Added: prometheus 8 implementers and 30 moved dispatch edges, real implementers the false ones had pushed past the cap (`blockSeriesSet`, `seriesSetAdapter`). gin and cobra byte-identical; controls flask and express identical. - REG's 7 false entries on caddy are gone. The 11 real implementers caddy's `Provisioner` and `Unmarshaler` still lose against 1.6.2 are the cap's: both arms keep 40 real ones, of more than 40, in file order. That isn't changed here; raising the cap to 400 adds 239 implementers and 467 edges on caddy. - CPU, median of 3 interleaved: hugo 22.75 to 22.44 s, etcd 21.19 to 22.00 s (wall 7.23 to 7.14 s). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bompus
added a commit
to bompus/codegraph
that referenced
this pull request
Nov 2, 2026
…s types (colbymchenry#3185) Ported from upstream 608487e
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.
goImplementsEdges matched method names and, since PR #2447, parameter and
result counts. Go wants the signatures identical, so a type with the right
number of the wrong types passed: caddy's TLS matchers, with
Match(*tls.ClientHelloInfo) bool, "implemented" its HTTPRequestMatcher,whose
Matchtakes an*http.Request, and every HTTP matcher its TLSConnectionMatcher. Each false entry also sent calls through the interfaceto a method they never reach, and took a place under the per-interface cap.
The fix: at the counts that fit, typesFit compares each parameter's and
result's type, read off the stored signature (goItemTypes,
goComparableType). A type compares by its name with the package left off,
since the two declarations may write
Contextandcaddy.Contextfromdifferent packages. Nothing is ruled out by a true alias, by a type
parameter of the type or of what it embeds, by a
func/struct/interfaceliteral type, or by a method a standard-library embedding brings, whose
types the table doesn't hold. A gRPC server keeps crossing to its client
interface at the server's counts.
Validation:
go-promoted-dispatch.test.ts pinned the old behaviour (two series sets
implementing each other's interface by name) and now says what Go says.
etcd 36, hugo 169. A separate judge reads each dropped pair's signatures
through embedded types with qualifiers and names removed: 490 of 490 differ.
Calls dropped with them: caddy 24, prometheus 636, etcd 36, hugo 98.
Added: prometheus 8 implementers and 30 moved dispatch edges, real
implementers the false ones had pushed past the cap (
blockSeriesSet,seriesSetAdapter). gin and cobra byte-identical; controls flask andexpress identical.
ProvisionerandUnmarshalerstill lose against 1.6.2 are the cap's: botharms keep 40 real ones, of more than 40, in file order. That isn't changed
here; raising the cap to 400 adds 239 implementers and 467 edges on caddy.
(wall 7.23 to 7.14 s).
Suite: 874 files passed, 6 skipped; 10,847 tests passed, 2 expected fail, 87 skipped, with the kernel on Windows, on the stack of these 8 PRs at 00b79ff2 over main 1f188da. The A/B numbers are against 4499d00; the stack on 1f188da is edge for edge the same arm on jsoup, rocksdb's java/, Minestom, okhttp, tokio, caddy, Alamofire, nowinandroid and mihon, and those repos give the same graph on both mains.
🤖 Generated with Claude Code