]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: report better error messages for make calls
authorRobert Griesemer <gri@golang.org>
Sat, 8 Mar 2025 00:00:53 +0000 (16:00 -0800)
committerGopher Robot <gobot@golang.org>
Tue, 11 Mar 2025 12:45:04 +0000 (05:45 -0700)
Change-Id: I4593aeb4cad1e2c3f4705ed5249ac0bad910162f
Reviewed-on: https://go-review.googlesource.com/c/go/+/655518
Auto-Submit: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/builtins.go
src/go/types/builtins.go
src/internal/types/testdata/check/builtins1.go

index 3b61a68b8b4bfa12fcd56a74acfc9054ea989306..fe46b4e997562e4a4b09f5861b88d421b62df726 100644 (file)
@@ -518,18 +518,30 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                        return
                }
 
+               u, err := commonUnder(T, func(_, u Type) *typeError {
+                       switch u.(type) {
+                       case *Slice, *Map, *Chan:
+                               return nil // ok
+                       case nil:
+                               return typeErrorf("no specific type")
+                       default:
+                               return typeErrorf("type must be slice, map, or channel")
+                       }
+               })
+               if err != nil {
+                       check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s: %s", arg0, err.format(check))
+                       return
+               }
+
                var min int // minimum number of arguments
-               switch u, _ := commonUnder(T, nil); u.(type) {
+               switch u.(type) {
                case *Slice:
                        min = 2
                case *Map, *Chan:
                        min = 1
-               case nil:
-                       check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s: no common underlying type", arg0)
-                       return
                default:
-                       check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
-                       return
+                       // any other type was excluded above
+                       panic("unreachable")
                }
                if nargs < min || min+1 < nargs {
                        check.errorf(call, WrongArgCount, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
index dc87954eb6e89c9ed70cc705f75a1f9f97beb74b..d190212e05a3222fce3998d6d3b577bda4c8bea7 100644 (file)
@@ -521,18 +521,30 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                        return
                }
 
+               u, err := commonUnder(T, func(_, u Type) *typeError {
+                       switch u.(type) {
+                       case *Slice, *Map, *Chan:
+                               return nil // ok
+                       case nil:
+                               return typeErrorf("no specific type")
+                       default:
+                               return typeErrorf("type must be slice, map, or channel")
+                       }
+               })
+               if err != nil {
+                       check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s: %s", arg0, err.format(check))
+                       return
+               }
+
                var min int // minimum number of arguments
-               switch u, _ := commonUnder(T, nil); u.(type) {
+               switch u.(type) {
                case *Slice:
                        min = 2
                case *Map, *Chan:
                        min = 1
-               case nil:
-                       check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s: no common underlying type", arg0)
-                       return
                default:
-                       check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
-                       return
+                       // any other type was excluded above
+                       panic("unreachable")
                }
                if nargs < min || min+1 < nargs {
                        check.errorf(call, WrongArgCount, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
index 25610c1379a591252cb35401b7ec1d262654c04f..422a5462d1c66b6fe06a96f0d281e59f5125e843 100644 (file)
@@ -145,6 +145,9 @@ func _[T M4[K, V], K comparable, V any](m T) {
 type myChan chan int
 
 func _[
+       A1 ~[10]byte,
+       A2 ~[]byte | ~[10]byte,
+
        S1 ~[]int,
        S2 ~[]int | ~chan int,
 
@@ -157,6 +160,11 @@ func _[
        C4 chan int | chan<- int, // channels may have different (non-conflicting) directions
        C5 <-chan int | chan<- int,
 ]() {
+       type A0 [10]byte
+       _ = make([ /* ERROR "cannot make [10]byte: type must be slice, map, or channel" */ 10]byte)
+       _ = make(A1 /* ERROR "cannot make A1: type must be slice, map, or channel" */ )
+       _ = make(A2 /* ERROR "cannot make A2: type must be slice, map, or channel" */ )
+
        type S0 []int
        _ = make([]int, 10)
        _ = make(S0, 10)
@@ -165,7 +173,7 @@ func _[
        _ = 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 S2: no common underlying type" */ , 10)
+       _ = make(S2 /* ERROR "cannot make S2: []int and chan int have different underlying types" */ , 10)
 
        type M0 map[string]int
        _ = make(map[string]int)
@@ -173,7 +181,7 @@ func _[
        _ = make(M1)
        _ = make(M1, 10)
        _ = make/* ERROR "expects 1 or 2 arguments" */(M1, 10, 20)
-       _ = make(M2 /* ERROR "cannot make M2: no common underlying type" */ )
+       _ = make(M2 /* ERROR "cannot make M2: map[string]int and chan int have different underlying types" */ )
 
        type C0 chan int
        _ = make(chan int)
@@ -181,10 +189,10 @@ func _[
        _ = make(C1)
        _ = make(C1, 10)
        _ = make/* ERROR "expects 1 or 2 arguments" */(C1, 10, 20)
-       _ = make(C2 /* ERROR "cannot make C2: no common underlying type" */ )
+       _ = make(C2 /* ERROR "cannot make C2: channels chan int and chan string have different element types" */ )
        _ = make(C3)
        _ = make(C4)
-       _ = make(C5 /* ERROR "cannot make C5: no common underlying type" */ )
+       _ = make(C5 /* ERROR "cannot make C5: channels <-chan int and chan<- int have conflicting directions" */ )
 }
 
 // max