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: failure to reject interface{}(nil) == []int(nil)
#28164
Comments
It seems to me that this is a bug in go/types: In 2), the left operand is of type interface{} and an []int is assignable to that, so one requirement is satisfied. The assignability is due to the fact that the left operand is an (empty) interface type and []int implements it. I'm not seeing an implicit conversion here. So we have a comparison between an interface and an []int, and []int's are not comparable against interfaces (only nil). |
That is to say, I don't see the spec issue, but maybe I am missing something. |
Sorry for not elaborating further in my initial post. I admit the Go spec strictly only says that the comparison operands must be assignable, but I think the implementations all understand that to mean the assignable operand is implicitly converted to other's type. Consider If we assume there's no implicit bool-to-interface conversion, then this is a comparison between an interface value and a boolean value. The spec says when two interface values are equal and when two boolean values are equal, but not when an interface value and a boolean value are equal. By the same logic, I reason that |
Go spec says:
and
So, I looks it is a problem of which of the above rules has a higher priority. |
Marked for 1.12 but not urgent. This has been like this for a while. |
We've rejected this code literally forever. I don't see the point to starting to accept it when we know it's a malformed test. It seems like we should fix go/types. Fine to clear up the spec language of course, but it seems like everyone (the compiler authors, and gri above) agrees that what we meant was to reject it. |
There are three parts of the spec to consider.
This statement is not an "if and only if", it simply states a "barrier" or sorts to be able to be comparable. The operands must be assignable but that does not mean that all assignable pairs are comparable.
This states that they are comparable if X is comparable and X implements T. X is a slice in this case, so this is fine.
This says slice, map, and function values are not comparable to anything except the identifier The spec is 100% correct with what it says. However, it may be good to make it more clear given that this issue was created and there was a bit of debate as to what the spec said. EDIT - Did not see that this already has NeedsFix, my bad. |
@deanveloper Thanks for pointing out the rule for comparing mixed interface and non-interface types. I completely missed that. I withdraw my arguments that there's an implicit conversion, and I agree that go/types is erroneous in accepting example 2. |
interface{}(nil) == []int(nil)
Change https://golang.org/cl/143277 mentions this issue: |
cmd/compile, gccgo, and go/types all accept 1.
However, only go/types accepts 2. cmd/compile and gccgo reject 2 because []int is not comparable (except directly against nil).
/cc @griesemer
The text was updated successfully, but these errors were encountered: