-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: inconsistent handling of untyped expressions #13061
Comments
@mdempsky It is definitively intentional - untyped constants are given their "inferred" type so that a backend - which needs to materialize the constants - knows of what type and size a constant is. My guess would have been - for the example above - that the types would be int, untyped int, *nil, and untyped nil, but I need to look into the logic again. I suspect the reason for the inconsistency is that nil is not considered a constant and thus perhaps is handled in a different code path. |
I'd think the backend could determine the needed type and size for materializing the constants some other way (e.g., looking at the type of the variable they're being assigned to)? But at least if |
I took a stab at this, but discovered the trivial fix (just don't propagate types to explicit conversion arguments) causes a regression on this test case in test/fixedbugs/bug193.go, because it no longer detects the expected errors:
I'm actually rather surprised to find out the above is not valid Go (whereas
Hrm. |
@mdempsky yes, shifts are tricky business . i'll take care of this (let me know if this is blocking you) |
Nope, not blocking me. I was just interested in better understanding the problem. |
Investigate and decide what to do. |
Ping Robert. You'd labeled this Go 1.9. |
I think this can be safely bumped to 1.10. Nothing changed during 1.9 with respect to this issue. |
The reason for the inconsistent behavior is that
Removing the special case for According to the comment, it's important to record the There may be a solution, still. Leaving open for now. |
It does seem reasonable to record the untyped type for values that are explicitly converted. So we should definitively fix this. |
CL 283872 is addressing this partly for For any other untyped operand we do report the "context type" though, which is different from the behavior for nil. This is necessary (at the moment) to make shifts behave correctly, e.g. It may make sense to always report the context type for any untyped value (even untyped nils). cc: @mdempsky |
Change https://golang.org/cl/284052 mentions this issue: |
… type as "untyped nil" This fixes an inconsistency where the type for nil in code such as var x unsafe.Pointer = nil and in conversions of the form T(nil) (where T is a pointer, function, slice, map, channel, interface, or unsafe.Pointer) was reported as (converted to) the respective type. For all other operations that accept a nil value, we don't do this conversion for nil. (We never change the type of the untyped nil value, in contrast to other untyped values where we give the values context-specific types.) It may still be useful to change this behavior and - consistently - report a converted nil type like we do for any other type, but for now this CL simply fixes the existing inconsistency. Added tests and fixed existing test harness. Updates #13061. Change-Id: Ia82832845c096e3cbc4a239ba3d6c8b9a9d274c9 Reviewed-on: https://go-review.googlesource.com/c/go/+/284052 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
Change https://golang.org/cl/289715 mentions this issue: |
This is a port of CL 284052 to go/types. The port is not entirely faithful, as untyped conversion has been refactored in go/types. Additionally, a comment was added to reference issue #13061 in the implicitType method. For #13061 Change-Id: Iec17611f6432c988624023d1d74121ff34eb0c83 Reviewed-on: https://go-review.googlesource.com/c/go/+/289715 Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Robert Findley <rfindley@google.com> Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
Currently if you type check this code with go/types:
both
0
expressions will have type "int", whereas the firstnil
expression will have type "untyped nil", and the second will have type "*int". This seems at the least inconsistent. See http://play.golang.org/p/cw8Ldz1U5DMy expectation was that the
0
s would type check as "untyped int" and thenil
s would type check as "untyped nil". The current behavior of rewriting the type of untyped expressions seems to have two negative consequences that I've noticed trying to use go/types:T(x)
wherex
is already of typeT
. Expressions likeint(0)
will trigger as false positives.types.TypeAndValue.IsNil
to return false for thenil
subexpression in(*int)(nil)
, because it doesn't have the type "untyped nil" anymore.It also seems inconsistent with conversions of already typed expressions, where they're not rewritten.
However, I notice api_test.go has a bunch of tests that seem to explicitly test for this behavior, so it seems intentional?
CC @griesemer
The text was updated successfully, but these errors were encountered: