diff options
| author | Robert Griesemer <gri@golang.org> | 2025-03-07 16:00:53 -0800 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2025-03-11 05:45:04 -0700 |
| commit | a588c6fba6d411245d72b9e071eedc3b4d00a0c8 (patch) | |
| tree | c73d7e81366f76d53fa7cd0ce953f32f7bf43937 /src | |
| parent | ae4c13afc51d81e9aefdfb101e895bc7318c05cd (diff) | |
| download | go-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>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/types2/builtins.go | 24 | ||||
| -rw-r--r-- | src/go/types/builtins.go | 24 | ||||
| -rw-r--r-- | src/internal/types/testdata/check/builtins1.go | 16 |
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 |
