mirror of
https://github.com/golang/go
synced 2024-11-26 23:11:24 -07:00
d8e33d558e
- Deal with closures in generic functions by fixing the stenciling code - Deal with instantiated function values (instantiated generic functions that are not immediately called) during stenciling. This requires changing the OFUNCINST node to an ONAME node for the appropriately instantiated function. We do this in a second pass, since this is uncommon, but requires editing the tree at multiple levels. - Check global assignments (as well as functions) for generic function instantiations. - Fix a bug in (*subst).typ where a generic type in a generic function may definitely not use all the type args of the function, so we need to translate the rparams of the type based on the tparams/targs of the function. - Added new test combine.go that tests out closures in generic functions and instantiated function values. - Added one new variant to the settable test. - Enabling inlining functions with closures for -G=3. (For now, set Ntype on closures in -G=3 mode to keep compatibility with later parts of compiler, and allow inlining of functions with closures.) Change-Id: Iea63d5704c322e42e2f750a83adc8b44f911d4ec Reviewed-on: https://go-review.googlesource.com/c/go/+/296269 Reviewed-by: Robert Griesemer <gri@golang.org> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Dan Scales <danscales@google.com>
66 lines
1.6 KiB
Go
66 lines
1.6 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 _Gen[A any] func() (A, bool)
|
|
|
|
func combine[T1, T2, T any](g1 _Gen[T1], g2 _Gen[T2], join func(T1, T2) T) _Gen[T] {
|
|
return func() (T, bool) {
|
|
var t T
|
|
t1, ok := g1()
|
|
if !ok {
|
|
return t, false
|
|
}
|
|
t2, ok := g2()
|
|
if !ok {
|
|
return t, false
|
|
}
|
|
return join(t1, t2), true
|
|
}
|
|
}
|
|
|
|
type _Pair[A, B any] struct {
|
|
A A
|
|
B B
|
|
}
|
|
|
|
func _NewPair[A, B any](a A, b B) _Pair[A, B] {
|
|
return _Pair[A, B]{a, b}
|
|
}
|
|
|
|
func _Combine2[A, B any](ga _Gen[A], gb _Gen[B]) _Gen[_Pair[A, B]] {
|
|
return combine(ga, gb, _NewPair[A, B])
|
|
}
|
|
|
|
func main() {
|
|
var g1 _Gen[int] = func() (int, bool) { return 3, true }
|
|
var g2 _Gen[string] = func() (string, bool) { return "x", false }
|
|
var g3 _Gen[string] = func() (string, bool) { return "y", true }
|
|
|
|
gc := combine(g1, g2, _NewPair[int, string])
|
|
if got, ok := gc(); ok {
|
|
panic(fmt.Sprintf("got %v, %v, wanted -/false", got, ok))
|
|
}
|
|
gc2 := _Combine2(g1, g2)
|
|
if got, ok := gc2(); ok {
|
|
panic(fmt.Sprintf("got %v, %v, wanted -/false", got, ok))
|
|
}
|
|
|
|
gc3 := combine(g1, g3, _NewPair[int, string])
|
|
if got, ok := gc3(); !ok || got.A != 3 || got.B != "y" {
|
|
panic(fmt.Sprintf("got %v, %v, wanted {3, y}, true", got, ok))
|
|
}
|
|
gc4 := _Combine2(g1, g3)
|
|
if got, ok := gc4(); !ok || got.A != 3 || got.B != "y" {
|
|
panic (fmt.Sprintf("got %v, %v, wanted {3, y}, true", got, ok))
|
|
}
|
|
}
|