Resolving type parameter ambiguities
August 2, 2023
First today, one rather mundane sentence from the spec…
Type parameter declarations
…
Just as each ordinary function parameter has a parameter type, each type parameter has a corresponding (meta-)type which is called its type constraint.
Followed by a bit of WTF…
A parsing ambiguity arises when the type parameter list for a generic type declares a single type parameter P with a constraint C such that the text P C forms a valid expression:
type T[P *C] … type T[P (C)] … type T[P *C|Q] … …
If you’re up for it, I’ll try to break this thing down. If you’re not up for it, no worries. See you tomorrow! 👋😆
Let’s consider the first example provided: type T[P *C] …
. How can this be ambiguous?
Well, it looks like an array type declaration, where the array length is derrived from a constant expression, such as in this example:
const P = 3
const C = 4
type T [P * C]int // T is of type [12]int
Other expressions are possible, too, which is what leads to this possible ambiguity.
So, we need a way to solve this WTF scenario, and Go gives us two of them…
In these rare cases, the type parameter list is indistinguishable from an expression and the type declaration is parsed as an array type declaration. To resolve the ambiguity, embed the constraint in an interface or use a trailing comma:
type T[P interface{*C}] … type T[P *C,] …
So either wrap your constraint in interface{…}
, or add a magical comma at the end. Poof! problem solved.
But still. WTF?!
Quotes from The Go Programming Language Specification Version of December 15, 2022