go/test/typeparam/mdempsky/13.go
Dan Scales 3cdf8b429e [dev.typeparams] cmd/compile: fixing case where type arg is an interface
In this case, we can't use an itab for doing a bound call, since we're
converting from an interface to an interface. We do a static or dynamic
type assert in new function assertToBound().

The dynamic type assert in assertToBound() is only needed if a bound is
parameterized. In that case, we must do a dynamic type assert, and
therefore need a dictionary entry for the type bound (see change in
getGfInfo). I'm not sure if we can somehow limit this case, since using
an interface as a type arg AND having the type bound of the type
arg be parameterized is a very unlikely case.

Had to add the TUNION case to parameterizedBy1() (which is only used for
extra checking).

Added a bunch of these test cases to 13.go, which now passes.

Change-Id: Ic22eed637fa879b5bbb46d36b40aaad6f90b9d01
Reviewed-on: https://go-review.googlesource.com/c/go/+/339898
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2021-08-05 17:33:41 +00:00

85 lines
1.4 KiB
Go

// run -gcflags=-G=3
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// Interface which will be used as a regular interface type and as a type bound.
type Mer interface{
M()
}
// Interface that is a superset of Mer.
type Mer2 interface {
M()
String() string
}
func F[T Mer](t T) {
T.M(t)
t.M()
}
type MyMer int
func (MyMer) M() {}
func (MyMer) String() string {
return "aa"
}
// Parameterized interface
type Abs[T any] interface {
Abs() T
}
func G[T Abs[U], U any](t T) {
T.Abs(t)
t.Abs()
}
type MyInt int
func (m MyInt) Abs() MyInt {
if m < 0 {
return -m
}
return m
}
type Abs2 interface {
Abs() MyInt
}
func main() {
mm := MyMer(3)
ms := struct{ Mer }{Mer: mm }
// Testing F with an interface type arg: Mer and Mer2
F[Mer](mm)
F[Mer2](mm)
F[struct{ Mer }](ms)
F[*struct{ Mer }](&ms)
ms2 := struct { MyMer }{MyMer: mm}
ms3 := struct { *MyMer }{MyMer: &mm}
// Testing F with a concrete type arg
F[MyMer](mm)
F[*MyMer](&mm)
F[struct{ MyMer }](ms2)
F[struct{ *MyMer }](ms3)
F[*struct{ MyMer }](&ms2)
F[*struct{ *MyMer }](&ms3)
// Testing G with a concrete type args
mi := MyInt(-3)
G[MyInt,MyInt](mi)
// Interface Abs[MyInt] holding an mi.
intMi := Abs[MyInt](mi)
// First type arg here is Abs[MyInt], an interface type.
G[Abs[MyInt],MyInt](intMi)
}