diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index e49702c04c..2bc1756b8d 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -610,21 +610,16 @@ func (g *irgen) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMeth // number of instantiations we have to generate. You can actually have a mix // of shape and non-shape arguments, because of inferred or explicitly // specified concrete type args. - var s1 []*types.Type + s1 := make([]*types.Type, len(shapes)) for i, t := range shapes { if !t.IsShape() { - if s1 == nil { - s1 = make([]*types.Type, len(shapes)) - copy(s1[0:i], shapes[0:i]) - } s1[i] = typecheck.Shapify(t, i) - } else if s1 != nil { - s1[i] = shapes[i] + } else { + // Already a shape, but make sure it has the correct index. + s1[i] = typecheck.Shapify(shapes[i].Underlying(), i) } } - if s1 != nil { - shapes = s1 - } + shapes = s1 sym := typecheck.MakeFuncInstSym(nameNode.Sym(), shapes, false, isMeth) info := g.instInfoMap[sym] diff --git a/test/typeparam/issue48645a.go b/test/typeparam/issue48645a.go new file mode 100644 index 0000000000..8d5aac94c6 --- /dev/null +++ b/test/typeparam/issue48645a.go @@ -0,0 +1,31 @@ +// 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" + "reflect" +) + +type Stream[T any] struct { +} + +func (s Stream[T]) DropWhile() Stream[T] { + return Pipe[T, T](s) +} + +func Pipe[T, R any](s Stream[T]) Stream[R] { + it := func(fn func(R) bool) { + } + fmt.Println(reflect.TypeOf(it).String()) + return Stream[R]{} +} + +func main() { + s := Stream[int]{} + s = s.DropWhile() +} diff --git a/test/typeparam/issue48645a.out b/test/typeparam/issue48645a.out new file mode 100644 index 0000000000..5093d0f0ff --- /dev/null +++ b/test/typeparam/issue48645a.out @@ -0,0 +1 @@ +func(func(int) bool) diff --git a/test/typeparam/issue48645b.go b/test/typeparam/issue48645b.go new file mode 100644 index 0000000000..0f3a7f230a --- /dev/null +++ b/test/typeparam/issue48645b.go @@ -0,0 +1,81 @@ +// 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 + +type Iterator[T any] interface { + Iterate(fn func(T) bool) +} + +type IteratorFunc[T any] func(fn func(T) bool) + +func (f IteratorFunc[T]) Iterate(fn func(T) bool) { + f(fn) +} + +type Stream[T any] struct { + it Iterator[T] +} + +func (s Stream[T]) Iterate(fn func(T) bool) { + if s.it == nil { + return + } + s.it.Iterate(fn) +} + +func FromIterator[T any](it Iterator[T]) Stream[T] { + return Stream[T]{it: it} +} + +func (s Stream[T]) DropWhile(fn func(T) bool) Stream[T] { + return Pipe[T, T](s, func(t T) (T, bool) { + return t, true + }) +} + +func Pipe[T, R any](s Stream[T], op func(d T) (R, bool)) Stream[R] { + it := func(fn func(R) bool) { + // XXX Not getting the closure right when converting to interface. + // s.it.Iterate(func(t T) bool { + // r, ok := op(t) + // if !ok { + // return true + // } + + // return fn(r) + // }) + } + + return FromIterator[R](IteratorFunc[R](it)) +} + +func Reduce[T, U any](s Stream[T], identity U, acc func(U, T) U) (r U) { + r = identity + s.Iterate(func(t T) bool { + r = acc(r, t) + return true + }) + + return r +} + +type myIterator struct { +} + +func (myIterator) Iterate(fn func(int) bool) { +} + +func main() { + s := Stream[int]{} + s.it = myIterator{} + s = s.DropWhile(func(i int) bool { + return false + }) + Reduce(s, nil, func(acc []int, e int) []int { + return append(acc, e) + }) +}