go/test/typeparam/issue51303.go
Dan Scales eb8198d2f6 cmd/compile: deal with constructed types that have shapes in them
We convert type args to shape types inside instantiations. If an
instantiation constructs a compound type based on that shape type and
uses that as a type arg to another generic function being called, then
we have a type arg with a shape type embedded inside of it. In that
case, we need to substitute out those embedded shape types with their
underlying type.

If we don't do this, we may create extra unneeded shape types that
have these other shape types embedded in them. This may lead to
generating extra shape instantiations, and a mismatch between the
instantiations that we used in generating dictionaries and the
instantations that are actually called.

Updates #51303

Change-Id: Ieef894a5fac176cfd1415f95926086277ad09759
Reviewed-on: https://go-review.googlesource.com/c/go/+/387674
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-02-28 19:38:22 +00:00

66 lines
1.1 KiB
Go

// run -gcflags=-G=3
// Copyright 2022 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"
)
func main() {
x := [][]int{{1}}
y := [][]int{{2, 3}}
IntersectSS(x, y)
}
type list[E any] interface {
~[]E
Equal(x, y E) bool
}
// ss is a set of sets
type ss[E comparable, T []E] []T
func (ss[E, T]) Equal(a, b T) bool {
return SetEq(a, b)
}
func IntersectSS[E comparable](x, y [][]E) [][]E {
return IntersectT[[]E, ss[E, []E]](ss[E, []E](x), ss[E, []E](y))
}
func IntersectT[E any, L list[E]](x, y L) L {
var z L
outer:
for _, xe := range x {
fmt.Println("xe", xe)
for _, ye := range y {
fmt.Println("ye", ye)
fmt.Println("x", x)
if x.Equal(xe, ye) {
fmt.Println("appending")
z = append(z, xe)
continue outer
}
}
}
return z
}
func SetEq[S []E, E comparable](x, y S) bool {
fmt.Println("SetEq", x, y)
outer:
for _, xe := range x {
for _, ye := range y {
if xe == ye {
continue outer
}
}
return false // xs wasn't found in y
}
return true
}