]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: better error messages for append
authorRobert Griesemer <gri@golang.org>
Wed, 9 Feb 2022 20:02:10 +0000 (12:02 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 9 Feb 2022 21:52:21 +0000 (21:52 +0000)
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>
src/cmd/compile/internal/types2/builtins.go
src/cmd/compile/internal/types2/testdata/check/builtins.src
src/cmd/compile/internal/types2/testdata/fixedbugs/issue49735.go2 [new file with mode: 0644]
src/go/types/builtins.go
src/go/types/testdata/check/builtins.src
src/go/types/testdata/fixedbugs/issue49735.go2 [new file with mode: 0644]

index f9db07fdea5d9fde84105d1333d758f9a2a58ca1..4b122bc54077ef6b618cad8bc90c0384d5fe40d2 100644 (file)
@@ -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
                }
 
index de27f5c6322132acbddfd8dc7d84b3fa44e923e7..358e9c5c0d13039391519b18ba77c7c6304c9084 100644 (file)
@@ -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 (file)
index 0000000..10e8df2
--- /dev/null
@@ -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)
+}
index 8fcfcb935f983cd0d46252582a361069076fee38..b421b38753e8c5b031780f487a574573003fda12 100644 (file)
@@ -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
                }
 
index 7fd6a4b03297ba2385f4e62ba4aecd450834c337..8a4c207a05d66398fac2f4eb2c6dafcba95d5866 100644 (file)
@@ -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 (file)
index 0000000..10e8df2
--- /dev/null
@@ -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)
+}