-
Notifications
You must be signed in to change notification settings - Fork 17.5k
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: type constraint containing any used directly as type #68710
Comments
any
to bypass go's generic checking?
cc @griesemer |
Simple case: https://go.dev/play/p/t8l45ebTndw
It seems that |
I think that |
@mateusz834 Good point, thanks. With a single interface this is clearly an embedded interface. Then the remaining question is with the original example, where |
I think we might want a different definition of type identity for basic interface as opposed to union ones. If we ever end up with union implemented as interfaces this will simplify discrimination. In that sense, the union here should not be usable as a type yet, just like any union we have nowadays. (because crypto.PublicKey is a defined interface type and the union with the slice type creates a full-blown 'union' interface type. That should be relevant when embedding union interface types. Probably a bug. (but something to think over) |
This might make #57644 unintuitive. Consider: type Foo interface {
any | int
}
type Bar interface {
Foo | string
}
func main() {
var _ Bar = struct{}{}
} |
IIUC, this is the right behavior because:
is a Basic Interface. While:
is not, since its type sets can not be defined entirely by a list of methods. |
To add, the clearer semantics would be that Bar accepts either interface values or string values. It's definitely weird to say that, given our current definition of type set and since interfaces have a dynamic type which is never an interface. But, if That's the type identity part.
|
I'll note that any (or rather, empty interfaces) is the only interface this works with. IMO this is pretty clearly a bug.
I don't think the spec is all that clear about whether it is actually a basic interface. It says
Now, on the one hand, the type set of I just can't imagine anyone thinking it is intended for |
type AnyType interface {
any | []uint8
} is equivalent to and automatically simplified by compiler as type AnyType interface {
any
} So, it is a basic interface type. Both spec and implementation have no problems here. |
@zigo101 that's arguable. The interface is defined as a set of methods that is empty AND a union of terms.
So the union might not be simplifiable? |
|
@cuonglm I understand what you mean. But in terms of sets, the union is decomposable in disjoint sets. Otherwise, that would mean that we could consider the type set of the union term {[]uint8} to be empty/uninhabited since all types satisfy [edit] It's perhaps easier to see that it is not true if we replace the interface by a union where each term is a distinct element of the type set: we'd get after simplification: The decomposition in disjoint sets should be preferable. |
One question. So this type AnyType interface {
interface{ /* nothing */ } | []uint8
} Or should be recognized as type AnyType interface {
interface { /* all types */ } | []uint8
} Should this type AnyType interface {
interface{ /* types all or nothing? */ } | []uint8
any // interface type
} |
Just since I don't think this has been stated yet, this is not new behavior -- the behavior described by OP appears to be present in Go 1.21+. |
It has been present since Go 1.18. |
Proposal Details
some issue content about this:
golang-jwt/jwt#401
The defined generic type
AnyType
can be used directly as a type and is compiled.If you delete
any
, you will be prompted withI haven't found anything about it, so I don't know if it's intentional or not.
If so, could you provide some relevant information?
The text was updated successfully, but these errors were encountered: