Skip to content

Commit

Permalink
Convert types when registering generic functions/closures
Browse files Browse the repository at this point in the history
  • Loading branch information
chriso committed Dec 13, 2023
1 parent 84565b3 commit 3219aea
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 15 deletions.
26 changes: 23 additions & 3 deletions compiler/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,25 @@ func collectFunctypes(p *packages.Package, name string, fn ast.Node, scope *func
if fields != nil {
for _, field := range fields.List {
for _, name := range field.Names {
typ := p.TypesInfo.TypeOf(name)
if g != nil {
if instanceType, ok := g.typeOfParam(typ); ok {
typ = instanceType
}
}
if typ != nil {
_, ellipsis := field.Type.(*ast.Ellipsis)
field.Type = typeExpr(p, typ)
if a, ok := field.Type.(*ast.ArrayType); ok && a.Len == nil && ellipsis {
field.Type = &ast.Ellipsis{Elt: a.Elt}
}
}
scope.insert(name, field.Type)
}
}
}
}
signature.TypeParams = nil

var inspect func(ast.Node) bool
inspect = func(node ast.Node) bool {
Expand All @@ -110,11 +124,17 @@ func collectFunctypes(p *packages.Package, name string, fn ast.Node, scope *func
switch s := spec.(type) {
case *ast.ValueSpec:
for _, name := range s.Names {
typ := s.Type
typ := p.TypesInfo.TypeOf(name)
if g != nil {
if instanceType, ok := g.typeOfParam(typ); ok {
typ = instanceType
}
}
if typ == nil {
typ = typeExpr(p, p.TypesInfo.TypeOf(name))
scope.insert(name, s.Type)
} else {
scope.insert(name, typeExpr(p, typ))
}
scope.insert(name, typ)
}
}
}
Expand Down
63 changes: 51 additions & 12 deletions compiler/testdata/coroutine_durable.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ package testdata

import (
coroutine "github.com/stealthrocket/coroutine"
unsafe "unsafe"
time "time"
unsafe "unsafe"
)
import _types "github.com/stealthrocket/coroutine/types"

func SomeFunctionThatShouldExistInTheCompiledFile() {
}

//go:noinline
func Identity(n int) { coroutine.Yield[int, any](n) }

//go:noinline
func SquareGenerator(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -48,6 +50,7 @@ func SquareGenerator(_fn0 int) {
}
}
}

//go:noinline
func SquareGeneratorTwice(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -78,6 +81,7 @@ func SquareGeneratorTwice(_fn0 int) {
SquareGenerator(_f0.X0)
}
}

//go:noinline
func SquareGeneratorTwiceLoop(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -113,6 +117,7 @@ func SquareGeneratorTwiceLoop(_fn0 int) {
}
}
}

//go:noinline
func EvenSquareGenerator(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -160,6 +165,7 @@ func EvenSquareGenerator(_fn0 int) {
}
}
}

//go:noinline
func NestedLoops(_fn0 int) (_ int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -241,6 +247,7 @@ func NestedLoops(_fn0 int) (_ int) {
}
panic("unreachable")
}

//go:noinline
func FizzBuzzIfGenerator(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -301,6 +308,7 @@ func FizzBuzzIfGenerator(_fn0 int) {
}
}
}

//go:noinline
func FizzBuzzSwitchGenerator(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -385,6 +393,7 @@ func FizzBuzzSwitchGenerator(_fn0 int) {
}
}
}

//go:noinline
func Shadowing(_ int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -727,6 +736,7 @@ func Shadowing(_ int) {
coroutine.Yield[int, any](_f0.X22)
}
}

//go:noinline
func RangeSliceIndexGenerator(_ int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -769,6 +779,7 @@ func RangeSliceIndexGenerator(_ int) {
}
}
}

//go:noinline
func RangeArrayIndexValueGenerator(_ int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -825,6 +836,7 @@ func RangeArrayIndexValueGenerator(_ int) {
}
}
}

//go:noinline
func TypeSwitchingGenerator(_ int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -899,6 +911,7 @@ func TypeSwitchingGenerator(_ int) {
}
}
}

//go:noinline
func LoopBreakAndContinue(_ int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -1053,6 +1066,7 @@ func LoopBreakAndContinue(_ int) {
}
}
}

//go:noinline
func RangeOverMaps(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -1387,6 +1401,7 @@ func RangeOverMaps(_fn0 int) {
}
}
}

//go:noinline
func Range(_fn0 int, _fn1 func(int)) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -1425,13 +1440,15 @@ func Range(_fn0 int, _fn1 func(int)) {
}
}
}

//go:noinline
func Double(n int) { coroutine.Yield[int, any](2 * n) }

//go:noinline
func RangeTriple(n int) {
Range(n, func(i int) { coroutine.Yield[int, any](3 * i) },
)
Range(n, func(i int) { coroutine.Yield[int, any](3 * i) })
}

//go:noinline
func RangeTripleFuncValue(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -1466,6 +1483,7 @@ func RangeTripleFuncValue(_fn0 int) {
Range(_f0.X0, _f0.X1)
}
}

//go:noinline
func RangeReverseClosureCaptureByValue(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -1515,6 +1533,7 @@ func RangeReverseClosureCaptureByValue(_fn0 int) {
}
}
}

//go:noinline
func Range10ClosureCapturingValues() {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -1621,6 +1640,7 @@ func Range10ClosureCapturingValues() {
}
}
}

//go:noinline
func Range10ClosureCapturingPointers() {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -1737,6 +1757,7 @@ func Range10ClosureCapturingPointers() {
}
}
}

//go:noinline
func Range10ClosureHeterogenousCapture() {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -1956,6 +1977,7 @@ func Range10ClosureHeterogenousCapture() {
}
}
}

//go:noinline
func Range10Heterogenous() {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -2067,6 +2089,7 @@ func Range10Heterogenous() {
}
}
}

//go:noinline
func Select(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -2361,6 +2384,7 @@ func Select(_fn0 int) {
}
}
}

//go:noinline
func YieldingExpressionDesugaring() {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -2783,6 +2807,7 @@ func YieldingExpressionDesugaring() {
}
}
}

//go:noinline
func a(_fn0 int) (_ int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -2814,6 +2839,7 @@ func a(_fn0 int) (_ int) {
}
panic("unreachable")
}

//go:noinline
func b(_fn0 int) (_ int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -2845,6 +2871,7 @@ func b(_fn0 int) (_ int) {
}
panic("unreachable")
}

//go:noinline
func YieldingDurations() {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -2952,6 +2979,7 @@ func YieldingDurations() {
}
}
}

//go:noinline
func YieldAndDeferAssign(_fn0 *int, _fn1, _fn2 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -2996,6 +3024,7 @@ func YieldAndDeferAssign(_fn0 *int, _fn1, _fn2 int) {
coroutine.Yield[int, any](_f0.X1)
}
}

//go:noinline
func RangeYieldAndDeferAssign(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -3033,6 +3062,7 @@ func RangeYieldAndDeferAssign(_fn0 int) {
}

type MethodGeneratorState struct{ i int }

//go:noinline
func (_fn0 *MethodGeneratorState) MethodGenerator(_fn1 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -3069,6 +3099,7 @@ func (_fn0 *MethodGeneratorState) MethodGenerator(_fn1 int) {
}
}
}

//go:noinline
func VarArgs(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -3108,6 +3139,7 @@ func VarArgs(_fn0 int) {
varArgs(_f0.X1...)
}
}

//go:noinline
func varArgs(_fn0 ...int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -3164,6 +3196,7 @@ func varArgs(_fn0 ...int) {
}
}
}

//go:noinline
func ReturnNamedValue() (_fn0 int) {
_c := coroutine.LoadContext[int, any]()
Expand Down Expand Up @@ -3203,21 +3236,26 @@ func ReturnNamedValue() (_fn0 int) {
}
panic("unreachable")
}

//go:noinline
func IdentityGeneric[T any](n T) { coroutine.Yield[T, any](n) }
func IdentityGeneric(n int) { coroutine.Yield[T, any](n) }

Check failure on line 3241 in compiler/testdata/coroutine_durable.go

View workflow job for this annotation

GitHub Actions / Test

undefined: T

type IdentityGenericStruct[T any] struct {
n T
}

//go:noinline
func (i *IdentityGenericStruct[T]) Run() { coroutine.Yield[T, any](i.n) }

//go:noinline
func IdentityGenericInt(n int) { IdentityGeneric[int](n) }

Check failure on line 3251 in compiler/testdata/coroutine_durable.go

View workflow job for this annotation

GitHub Actions / Test

invalid operation: cannot index IdentityGeneric (value of type func(n int))

//go:noinline
func IdentityGenericStructInt(n int) { (&IdentityGenericStruct[int]{n: n}).Run() }

//go:noinline
func IdentityGenericClosure[T any](_fn0 T) {
_c := coroutine.LoadContext[T, any]()
func IdentityGenericClosure(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
var _f0 *struct {
IP int
X0 T

Check failure on line 3261 in compiler/testdata/coroutine_durable.go

View workflow job for this annotation

GitHub Actions / Test

undefined: T
Expand Down Expand Up @@ -3256,11 +3294,12 @@ func IdentityGenericClosure[T any](_fn0 T) {
// TODO: add this go:noinline directive automatically
//
//go:noinline
func buildClosure[T any](n T) func() {
func buildClosure(n T) func() {

Check failure on line 3297 in compiler/testdata/coroutine_durable.go

View workflow job for this annotation

GitHub Actions / Test

undefined: T
return func() {
coroutine.Yield[T, any](n)

Check failure on line 3299 in compiler/testdata/coroutine_durable.go

View workflow job for this annotation

GitHub Actions / Test

undefined: T
}
}

//go:noinline
func IdentityGenericClosureInt(n int) { IdentityGenericClosure[int](n) }

Check failure on line 3304 in compiler/testdata/coroutine_durable.go

View workflow job for this annotation

GitHub Actions / Test

invalid operation: cannot index IdentityGenericClosure (value of type func(_fn0 int))
func init() {
Expand All @@ -3271,10 +3310,10 @@ func init() {
_types.RegisterFunc[func(_fn0 int)]("github.com/stealthrocket/coroutine/compiler/testdata.FizzBuzzSwitchGenerator")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.Identity")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericClosureInt")
_types.RegisterFunc[func[T any](_fn0 T)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericClosure[go.shape.int]")
_types.RegisterFunc[func(_fn0 int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericClosure[go.shape.int]")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericInt")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericStructInt")
_types.RegisterFunc[func[T any](n T)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGeneric[go.shape.int]")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGeneric[go.shape.int]")
_types.RegisterFunc[func(_ int)]("github.com/stealthrocket/coroutine/compiler/testdata.LoopBreakAndContinue")
_types.RegisterFunc[func(_fn1 int)]("github.com/stealthrocket/coroutine/compiler/testdata.MethodGenerator")
_types.RegisterFunc[func(_fn0 int) (_ int)]("github.com/stealthrocket/coroutine/compiler/testdata.NestedLoops")
Expand Down Expand Up @@ -3399,12 +3438,12 @@ func init() {
_types.RegisterFunc[func()]("github.com/stealthrocket/coroutine/compiler/testdata.YieldingExpressionDesugaring")
_types.RegisterFunc[func(_fn0 int) (_ int)]("github.com/stealthrocket/coroutine/compiler/testdata.a")
_types.RegisterFunc[func(_fn0 int) (_ int)]("github.com/stealthrocket/coroutine/compiler/testdata.b")
_types.RegisterFunc[func[T any](n T) func()]("github.com/stealthrocket/coroutine/compiler/testdata.buildClosure[go.shape.int]")
_types.RegisterFunc[func(n T) func()]("github.com/stealthrocket/coroutine/compiler/testdata.buildClosure[go.shape.int]")

Check failure on line 3441 in compiler/testdata/coroutine_durable.go

View workflow job for this annotation

GitHub Actions / Test

undefined: T
_types.RegisterClosure[func(), struct {
F uintptr
X0 T
X0 int
}]("github.com/stealthrocket/coroutine/compiler/testdata.buildClosure[go.shape.int].func1")
_types.RegisterFunc[func[T any](n T) func()]("github.com/stealthrocket/coroutine/compiler/testdata.buildClosure[go.shape.interface{}]")
_types.RegisterFunc[func(n T) func()]("github.com/stealthrocket/coroutine/compiler/testdata.buildClosure[go.shape.interface{}]")

Check failure on line 3446 in compiler/testdata/coroutine_durable.go

View workflow job for this annotation

GitHub Actions / Test

undefined: T
_types.RegisterClosure[func(), struct {
F uintptr
X0 T
Expand Down

0 comments on commit 3219aea

Please sign in to comment.