go/test/typeparam/issue50642.go
Dan Scales c1296af151 cmd/compile: add early a CONVIFACE normally created in the order phase
Most CONVIFACEs are created in the transform phase (or old typechecker,
in -G=0 mode). But if the main result of a multi-value assignment (map,
channel, or dot-type) must be converted to an interface during the
assignment, that CONVIFACE is not created until (*orderState).as2ok in
the order phase (because the AS2* ops and their sub-ops are so tightly
intertwined). But we need to create the CONVIFACE during the
stenciling/transform phase to enable dictionary lookups. So, in
transformAssign(), if we are doing a special multi-value assignment
involving a type-param-derived type, assign the results first to temps,
so that we can manifest the CONVIFACE during the transform in assigning
the first temp to lhs[0].

Added a test for both AS2RECV (channel receives) and AS2MAPR (maps). I
don't think we can have a type assertion on a type-param-derived type.

Fixes #50642

Change-Id: I4d079fc46c93d8494d7db4ea8234d91522edb02a
Reviewed-on: https://go-review.googlesource.com/c/go/+/379054
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-01-19 21:14:18 +00:00

64 lines
1 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
import "fmt"
type Temp[T any] struct {
}
var temp, temp1 any
var ch any
func (it Temp[T]) HasNext() bool {
var ok bool
temp1 = <-ch.(chan T)
// test conversion of T to interface{} during an OAS2RECV
temp, ok = <-ch.(chan T)
return ok
}
type MyInt int
func (i MyInt) String() string {
return "a"
}
type Stringer interface {
String() string
}
type Temp2[T Stringer] struct {
}
var temp2 Stringer
func (it Temp2[T]) HasNext() string {
var x map[int]T
var ok bool
// test conversion of T to Stringer during an OAS2MAPR
temp2, ok = x[43]
_ = ok
return temp2.String()
}
func main() {
ch1 := make(chan int, 2)
ch1 <- 5
ch1 <- 6
ch = ch1
iter := Temp[int]{}
iter.HasNext()
iter2 := Temp2[MyInt]{}
if got, want := iter2.HasNext(), "a"; got != want {
panic(fmt.Sprintf("got %v, want %v", got, want))
}
}