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

cmd/compile: permit multiple blank type parameters (fix export data) #50481

Open
findleyr opened this issue Jan 6, 2022 · 9 comments
Open

cmd/compile: permit multiple blank type parameters (fix export data) #50481

findleyr opened this issue Jan 6, 2022 · 9 comments
Assignees
Milestone

Comments

@findleyr
Copy link
Contributor

@findleyr findleyr commented Jan 6, 2022

While investigating #50419, I observed a problem with the way we're indexing type parameters in export data. Consider the following type declaration:

type T[P A, _ B, _ C] int

Because we index type parameters along with other declarations in the package export data, we assign a unique name to them by prefixing with the name of the parameterized declaration, in this case, for example, "T.P" is the type parameter constrained by A. However, this schema has no way to distinguish the type parameter constrained by B and the type parameter constrained by C: both would be indexed by "T._".

Currently, our exporters are not failing, but rather choosing one of the blank type parameters to index.

Given the care required for changes to the export data, it is probably too late to fix this. Maybe we could change the indexed name for blank type parameters to something like "<prefix>.$<index>", so that the blank type parameters in the example above would be indexed as "T.$1" and "T.$2", but even that seems risky at this point.

This is unfortunate, but also should not be a significant problem for our users, since blank type parameters can always be given names. Discussing with @griesemer, we think that for Go 1.18 we should note this limitation and make it a type checking error to have multiple blank type parameters in a type or function declaration, or perhaps an error to have ANY blank names for type parameters.

Note that this limitation should NOT apply to receiver type parameters: func (T[_, _, _]) m() should be fine. EDIT: I spoke too soon: see #50481 (comment)

At some point, perhaps 1.19, we plan to increment the export data version again for the unified export data format. At that point we can lift this restriction.

CC @danscales @griesemer @mdempsky @ianlancetaylor

@findleyr findleyr changed the title cmd/compile: multiple blank type parameters cannot be encoded in export data cmd/compile: multiple blank type parameters cannot be indexed in export data Jan 6, 2022
@findleyr findleyr added this to the Go1.18 milestone Jan 6, 2022
@gopherbot
Copy link

@gopherbot gopherbot commented Jan 6, 2022

Change https://golang.org/cl/376058 mentions this issue: go/types, types2: disallow multiple blank type parameters

@griesemer
Copy link
Contributor

@griesemer griesemer commented Jan 6, 2022

If we accept CL 376058 then this issue can be retitled accordingly and moved to 1.19 where we should remove the restriction introduced by this CL.

gopherbot pushed a commit that referenced this issue Jan 7, 2022
Work-around for #50481: report an error for multiple
blank type parameters. It's always possible to use
non-blank names in those cases.

We expect to lift this restriction for 1.19.

For #50481.

Change-Id: Ifdd2d91340aac1da3387f7d80d46e44f5997c2a8
Reviewed-on: https://go-review.googlesource.com/c/go/+/376058
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Dan Scales <danscales@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
@griesemer griesemer changed the title cmd/compile: multiple blank type parameters cannot be indexed in export data cmd/compile: permit multiple blank type parameters (fix export data) Jan 7, 2022
@griesemer griesemer removed this from the Go1.18 milestone Jan 7, 2022
@griesemer griesemer added this to the Go1.19 milestone Jan 7, 2022
@griesemer
Copy link
Contributor

@griesemer griesemer commented Jan 7, 2022

cc: @mdempsky (for consideration when working on 1.19 export data)

@gopherbot
Copy link

@gopherbot gopherbot commented Jan 7, 2022

Change https://golang.org/cl/376216 mentions this issue: test/typeparam: adjust test preamble (fix longtests)

gopherbot pushed a commit that referenced this issue Jan 7, 2022
For #50481.

Change-Id: I27e6c6499d6abfea6e215d8aedbdd5074ff88291
Reviewed-on: https://go-review.googlesource.com/c/go/+/376216
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jan 7, 2022

If we're imposing this restriction for 1.18 be sure to note it in the release notes in the list under "The current generics implementation has the following limitations:" Thanks.

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Jan 10, 2022

FWIW, unified IR indexes type parameters by ordinal index, not by name.

I'm interested if we have a test case that fails under the current scheme though. Because blank type parameters can't be referenced. Is the issue that the type parameters end up with the wrong constraints due to non-unique indexing?

The other quick fix is to rename blank type parameters like we do blank and anonymous (value) parameters to ~rN and ~bN.

@findleyr
Copy link
Contributor Author

@findleyr findleyr commented Jan 11, 2022

I'm interested if we have a test case that fails under the current scheme though. Because blank type parameters can't be referenced. Is the issue that the type parameters end up with the wrong constraints due to non-unique indexing?

Before the change to disallow this, it was possible to import a type parameter with incorrect constraint (only one constraint could be recorded for _). This could result in explicit instantiations that either succeed or fail where they shouldn't.

@gopherbot
Copy link

@gopherbot gopherbot commented Jan 14, 2022

Change https://golang.org/cl/378580 mentions this issue: go/internal/gcimporter: ensure the correct constraint for blank rparams

@findleyr
Copy link
Contributor Author

@findleyr findleyr commented Jan 15, 2022

Unfortunately, it's not actually trivial to support multiple blanks on method receivers. The reason being that we need to substitute receiver type parameters in their constraints, as in the example below, and there is no such API exposed by the type checker:

type T[P any, _ *P] int

func (T[R, _]) m() {}

In this example, the constraint on the second receiver type parameter should be *R.

Therefore, even though we may have an associated constraint for receiver type parameters, there is no way to make this constraint consistent with the rest of the declaration. This may not matter much in practice, but it's incorrect.

It appears we need to either disallow multiple blanks in receiver type expressions, which would be annoying, or revisit whether or not to change the export data format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants