-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
spec: type inference should be more lenient about untyped numeric literals #58671
Comments
CC @griesemer |
Given the example above, what should be inferred for We can come up with rules, but it smells like an unnecessary complication. A minor change to a constant value, possibly defined somewhere else, may suddenly change an inferred type. |
If I write I don't know if this diagram will help but: On one hand we have On the other we have I'm asking for |
I don't follow why float32 would be a contender.
Agreed. Assuming int and float64 for func Add(x, y interface{}) {...} because each value could be evaluated in isolation. Now, with type parameters, with the generic Add, the arguments' types are linked, so one must affect the other. It's the same in 1 + 1.2, where the spec requires the operands to have the same type, which is equivalent to the generic function Add. See how Haskell handles apparent mismatched types from different literal kinds in its type checking. |
I thought a bit more about this and I retract my earlier comment. I believe @jimmyfrasche is correct that if two arguments of the same type parameter type get assigned different untyped values, an analogue rule should apply as for a constant operation between these two untyped values. Specifically, the proposal is:
Example: func g[P any](...P) P { var x P; return x }
func _() {
var (
_ int = g(1, 2)
_ rune = g(1, 'a')
_ float64 = g(1, 'a', 2.3)
_ float64 = g('a', 2.3)
_ complex128 = g(2.3, 'a', 1i)
)
g(true, 'a' /* ERROR "mismatched types untyped bool and untyped rune (cannot infer P)" */)
g(1, "foo" /* ERROR "mismatched types untyped int and untyped string (cannot infer P)" */)
g(1, 2.3, "bar" /* ERROR "mismatched types untyped float and untyped string (cannot infer P)" */)
} This is unambiguous, fits nicely with the existing rules for constants (as @jimmyfrasche has pointed out before) and thus feels "natural" for Go. It is fully backward-compatible: existing code will continue to run, and some code that wasn't accepted before is now accepted. It removes possibly annoying type inference errors. As an aside, it is about as complex to implement as what we do now. I believe we should do this. |
Change https://go.dev/cl/492835 mentions this issue: |
I think |
This implements the proposal #58671. Must be explicitly enabled and requires proposal approval. For #58671. Change-Id: I150e78f4f3282d6b7cf9d90feeb5f1c5a36d8c38 Reviewed-on: https://go-review.googlesource.com/c/go/+/492835 Auto-Submit: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Robert Griesemer <gri@google.com>
This proposal has been added to the active column of the proposals project |
Based on the discussion above, this proposal seems like a likely accept. |
Change https://go.dev/cl/495955 mentions this issue: |
Change https://go.dev/cl/496035 mentions this issue: |
This enables the implementation for proposal #58671, which is a likely accept. By enabling it early we get a bit extra soak time for this feature. The change can be reverted trivially, if need be. For #58671. Change-Id: Id6c27515e45ff79f4f1d2fc1706f3f672ccdd1ab Reviewed-on: https://go-review.googlesource.com/c/go/+/495955 Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
…r go1.21 This CL permanently enables the new behavior for -lang=go1.21 and newer, and keeps the existing behavior if -lang=go1.20 or older. To be submitted once #58671 is accepted. For #58671. Change-Id: I83a1d393f0ce7871be8f38ec35742d393946c55f Reviewed-on: https://go-review.googlesource.com/c/go/+/496035 Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com>
No change in consensus, so accepted. 🎉 |
This has been implemented and submitted. Leaving this open to track documentation in the spec. |
Change https://go.dev/cl/499282 mentions this issue: |
For #39661. For #41176. For #51593. For #52397. For #57192. For #58645. For #58650. For #58671. For #59338. For #59750. For #60353. Change-Id: Ib731c9f2879beb541f44cb10e40c36a8677d3ad4 Reviewed-on: https://go-review.googlesource.com/c/go/+/499282 TryBot-Bypass: Robert Griesemer <gri@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Robert Griesemer <gri@google.com>
Change https://go.dev/cl/499997 mentions this issue: |
…ling in inference For #58671. Fixes #60566. Change-Id: I746f99cdfd44b204dc90350fcfb3867e9b8b1da8 Reviewed-on: https://go-review.googlesource.com/c/go/+/499997 Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This is now described in the new section on type inference in the spec, per CL 503920. |
Forked off #58650 per @ianlancetaylor's request
Currently
assigns
x
the typefloat64
but on the next line reports the errordefault type float64 of 2.5 does not match inferred type int for T
.Go takes the default type based on the literal form before applying type inference so it's the same as writing
Add(int(1), float64(2.5))
.In the special case of multiple untyped numeric literals for a single type parameter, type inference should select the "largest" one provided to use as the default type.
("largest" in the sense that complex128 is larger than float64 is larger than int)
template
Author background
Related proposals
Proposal
1 + 2.5
Show example code before and after the change.
Add(1.0, 2.5)
Add(1, 2.5)
Costs
The text was updated successfully, but these errors were encountered: