Most generic types are not valid types for composite literals. This isn't a problem though, as there are other ways to create values of generic types.
To create a pointer to a new zero value:
func createThing[T thing]() *T {
return new(T)
}
Or to create a non-pointer zero value:
func createThing[T thing]() T {
var value T
return value
}
As for why the error occurs in this way, here's the explanation from the spec, revised to address your specific question.
For composite literals:
The LiteralType's core type T must be a struct, array, slice, or map type
What is the core type?
An interface T has a core type if [...] there is a single type U which is the underlying type of all types in the type set of T
No other interfaces have a core type.
What is the underlying type?
Each type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T's underlying type is the underlying type of the type to which T refers in its declaration.
A "type literal" can refer to a literal struct type, like struct{int id}
. So, when foo
and bar
both have an underlying type of struct{int id}
, then thing
has a core type of struct{int id}
, and so composite literals are possible. When foo
and bar
don't have the same underlying type, then thing
has no core type, and composite literals are not possible, hence your error.
The formal definition may seem complicated, but the result and practical takeaway is simple: generic code is only capable of expressing common behaviour across the possible types. Besides in the special case where all underlying types are the same, literal values are not a common behaviour.