diff options
| author | Robert Griesemer <gri@golang.org> | 2022-02-09 12:02:10 -0800 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2022-02-09 21:52:21 +0000 |
| commit | 2e2ef31778800856d9db87ad06cc963ef2530eeb (patch) | |
| tree | 2783c55e42acf42cff233a136007af1033d2b550 /src | |
| parent | 9867262dfd9b1ba2f212c24dbf26758f81d7cd58 (diff) | |
| download | go-2e2ef31778800856d9db87ad06cc963ef2530eeb.tar.xz | |
go/types, types2: better error messages for append
For #49735.
Change-Id: Ib7343061dca0e8d848e0719d39be0393d7cfad93
Reviewed-on: https://go-review.googlesource.com/c/go/+/384615
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/types2/builtins.go | 16 | ||||
| -rw-r--r-- | src/cmd/compile/internal/types2/testdata/check/builtins.src | 8 | ||||
| -rw-r--r-- | src/cmd/compile/internal/types2/testdata/fixedbugs/issue49735.go2 | 11 | ||||
| -rw-r--r-- | src/go/types/builtins.go | 16 | ||||
| -rw-r--r-- | src/go/types/testdata/check/builtins.src | 8 | ||||
| -rw-r--r-- | src/go/types/testdata/fixedbugs/issue49735.go2 | 11 |
6 files changed, 60 insertions, 10 deletions
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go index f9db07fdea..4b122bc540 100644 --- a/src/cmd/compile/internal/types2/builtins.go +++ b/src/cmd/compile/internal/types2/builtins.go @@ -85,7 +85,21 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) ( if s, _ := structuralType(S).(*Slice); s != nil { T = s.elem } else { - check.errorf(x, invalidArg+"%s is not a slice", x) + var cause string + switch { + case x.isNil(): + cause = "have untyped nil" + case isTypeParam(S): + if u := structuralType(S); u != nil { + cause = check.sprintf("%s has structural type %s", x, u) + } else { + cause = check.sprintf("%s has no structural type", x) + } + default: + cause = check.sprintf("have %s", x) + } + // don't use invalidArg prefix here as it would repeat "argument" in the error message + check.errorf(x, "first argument to append must be a slice; %s", cause) return } diff --git a/src/cmd/compile/internal/types2/testdata/check/builtins.src b/src/cmd/compile/internal/types2/testdata/check/builtins.src index de27f5c632..358e9c5c0d 100644 --- a/src/cmd/compile/internal/types2/testdata/check/builtins.src +++ b/src/cmd/compile/internal/types2/testdata/check/builtins.src @@ -15,9 +15,9 @@ func append1() { var x int var s []byte _ = append() // ERROR not enough arguments - _ = append("foo" /* ERROR not a slice */ ) - _ = append(nil /* ERROR not a slice */ , s) - _ = append(x /* ERROR not a slice */ , s) + _ = append("foo" /* ERROR must be a slice */ ) + _ = append(nil /* ERROR must be a slice */ , s) + _ = append(x /* ERROR must be a slice */ , s) _ = append(s) _ = append(s, nil...) append /* ERROR not used */ (s) @@ -77,7 +77,7 @@ func append3() { _ = append(f2()) _ = append(f3()) _ = append(f5()) - _ = append(ff /* ERROR not a slice */ ()) // TODO(gri) better error message + _ = append(ff /* ERROR must be a slice */ ()) // TODO(gri) better error message } func cap1() { diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49735.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49735.go2 new file mode 100644 index 0000000000..10e8df2776 --- /dev/null +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49735.go2 @@ -0,0 +1,11 @@ +// Copyright 2022 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. + +package p + +func _[P1 any, P2 ~byte](s1 P1, s2 P2) { + _ = append(nil /* ERROR first argument to append must be a slice; have untyped nil */ , 0) + _ = append(s1 /* ERROR s1 .* has no structural type */ , 0) + _ = append(s2 /* ERROR s2 .* has structural type byte */ , 0) +} diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go index 8fcfcb935f..b421b38753 100644 --- a/src/go/types/builtins.go +++ b/src/go/types/builtins.go @@ -86,7 +86,21 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b if s, _ := structuralType(S).(*Slice); s != nil { T = s.elem } else { - check.invalidArg(x, _InvalidAppend, "%s is not a slice", x) + var cause string + switch { + case x.isNil(): + cause = "have untyped nil" + case isTypeParam(S): + if u := structuralType(S); u != nil { + cause = check.sprintf("%s has structural type %s", x, u) + } else { + cause = check.sprintf("%s has no structural type", x) + } + default: + cause = check.sprintf("have %s", x) + } + // don't use Checker.invalidArg here as it would repeat "argument" in the error message + check.errorf(x, _InvalidAppend, "first argument to append must be a slice; %s", cause) return } diff --git a/src/go/types/testdata/check/builtins.src b/src/go/types/testdata/check/builtins.src index 7fd6a4b032..8a4c207a05 100644 --- a/src/go/types/testdata/check/builtins.src +++ b/src/go/types/testdata/check/builtins.src @@ -15,9 +15,9 @@ func append1() { var x int var s []byte _ = append() // ERROR not enough arguments - _ = append("foo" /* ERROR not a slice */ ) - _ = append(nil /* ERROR not a slice */ , s) - _ = append(x /* ERROR not a slice */ , s) + _ = append("foo" /* ERROR must be a slice */ ) + _ = append(nil /* ERROR must be a slice */ , s) + _ = append(x /* ERROR must be a slice */ , s) _ = append(s) _ = append(s, nil...) append /* ERROR not used */ (s) @@ -77,7 +77,7 @@ func append3() { _ = append(f2()) _ = append(f3()) _ = append(f5()) - _ = append(ff /* ERROR not a slice */ ()) // TODO(gri) better error message + _ = append(ff /* ERROR must be a slice */ ()) // TODO(gri) better error message } func cap1() { diff --git a/src/go/types/testdata/fixedbugs/issue49735.go2 b/src/go/types/testdata/fixedbugs/issue49735.go2 new file mode 100644 index 0000000000..10e8df2776 --- /dev/null +++ b/src/go/types/testdata/fixedbugs/issue49735.go2 @@ -0,0 +1,11 @@ +// Copyright 2022 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. + +package p + +func _[P1 any, P2 ~byte](s1 P1, s2 P2) { + _ = append(nil /* ERROR first argument to append must be a slice; have untyped nil */ , 0) + _ = append(s1 /* ERROR s1 .* has no structural type */ , 0) + _ = append(s2 /* ERROR s2 .* has structural type byte */ , 0) +} |
