Open12

型パラメータのソースコード読みメモ

lazy union type set computationというものが出てくる(コメントに)
遅延して計算させるということだと思うけど具体的にどういうことかが気になる

プルリクチャンス

https://go-review.googlesource.com/c/go/+/294469/22/doc/go_spec.html#1520

Implementation restriction:
A union expression with more than one term cannot contain interface types
with non-empty method sets.

の記述は不正確である

理由

https://go-review.googlesource.com/c/go/+/294469/22/doc/go_spec.html#854

The method set of an interface type is the intersection of the method sets of each type in the interface's type set (which is usually just the set of declared methods in the interface).

とある。そのため、次のMyIntIFを考えると、float64 | MyIntIFというunionsがillegalになるが、これはlegalになるべきである。

type MyInt int
func(x MyInt) Print() {}

type MyIntIF interface {
  MyInt
}

type SomeIF interface {
  // illegal according to the spec because MyIntIF is an interface type with non-empty method set.
  // but I believe it should be legal.
  MyIntIF | float64 
}

より詳しく述べる。

The method set of an interface type is the intersection of the method sets of each type in the interface's type set

より、MyIntIFのメソッドセットはMyIntIFの型セットに属する型のメソッドセットの共通部分である。また、

  • MyIntIFの型セットは{ MyInt }である
  • MyIntのメソッドセットは{ Print() }である

ので、method_set(MyIntIF) = { Print() }となる。よって、1より大きい数のtermからなるunionsはMyIntIFを含むことができないことになるが、https://github.com/golang/go/issues/45346#issuecomment-862505803 の趣旨から考えればこれは許されるはずである。

go install golang.org/dl/gotip@latest
gotip download dev.typeparams
gotip run -gcflags="-G=3" main.go

According to this line, following definition of IFUnion should not be allowed. But I think this should be allowed:

type MyInt int
func (MyInt) Print() {} // method set of MyInt is { Print() }
type MyIntIF interface {
MyInt
}
type IFUnion interface {
int | MyIntIF
}

According to L851, the method set of MyIntIF is { Print() }, which is not empty.
So IFUnion contains a union with interface type with non-empty method sets, making IFUnion not allowed.
I wonder if this is what this line means.

ログインするとコメントできます