]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: fix make with type parameter argument
authorRobert Findley <rfindley@google.com>
Mon, 16 Aug 2021 01:20:10 +0000 (21:20 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 16 Aug 2021 14:26:45 +0000 (14:26 +0000)
This is a port of CL 339899 to go/types. A test assertion is adjusted
to place the 'not enough arguments' error on the ')'.

Change-Id: Ia13eccc66586f9b84a8b99d462bb406d363a3288
Reviewed-on: https://go-review.googlesource.com/c/go/+/342434
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/builtins.go
src/go/types/testdata/check/builtins.go2

index 4ace1303a7c92856ac7419207e8a16f87593b041..ecf6568f80875cd321aa761b66652adc0c0d1a36 100644 (file)
@@ -481,39 +481,21 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                        return
                }
 
-               min, max := -1, 10
-               var valid func(t Type) bool
-               valid = func(t Type) bool {
-                       var m int
-                       switch t := under(t).(type) {
-                       case *Slice:
-                               m = 2
-                       case *Map, *Chan:
-                               m = 1
-                       case *TypeParam:
-                               return t.underIs(valid)
-                       default:
-                               return false
-                       }
-                       if m > min {
-                               min = m
-                       }
-                       if m+1 < max {
-                               max = m + 1
-                       }
-                       return true
-               }
-
-               if !valid(T) {
+               var min int // minimum number of arguments
+               switch optype(T).(type) {
+               case *Slice:
+                       min = 2
+               case *Map, *Chan:
+                       min = 1
+               case *top:
+                       check.invalidArg(arg0, _InvalidMake, "cannot make %s; type parameter has no structural type", arg0)
+                       return
+               default:
                        check.invalidArg(arg0, _InvalidMake, "cannot make %s; type must be slice, map, or channel", arg0)
                        return
                }
-               if nargs < min || max < nargs {
-                       if min == max {
-                               check.errorf(call, _WrongArgCount, "%v expects %d arguments; found %d", call, min, nargs)
-                       } else {
-                               check.errorf(call, _WrongArgCount, "%v expects %d or %d arguments; found %d", call, min, max, nargs)
-                       }
+               if nargs < min || min+1 < nargs {
+                       check.invalidOp(call, _WrongArgCount, "%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
                        return
                }
 
index 3881090603ebcc0831bef61756bd6e836aa88ab5..1c773cc70b17e741b1ac71882d3d80f9b977c0ef 100644 (file)
@@ -84,50 +84,41 @@ func _[T M4[K, V], K comparable, V any](m T) {
 
 // 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 any]() {
-       _ = make(T /* ERROR invalid argument */)
-       _ = make(T /* ERROR invalid argument */, 10)
-       _ = make(T /* ERROR invalid argument */, 10, 20)
-}
-
-func _[T Bmc]() {
-       _ = make(T)
-       _ = make(T, 10)
-       _ = make /* ERROR expects 1 or 2 arguments */ (T, 10, 20)
-}
-
-func _[T Bms]() {
-       _ = make /* ERROR expects 2 arguments */ (T)
-       _ = make(T, 10)
-       _ = make /* ERROR expects 2 arguments */ (T, 10, 20)
-}
-
-func _[T Bcs]() {
-       _ = make /* ERROR expects 2 arguments */ (T)
-       _ = make(T, 10)
-       _ = make /* ERROR expects 2 arguments */ (T, 10, 20)
-}
-
-func _[T Bss]() {
-       _ = make /* ERROR expects 2 or 3 arguments */ (T)
-       _ = make(T, 10)
-       _ = make(T, 10, 20)
+func _[
+       S1 interface{ []int },
+       S2 interface{ []int | chan int },
+
+       M1 interface{ map[string]int },
+       M2 interface{ map[string]int | chan int },
+
+       C1 interface{ chan int },
+       C2 interface{ chan int | chan string },
+]() {
+       type S0 []int
+       _ = make([]int, 10)
+       _ = make(S0, 10)
+       _ = make(S1, 10)
+       _ = make() /* ERROR not enough arguments */
+       _ = make /* ERROR expects 2 or 3 arguments */ (S1)
+       _ = make(S1, 10, 20)
+       _ = make /* ERROR expects 2 or 3 arguments */ (S1, 10, 20, 30)
+       _ = make(S2 /* ERROR cannot make .* no structural type */ , 10)
+
+       type M0 map[string]int
+       _ = make(map[string]int)
+       _ = make(M0)
+       _ = make(M1)
+       _ = make(M1, 10)
+       _ = make/* ERROR expects 1 or 2 arguments */(M1, 10, 20)
+       _ = make(M2 /* ERROR cannot make .* no structural type */ )
+
+       type C0 chan int
+       _ = make(chan int)
+       _ = make(C0)
+       _ = make(C1)
+       _ = make(C1, 10)
+       _ = make/* ERROR expects 1 or 2 arguments */(C1, 10, 20)
+       _ = make(C2 /* ERROR cannot make .* no structural type */ )
 }
 
 // unsafe.Alignof