aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2025-03-07 16:00:53 -0800
committerGopher Robot <gobot@golang.org>2025-03-11 05:45:04 -0700
commita588c6fba6d411245d72b9e071eedc3b4d00a0c8 (patch)
treec73d7e81366f76d53fa7cd0ce953f32f7bf43937
parentae4c13afc51d81e9aefdfb101e895bc7318c05cd (diff)
downloadgo-a588c6fba6d411245d72b9e071eedc3b4d00a0c8.tar.xz
go/types, types2: report better error messages for make calls
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>
-rw-r--r--src/cmd/compile/internal/types2/builtins.go24
-rw-r--r--src/go/types/builtins.go24
-rw-r--r--src/internal/types/testdata/check/builtins1.go16
3 files changed, 48 insertions, 16 deletions
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go
index 3b61a68b8b..fe46b4e997 100644
--- a/src/cmd/compile/internal/types2/builtins.go
+++ b/src/cmd/compile/internal/types2/builtins.go
@@ -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)
diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go
index dc87954eb6..d190212e05 100644
--- a/src/go/types/builtins.go
+++ b/src/go/types/builtins.go
@@ -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)
diff --git a/src/internal/types/testdata/check/builtins1.go b/src/internal/types/testdata/check/builtins1.go
index 25610c1379..422a5462d1 100644
--- a/src/internal/types/testdata/check/builtins1.go
+++ b/src/internal/types/testdata/check/builtins1.go
@@ -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