// 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 typeparams
import "io"
type SourceReader[Source any] interface {
Read(p Source) (n int, err error)
}
func GenericInterfaceAssertionTest[T io.Reader]() {
var (
a SourceReader[[]byte]
b SourceReader[[]int]
r io.Reader
)
_ = a.(io.Reader)
_ = b.(io.Reader) // want `^impossible type assertion: no type can implement both typeparams.SourceReader\[\[\]int\] and io.Reader \(conflicting types for Read method\)$`
_ = r.(SourceReader[[]byte])
_ = r.(SourceReader[[]int]) // want `^impossible type assertion: no type can implement both io.Reader and typeparams.SourceReader\[\[\]int\] \(conflicting types for Read method\)$`
_ = r.(T) // not actually an iface assertion, so checked by the type checker.
switch a.(type) {
case io.Reader:
default:
}
switch b.(type) {
case io.Reader: // want `^impossible type assertion: no type can implement both typeparams.SourceReader\[\[\]int\] and io.Reader \(conflicting types for Read method\)$`
default:
}
}
// Issue 50658: Check for type parameters in type switches.
type Float interface {
float32 | float64
}
type Doer[F Float] interface {
Do() F
}
func Underlying[F Float](v Doer[F]) string {
switch v.(type) {
case Doer[float32]:
return "float32!"
case Doer[float64]:
return "float64!"
default:
return "<unknown>"
}
}
func DoIf[F Float]() {
// This is a synthetic function to create a non-generic to generic assignment.
// This function does not make much sense.
var v Doer[float32]
if t, ok := v.(Doer[F]); ok {
t.Do()
}
}
func IsASwitch[F Float, U Float](v Doer[F]) bool {
switch v.(type) {
case Doer[U]:
return true
}
return false
}
func IsA[F Float, U Float](v Doer[F]) bool {
_, is := v.(Doer[U])
return is
}
func LayeredTypes[F Float]() {
// This is a synthetic function cover more isParameterized cases.
type T interface {
foo() struct{ _ map[T][2]chan *F }
}
type V interface {
foo() struct{ _ map[T][2]chan *float32 }
}
var t T
var v V
t, _ = v.(T)
_ = t
}
type X[T any] struct{}
func (x X[T]) m(T) {}
func InstancesOfGenericMethods() {
var x interface{ m(string) }
// _ = x.(X[int]) // BAD. Not enabled as it does not type check.
_ = x.(X[string]) // OK
}