Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/types, types2: always set the receiver type of interface methods to the defining interface type #49906

Open
griesemer opened this issue Dec 1, 2021 · 9 comments
Assignees
Labels
NeedsInvestigation
Milestone

Comments

@griesemer
Copy link
Contributor

@griesemer griesemer commented Dec 1, 2021

When setting up methods for interfaces, we set the recv to the interface type (its definition if we have one). We are (probably - I don't remember for sure) doing this so we can tell that those Func objects are methods; there may be other reasons. Investigate if this is something we can or might want to change.

See also #49888 and the respective CL which would be affected.

cc: rfindley

@griesemer griesemer added the NeedsInvestigation label Dec 1, 2021
@griesemer griesemer added this to the Backlog milestone Dec 1, 2021
@griesemer griesemer self-assigned this Dec 1, 2021
@mdempsky
Copy link
Member

@mdempsky mdempsky commented Feb 1, 2022

I'd like to suggest that the Func's receiver parameter always points to the types.Interface that represents the underlying interface type literal that declared the method, and never to the types.Named for defined interface types.

For example, I suggest https://go.dev/play/p/weOZB-AO-w2 should print:

func (interface).M()
func (interface).M()
func (interface).M()

rather than

func (p.A).M()
func (p.A).M()
func (interface).M()

like it does currently. I think this would be more consistent and also simplify importers.

@gopherbot
Copy link

@gopherbot gopherbot commented Feb 15, 2022

Change https://go.dev/cl/386003 mentions this issue: go/types: disable TestCheckExpr for unified IR

@gopherbot
Copy link

@gopherbot gopherbot commented Mar 1, 2022

Change https://go.dev/cl/386004 mentions this issue: cmd/compile: switch to final unified IR export format

@griesemer griesemer removed this from the Backlog milestone Mar 29, 2022
@griesemer griesemer added this to the Go1.19 milestone Mar 29, 2022
@griesemer
Copy link
Contributor Author

@griesemer griesemer commented Mar 29, 2022

Marking for Go 1.19 so this stays on the radar.

@griesemer griesemer changed the title go/types, types2: consider not setting the receiver type of interface methods go/types, types2: always set the receiver type of interface methods to the defining interface type Mar 29, 2022
@gopherbot
Copy link

@gopherbot gopherbot commented Mar 29, 2022

Change https://go.dev/cl/396516 mentions this issue: types2: use declaring interface as receiver for interface methods

@griesemer
Copy link
Contributor Author

@griesemer griesemer commented Mar 29, 2022

I am ok with this change. As far as I can tell, it's important to have a non-nil receiver (so we know that we have a method), but for interface methods it doesn't matter whether the receiver is the declaring interface proper or the named type if one was given to the interface. CL 396516 makes the relevant changes in types2.

@findleyr Do you see any problems with tools (backward-compatibility)?

gopherbot pushed a commit that referenced this issue Apr 4, 2022
Now that there's a native go/types importer for unified IR, the
compiler no longer needs to stay backwards compatible with old iexport
importers.

This CL also updates the go/types and go/internal/gcimporter tests to
expect that the unified IR importer sets the receiver parameter type
to the underlying Interface type, rather than the Named type. This is
a temporary workaround until we make a decision on #49906.

Notably, this makes `GOEXPERIMENT=unified go test` work on generics
code without requiring `-vet=off` (because previously cmd/vet was
relying on unified IR's backwards-compatible iexport data, which
omitted generic types).

Change-Id: Iac7a2346bb7a91e6690fb2978fb702fadae5559d
Reviewed-on: https://go-review.googlesource.com/c/go/+/386004
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
@griesemer
Copy link
Contributor Author

@griesemer griesemer commented Apr 5, 2022

We have now pending CL 396516 that implements the suggestion by @mdempsky , but for the failures in the x/tools repo. However, these failures give me pause: it does seem that we are going to lose quite a bit of information that's useful by tools when reporting errors. It's not clear to me that this is a change/simplification worth doing.

@mdempsky mentions that the chance would simplify importers. That's true, and it also simplifies the type checker slightly. But leaving the requirements as is doesn't seem particularly difficult either.

@mdempsky @findleyr for comments.

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Apr 29, 2022

Agreed we shouldn't make this change if it negatively impacts end-user experience. I'd like to take a deeper look at the x/tools failures though, before ruling out this change.

My intuition is the defined receiver type information should still be available via the go/types API, just the consumer code isn't worrying about getting it, because in the common case (e.g., type A interface { M() } from the https://go.dev/play/p/weOZB-AO-w2) it just works already. But for the same reason that the tests are failing for CL 396516, I suspect they'd similarly provide non-ideal end-user results for types B and C.

@griesemer
Copy link
Contributor Author

@griesemer griesemer commented May 17, 2022

Agreed that there are scenarios (https://go.dev/play/p/weOZB-AO-w2) where the reported receiver type is not ideal. The "correct" solution might be to adjust the various tests that are failing.

Postponing for now as this is neither urgent nor a major issue at the moment.

@griesemer griesemer removed this from the Go1.19 milestone May 17, 2022
@griesemer griesemer added this to the Go1.20 milestone May 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation
Projects
None yet
Development

No branches or pull requests

3 participants