What it means. A method is declared on a type alias that does not resolve to a plain type this package declares — a built-in, a type from another package, an unnamed composite (slice, map, func) or an instantiated type — or on any generic alias (type Box[T any] Cell[T]), which Go gives no methods whatever it names. type X Y is an alias, not a new type: X and Y are one type, so the method would belong to Y, and Go permits methods only on types its own package declares.
package main
type DateTime int64
func (d DateTime) Millis() int64 = int64(d)
func main() {
Println(DateTime(5).Millis())
}
error[GALA-E0048]: cannot declare a method on "DateTime": it resolves to the built-in type int64
--> main.gala:5:6
|
5 | func (d DateTime) Millis() int64 = int64(d)
| ^ a type alias is the same type as its target, so it takes no…
|
= hint: a type alias is the same type as its target, so it takes no methods of its own — declare `opaque type DateTime int64` for a distinct type with methods, or write the method as a plain function
Declare an opaque type, which gives the value an identity of its own and somewhere for the methods to live, and keeps its operators and its encoding:
opaque type DateTime int64
func (d DateTime) Millis() int64 = int64(d)
A JSON or YAML codec writes an opaque type as the bare value, exactly as it wrote the alias, so documents already written still decode. The opaque type is distinct, though: an int64 no longer passes for a DateTime without DateTime(n) (GALA-E0064) — see Opaque Types. A plain function keeps the alias:
type DateTime int64
func millisOf(d DateTime) int64 = int64(d)
A non-generic alias whose chain passes through no generic alias and ends at a plain type declared in this package is a legal receiver, because the base type is then local:
struct Point(X int, Y int)
type Coord Point
func (c Coord) Sum() int = c.X + c.Y
Everything else an alias does is unaffected — annotating a type, converting (Millis(v)), and constructing through an alias to a struct (Coord(1, 2)). Declaration order does not matter: a method written above its own alias is caught too.
The declaration used to be emitted unchecked, so the rejection arrived from go build against generated code — cannot define new methods on non-local type DateTime — naming a Go rule for a type the author declared in GALA, and only at build time, after a clean transpile.