]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: in typ0(), load base type before checking s.Def
authorDan Scales <danscales@google.com>
Fri, 7 Jan 2022 20:22:24 +0000 (12:22 -0800)
committerDan Scales <danscales@google.com>
Tue, 11 Jan 2022 21:56:11 +0000 (21:56 +0000)
The loading of the base type in typ0() may cause s.Def to be defined for
the instantiated type, so load the base type before checking s.Def.

Fixes #50486

Change-Id: Ic039bc8f774dda534f4ccd1f920220b7a10dede6
Reviewed-on: https://go-review.googlesource.com/c/go/+/377094
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/noder/types.go
test/typeparam/issue50486.dir/goerror_fp.go [new file with mode: 0644]
test/typeparam/issue50486.dir/main.go [new file with mode: 0644]
test/typeparam/issue50486.go [new file with mode: 0644]

index ed816b4955a9419f2a3a4de46cc8dc45e10b9e1c..3f3c9566ca12fd414f050974af9b468d76dce502 100644 (file)
@@ -113,6 +113,15 @@ func (g *irgen) typ0(typ types2.Type) *types.Type {
                        // based on the names of the type arguments.
                        instName := g.instTypeName2(typ.Obj().Name(), typ.TypeArgs())
                        s := g.pkg(typ.Obj().Pkg()).Lookup(instName)
+
+                       // Make sure the base generic type exists in type1 (it may
+                       // not yet if we are referecing an imported generic type, as
+                       // opposed to a generic type declared in this package). Make
+                       // sure to do this lookup before checking s.Def, in case
+                       // s.Def gets defined while importing base (if an imported
+                       // type). (Issue #50486).
+                       base := g.obj(typ.Origin().Obj())
+
                        if s.Def != nil {
                                // We have already encountered this instantiation.
                                // Use the type we previously created, since there
@@ -120,10 +129,6 @@ func (g *irgen) typ0(typ types2.Type) *types.Type {
                                return s.Def.Type()
                        }
 
-                       // Make sure the base generic type exists in type1 (it may
-                       // not yet if we are referecing an imported generic type, as
-                       // opposed to a generic type declared in this package).
-                       base := g.obj(typ.Origin().Obj())
                        if base.Class == ir.PAUTO {
                                // If the base type is a local type, we want to pop
                                // this instantiated type symbol/definition when we
diff --git a/test/typeparam/issue50486.dir/goerror_fp.go b/test/typeparam/issue50486.dir/goerror_fp.go
new file mode 100644 (file)
index 0000000..fec9095
--- /dev/null
@@ -0,0 +1,75 @@
+// 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 goerror_fp
+
+type Seq[T any] []T
+
+func (r Seq[T]) Size() int {
+       return len(r)
+}
+
+func (r Seq[T]) Append(items ...T) Seq[T] {
+       tail := Seq[T](items)
+       ret := make(Seq[T], r.Size()+tail.Size())
+
+       for i := range r {
+               ret[i] = r[i]
+       }
+
+       for i := range tail {
+               ret[i+r.Size()] = tail[i]
+       }
+
+       return ret
+}
+
+func (r Seq[T]) Iterator() Iterator[T] {
+       idx := 0
+
+       return Iterator[T]{
+               IsHasNext: func() bool {
+                       return idx < r.Size()
+               },
+               GetNext: func() T {
+                       ret := r[idx]
+                       idx++
+                       return ret
+               },
+       }
+}
+
+type Iterator[T any] struct {
+       IsHasNext func() bool
+       GetNext   func() T
+}
+
+func (r Iterator[T]) ToSeq() Seq[T] {
+       ret := Seq[T]{}
+       for r.HasNext() {
+               ret = append(ret, r.Next())
+       }
+       return ret
+}
+
+func (r Iterator[T]) Map(f func(T) any) Iterator[any] {
+       return MakeIterator(r.HasNext, func() any {
+               return f(r.Next())
+       })
+}
+
+func (r Iterator[T]) HasNext() bool {
+       return r.IsHasNext()
+}
+
+func (r Iterator[T]) Next() T {
+       return r.GetNext()
+}
+
+func MakeIterator[T any](has func() bool, next func() T) Iterator[T] {
+       return Iterator[T]{
+               IsHasNext: has,
+               GetNext:   next,
+       }
+}
diff --git a/test/typeparam/issue50486.dir/main.go b/test/typeparam/issue50486.dir/main.go
new file mode 100644 (file)
index 0000000..db5f1c3
--- /dev/null
@@ -0,0 +1,16 @@
+package main
+
+import fp "goerror_fp"
+
+func Fold[A, B any](zero B, a A, f func(B, A) B) B {
+       return f(zero, a)
+}
+
+func main() {
+
+       var v any = "hello"
+       Fold(fp.Seq[any]{}, v, func(seq fp.Seq[any], v any) fp.Seq[any] {
+               return seq.Append(v)
+       })
+
+}
diff --git a/test/typeparam/issue50486.go b/test/typeparam/issue50486.go
new file mode 100644 (file)
index 0000000..87b4ff4
--- /dev/null
@@ -0,0 +1,7 @@
+// compiledir -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 ignored