Skip to content

Commit

Permalink
go/types, types2: better error messages for append
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
griesemer committed Feb 9, 2022
1 parent 9867262 commit 2e2ef31
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 10 deletions.
16 changes: 15 additions & 1 deletion src/cmd/compile/internal/types2/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
8 changes: 4 additions & 4 deletions src/cmd/compile/internal/types2/testdata/check/builtins.src
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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() {
Expand Down
11 changes: 11 additions & 0 deletions src/cmd/compile/internal/types2/testdata/fixedbugs/issue49735.go2
Original file line number Diff line number Diff line change
@@ -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)
}
16 changes: 15 additions & 1 deletion src/go/types/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
8 changes: 4 additions & 4 deletions src/go/types/testdata/check/builtins.src
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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() {
Expand Down
11 changes: 11 additions & 0 deletions src/go/types/testdata/fixedbugs/issue49735.go2
Original file line number Diff line number Diff line change
@@ -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)
}

0 comments on commit 2e2ef31

Please sign in to comment.