]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: added a builtins.go test, fixed one bug
authorDan Scales <danscales@google.com>
Tue, 20 Jul 2021 16:37:35 +0000 (09:37 -0700)
committerDan Scales <danscales@google.com>
Wed, 21 Jul 2021 21:25:20 +0000 (21:25 +0000)
The builtins.go test is derived from
cmd/compile/internal/types2/testdata/check/builtins.go2, after removing
the error cases.  Added a few extra tests for len/cap/append.

Fixed one bug, which is that DELETE operations can't be transformed if
their argument is a typeparam. Also, the tranform of LEN/CAP calls does
not need to be delayed. Removed out-date references to the old
typechecker in the comments.

Change-Id: If7a21506a7ff63ff7c8e87ccd614ef4ff3a0d3c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/336010
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>

src/cmd/compile/internal/noder/helpers.go
src/cmd/compile/internal/noder/stencil.go
test/typeparam/builtins.go [new file with mode: 0644]

index b0fb913ee846f28112e01ed2b2deffae9520b98e..7da5aa3102ed5e86f27eda01bef7dff2019c254b 100644 (file)
@@ -126,22 +126,17 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
        }
 
        if fun, ok := fun.(*ir.Name); ok && fun.BuiltinOp != 0 {
-               // For Builtin ops, we currently stay with using the old
-               // typechecker to transform the call to a more specific expression
-               // and possibly use more specific ops. However, for a bunch of the
-               // ops, we delay doing the old typechecker if any of the args have
-               // type params, for a variety of reasons:
+               // For most Builtin ops, we delay doing transformBuiltin if any of the
+               // args have type params, for a variety of reasons:
                //
-               // OMAKE: hard to choose specific ops OMAKESLICE, etc. until arg type is known
-               // OREAL/OIMAG: can't determine type float32/float64 until arg type know
-               // OLEN/OCAP: old typechecker will complain if arg is not obviously a slice/array.
-               // OAPPEND: old typechecker will complain if arg is not obviously slice, etc.
-               //
-               // We will eventually break out the transforming functionality
-               // needed for builtin's, and call it here or during stenciling, as
-               // appropriate.
+               // OMAKE: transformMake can't choose specific ops OMAKESLICE, etc.
+               //    until arg type is known
+               // OREAL/OIMAG: transformRealImag can't determine type float32/float64
+               //    until arg type known
+               // OAPPEND: transformAppend requires that the arg is a slice
+               // ODELETE: transformDelete requires that the arg is a map
                switch fun.BuiltinOp {
-               case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OLEN, ir.OCAP, ir.OAPPEND:
+               case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.ODELETE:
                        hasTParam := false
                        for _, arg := range args {
                                if arg.Type().HasTParam() {
index cff36dd3bf202581c69f52c57723aae45057f188..d1527c5d5c7af7f502439e24d0c5749eea060853 100644 (file)
@@ -1270,7 +1270,7 @@ func (subst *subster) node(n ir.Node) ir.Node {
                                name := call.X.Name()
                                if name.BuiltinOp != ir.OXXX {
                                        switch name.BuiltinOp {
-                                       case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OLEN, ir.OCAP, ir.OAPPEND:
+                                       case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.ODELETE:
                                                // Transform these builtins now that we
                                                // know the type of the args.
                                                m = transformBuiltin(call)
diff --git a/test/typeparam/builtins.go b/test/typeparam/builtins.go
new file mode 100644 (file)
index 0000000..3fe6f79
--- /dev/null
@@ -0,0 +1,114 @@
+// compile -G=3
+
+// Copyright 2020 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.
+
+// This file tests built-in calls on generic types.
+
+// derived and expanded from cmd/compile/internal/types2/testdata/check/builtins.go2
+
+package builtins
+
+// close
+
+type C0 interface{ int }
+type C1 interface{ chan int }
+type C2 interface{ chan int | <-chan int }
+type C3 interface{ chan int | chan float32 }
+type C4 interface{ chan int | chan<- int }
+type C5[T any] interface{ ~chan T | chan<- T }
+
+func _[T C1](ch T) {
+       close(ch)
+}
+
+func _[T C3](ch T) {
+       close(ch)
+}
+
+func _[T C4](ch T) {
+       close(ch)
+}
+
+func _[T C5[X], X any](ch T) {
+       close(ch)
+}
+
+// delete
+
+type M0 interface{ int }
+type M1 interface{ map[string]int }
+type M2 interface { map[string]int | map[string]float64 }
+type M3 interface{ map[string]int | map[rune]int }
+type M4[K comparable, V any] interface{ map[K]V | map[rune]V }
+
+func _[T M1](m T) {
+       delete(m, "foo")
+}
+
+func _[T M2](m T) {
+       delete(m, "foo")
+}
+
+func _[T M4[rune, V], V any](m T) {
+       delete(m, 'k')
+}
+
+// make
+
+type Bmc interface {
+       ~map[rune]string | ~chan int
+}
+
+type Bms interface {
+       ~map[string]int | ~[]int
+}
+
+type Bcs interface {
+       ~chan bool | ~[]float64
+}
+
+type Bss interface {
+       ~[]int | ~[]string
+}
+
+func _[T Bmc]() {
+       _ = make(T)
+       _ = make(T, 10)
+}
+
+func _[T Bms]() {
+       _ = make(T, 10)
+}
+
+func _[T Bcs]() {
+       _ = make(T, 10)
+}
+
+func _[T Bss]() {
+       _ = make(T, 10)
+       _ = make(T, 10, 20)
+}
+
+// len/cap
+
+type Slice[T any] interface {
+       type []T
+}
+
+func _[T any, S Slice[T]]() {
+       x := make(S, 5, 10)
+       _ = len(x)
+       _ = cap(x)
+}
+
+// append
+
+func _[T any, S Slice[T]]() {
+       x := make(S, 5)
+       y := make(S, 2)
+       var z T
+       _ = append(x, y...)
+       _ = append(x, z)
+}