1
0
mirror of https://github.com/golang/go synced 2024-11-23 03:50:03 -07:00

cmd/compile/internal/types2: simplify error reporting API (cleanup)

- Remove specialized errorf functions for invalid AST/argument/operation.
  Instead use prefix constants with the error message.

- Replace several calls to Checker.errorf with calls to Checker.error
  if there are no arguments to format.

- Replace a handful of %s format verbs with %v to satisfy vet check.

- Add a basic test that checks that we're not using Checker.errorf when
  we should be using Checker.error.

Change-Id: I7bc7c14f3cf774689ec8cd5782ea31b6e30dbcd6
Reviewed-on: https://go-review.googlesource.com/c/go/+/300995
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2021-03-11 16:34:01 -08:00
parent 7b47f9a5f2
commit 16ad1ea841
13 changed files with 162 additions and 117 deletions

View File

@ -194,7 +194,7 @@ func (check *Checker) assignVar(lhs syntax.Expr, x *operand) Type {
case variable, mapindex:
// ok
case nilvalue:
check.errorf(&z, "cannot assign to nil") // default would print "untyped nil"
check.error(&z, "cannot assign to nil") // default would print "untyped nil"
return nil
default:
if sel, ok := z.expr.(*syntax.SelectorExpr); ok {

View File

@ -21,8 +21,8 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// append is the only built-in that permits the use of ... for the last argument
bin := predeclaredFuncs[id]
if call.HasDots && id != _Append {
//check.invalidOpf(call.Ellipsis, "invalid use of ... with built-in %s", bin.name)
check.invalidOpf(call, "invalid use of ... with built-in %s", bin.name)
//check.errorf(call.Ellipsis, invalidOp + "invalid use of ... with built-in %s", bin.name)
check.errorf(call, invalidOp+"invalid use of ... with built-in %s", bin.name)
check.use(call.ArgList...)
return
}
@ -68,7 +68,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
msg = "too many"
}
if msg != "" {
check.invalidOpf(call, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
check.errorf(call, invalidOp+"%s arguments for %v (expected %d, found %d)", msg, call, bin.nargs, nargs)
return
}
}
@ -85,7 +85,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
if s := asSlice(S); s != nil {
T = s.elem
} else {
check.invalidArgf(x, "%s is not a slice", x)
check.errorf(x, invalidArg+"%s is not a slice", x)
return
}
@ -197,7 +197,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
if mode == invalid && typ != Typ[Invalid] {
check.invalidArgf(x, "%s for %s", x, bin.name)
check.errorf(x, invalidArg+"%s for %s", x, bin.name)
return
}
@ -212,11 +212,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// close(c)
c := asChan(x.typ)
if c == nil {
check.invalidArgf(x, "%s is not a channel", x)
check.errorf(x, invalidArg+"%s is not a channel", x)
return
}
if c.dir == RecvOnly {
check.invalidArgf(x, "%s must not be a receive-only channel", x)
check.errorf(x, invalidArg+"%s must not be a receive-only channel", x)
return
}
@ -280,7 +280,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// both argument types must be identical
if !check.identical(x.typ, y.typ) {
check.invalidOpf(x, "%s (mismatched types %s and %s)", call, x.typ, y.typ)
check.errorf(x, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
return
}
@ -300,7 +300,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
resTyp := check.applyTypeFunc(f, x.typ)
if resTyp == nil {
check.invalidArgf(x, "arguments have type %s, expected floating-point", x.typ)
check.errorf(x, invalidArg+"arguments have type %s, expected floating-point", x.typ)
return
}
@ -340,12 +340,12 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
if dst == nil || src == nil {
check.invalidArgf(x, "copy expects slice arguments; found %s and %s", x, &y)
check.errorf(x, invalidArg+"copy expects slice arguments; found %s and %s", x, &y)
return
}
if !check.identical(dst, src) {
check.invalidArgf(x, "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src)
check.errorf(x, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src)
return
}
@ -359,7 +359,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// delete(m, k)
m := asMap(x.typ)
if m == nil {
check.invalidArgf(x, "%s is not a map", x)
check.errorf(x, invalidArg+"%s is not a map", x)
return
}
arg(x, 1) // k
@ -418,7 +418,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
resTyp := check.applyTypeFunc(f, x.typ)
if resTyp == nil {
check.invalidArgf(x, "argument has type %s, expected complex type", x.typ)
check.errorf(x, invalidArg+"argument has type %s, expected complex type", x.typ)
return
}
@ -473,7 +473,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
if !valid(T) {
check.invalidArgf(arg0, "cannot make %s; type must be slice, map, or channel", arg0)
check.errorf(arg0, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
return
}
if nargs < min || max < nargs {
@ -495,7 +495,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
}
if len(sizes) == 2 && sizes[0] > sizes[1] {
check.invalidArgf(call.ArgList[1], "length and capacity swapped")
check.error(call.ArgList[1], invalidArg+"length and capacity swapped")
// safe to continue
}
x.mode = value
@ -578,7 +578,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
case _Alignof:
// unsafe.Alignof(x T) uintptr
if asTypeParam(x.typ) != nil {
check.invalidOpf(call, "unsafe.Alignof undefined for %s", x)
check.errorf(call, invalidOp+"unsafe.Alignof undefined for %s", x)
return
}
check.assignment(x, nil, "argument to unsafe.Alignof")
@ -597,7 +597,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
arg0 := call.ArgList[0]
selx, _ := unparen(arg0).(*syntax.SelectorExpr)
if selx == nil {
check.invalidArgf(arg0, "%s is not a selector expression", arg0)
check.errorf(arg0, invalidArg+"%s is not a selector expression", arg0)
check.use(arg0)
return
}
@ -612,18 +612,18 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
obj, index, indirect := check.lookupFieldOrMethod(base, false, check.pkg, sel)
switch obj.(type) {
case nil:
check.invalidArgf(x, "%s has no single field %s", base, sel)
check.errorf(x, invalidArg+"%s has no single field %s", base, sel)
return
case *Func:
// TODO(gri) Using derefStructPtr may result in methods being found
// that don't actually exist. An error either way, but the error
// message is confusing. See: https://play.golang.org/p/al75v23kUy ,
// but go/types reports: "invalid argument: x.m is a method value".
check.invalidArgf(arg0, "%s is a method value", arg0)
check.errorf(arg0, invalidArg+"%s is a method value", arg0)
return
}
if indirect {
check.invalidArgf(x, "field %s is embedded via a pointer in %s", sel, base)
check.errorf(x, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
return
}
@ -639,7 +639,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
case _Sizeof:
// unsafe.Sizeof(x T) uintptr
if asTypeParam(x.typ) != nil {
check.invalidOpf(call, "unsafe.Sizeof undefined for %s", x)
check.errorf(call, invalidOp+"unsafe.Sizeof undefined for %s", x)
return
}
check.assignment(x, nil, "argument to unsafe.Sizeof")
@ -657,7 +657,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// The result of assert is the value of pred if there is no error.
// Note: assert is only available in self-test mode.
if x.mode != constant_ || !isBoolean(x.typ) {
check.invalidArgf(x, "%s is not a boolean constant", x)
check.errorf(x, invalidArg+"%s is not a boolean constant", x)
return
}
if x.val.Kind() != constant.Bool {

View File

@ -158,7 +158,7 @@ func (check *Checker) call(x *operand, call *syntax.CallExpr) exprKind {
sig := asSignature(x.typ)
if sig == nil {
check.invalidOpf(x, "cannot call non-function %s", x)
check.errorf(x, invalidOp+"cannot call non-function %s", x)
x.mode = invalid
x.expr = call
return statement
@ -248,7 +248,7 @@ func (check *Checker) exprOrTypeList(elist []syntax.Expr) (xlist []*operand, ok
}
}
if 0 < ntypes && ntypes < len(xlist) {
check.errorf(xlist[0], "mix of value and type expressions")
check.error(xlist[0], "mix of value and type expressions")
ok = false
}
}

View File

@ -214,7 +214,7 @@ func (check *Checker) initFiles(files []*syntax.File) {
if name != "_" {
pkg.name = name
} else {
check.errorf(file.PkgName, "invalid package name _")
check.error(file.PkgName, "invalid package name _")
}
fallthrough

View File

@ -629,14 +629,14 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
if alias && tdecl.TParamList != nil {
// The parser will ensure this but we may still get an invalid AST.
// Complain and continue as regular type definition.
check.errorf(tdecl, "generic type cannot be alias")
check.error(tdecl, "generic type cannot be alias")
alias = false
}
if alias {
// type alias declaration
if !check.allowVersion(obj.pkg, 1, 9) {
check.errorf(tdecl, "type aliases requires go1.9 or later")
check.error(tdecl, "type aliases requires go1.9 or later")
}
obj.typ = Typ[Invalid]
@ -978,7 +978,7 @@ func (check *Checker) declStmt(list []syntax.Decl) {
check.pop().setColor(black)
default:
check.invalidASTf(s, "unknown syntax.Decl node %T", s)
check.errorf(s, invalidAST+"unknown syntax.Decl node %T", s)
}
}
}

View File

@ -0,0 +1,49 @@
// Copyright 2021 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 ast.
package types2_test
import (
"cmd/compile/internal/syntax"
"testing"
)
// TestErrorCalls makes sure that check.errorf calls have at
// least 3 arguments (otherwise we should be using check.error).
func TestErrorCalls(t *testing.T) {
files, err := pkgFiles(".")
if err != nil {
t.Fatal(err)
}
for _, file := range files {
syntax.Walk(file, func(n syntax.Node) bool {
call, _ := n.(*syntax.CallExpr)
if call == nil {
return false
}
selx, _ := call.Fun.(*syntax.SelectorExpr)
if selx == nil {
return false
}
if !(isName(selx.X, "check") && isName(selx.Sel, "errorf")) {
return false
}
// check.errorf calls should have more than 2 arguments:
// position, format string, and arguments to format
if n := len(call.ArgList); n <= 2 {
t.Errorf("%s: got %d arguments, want > 2", call.Pos(), n)
return true
}
return false
})
}
}
func isName(n syntax.Node, name string) bool {
if n, ok := n.(*syntax.Name); ok {
return n.Value == name
}
return false
}

View File

@ -142,7 +142,7 @@ func (check *Checker) dump(format string, args ...interface{}) {
fmt.Println(check.sprintf(format, args...))
}
func (check *Checker) err(pos syntax.Pos, msg string, soft bool) {
func (check *Checker) err(at poser, msg string, soft bool) {
// Cheap trick: Don't report errors with messages containing
// "invalid operand" or "invalid type" as those tend to be
// follow-on errors which don't add useful information. Only
@ -152,6 +152,8 @@ func (check *Checker) err(pos syntax.Pos, msg string, soft bool) {
return
}
pos := posFor(at)
// If we are encountering an error while evaluating an inherited
// constant initialization expression, pos is the position of in
// the original expression, and not of the currently declared
@ -179,32 +181,26 @@ func (check *Checker) err(pos syntax.Pos, msg string, soft bool) {
f(err)
}
const (
invalidAST = "invalid AST: "
invalidArg = "invalid argument: "
invalidOp = "invalid operation: "
)
type poser interface {
Pos() syntax.Pos
}
func (check *Checker) error(at poser, msg string) {
check.err(posFor(at), msg, false)
check.err(at, msg, false)
}
func (check *Checker) errorf(at poser, format string, args ...interface{}) {
check.err(posFor(at), check.sprintf(format, args...), false)
check.err(at, check.sprintf(format, args...), false)
}
func (check *Checker) softErrorf(at poser, format string, args ...interface{}) {
check.err(posFor(at), check.sprintf(format, args...), true)
}
func (check *Checker) invalidASTf(at poser, format string, args ...interface{}) {
check.errorf(at, "invalid AST: "+format, args...)
}
func (check *Checker) invalidArgf(at poser, format string, args ...interface{}) {
check.errorf(at, "invalid argument: "+format, args...)
}
func (check *Checker) invalidOpf(at poser, format string, args ...interface{}) {
check.errorf(at, "invalid operation: "+format, args...)
check.err(at, check.sprintf(format, args...), true)
}
// posFor reports the left (= start) position of at.

View File

@ -75,14 +75,14 @@ func (check *Checker) op(m opPredicates, x *operand, op syntax.Operator) bool {
if pred := m[op]; pred != nil {
if !pred(x.typ) {
if check.conf.CompilerErrorMessages {
check.invalidOpf(x, "operator %s not defined on %s", op, x)
check.errorf(x, invalidOp+"operator %s not defined on %s", op, x)
} else {
check.invalidOpf(x, "operator %s not defined for %s", op, x)
check.errorf(x, invalidOp+"operator %s not defined for %s", op, x)
}
return false
}
} else {
check.invalidASTf(x, "unknown operator %s", op)
check.errorf(x, invalidAST+"unknown operator %s", op)
return false
}
return true
@ -108,7 +108,7 @@ func (check *Checker) overflow(x *operand) {
// TODO(gri) We should report exactly what went wrong. At the
// moment we don't have the (go/constant) API for that.
// See also TODO in go/constant/value.go.
check.errorf(pos, "constant result is not representable")
check.error(pos, "constant result is not representable")
return
}
@ -169,7 +169,7 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
// spec: "As an exception to the addressability
// requirement x may also be a composite literal."
if _, ok := unparen(e.X).(*syntax.CompositeLit); !ok && x.mode != variable {
check.invalidOpf(x, "cannot take address of %s", x)
check.errorf(x, invalidOp+"cannot take address of %s", x)
x.mode = invalid
return
}
@ -180,12 +180,12 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
case syntax.Recv:
typ := asChan(x.typ)
if typ == nil {
check.invalidOpf(x, "cannot receive from non-channel %s", x)
check.errorf(x, invalidOp+"cannot receive from non-channel %s", x)
x.mode = invalid
return
}
if typ.dir == SendOnly {
check.invalidOpf(x, "cannot receive from send-only channel %s", x)
check.errorf(x, invalidOp+"cannot receive from send-only channel %s", x)
x.mode = invalid
return
}
@ -562,7 +562,7 @@ func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
// We already know from the shift check that it is representable
// as an integer if it is a constant.
if !isInteger(typ) {
check.invalidOpf(x, "shifted operand %s (type %s) must be integer", x, typ)
check.errorf(x, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
return
}
// Even if we have an integer, if the value is a constant we
@ -753,7 +753,7 @@ func (check *Checker) comparison(x, y *operand, op syntax.Operator) {
if err != "" {
// TODO(gri) better error message for cases where one can only compare against nil
check.invalidOpf(x, "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err)
check.errorf(x, invalidOp+"cannot compare %s %s %s (%s)", x.expr, op, y.expr, err)
x.mode = invalid
return
}
@ -791,7 +791,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
// as an integer. Nothing to do.
} else {
// shift has no chance
check.invalidOpf(x, "shifted operand %s must be integer", x)
check.errorf(x, invalidOp+"shifted operand %s must be integer", x)
x.mode = invalid
return
}
@ -803,7 +803,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
if y.mode == constant_ {
yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
check.invalidOpf(y, "negative shift count %s", y)
check.errorf(y, invalidOp+"negative shift count %s", y)
x.mode = invalid
return
}
@ -818,11 +818,11 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
return
}
} else if !isInteger(y.typ) {
check.invalidOpf(y, "shift count %s must be integer", y)
check.errorf(y, invalidOp+"shift count %s must be integer", y)
x.mode = invalid
return
} else if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
check.invalidOpf(y, "signed shift count %s requires go1.13 or later", y)
check.errorf(y, invalidOp+"signed shift count %s requires go1.13 or later", y)
x.mode = invalid
return
}
@ -842,7 +842,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see issue #44057)
s, ok := constant.Uint64Val(y.val)
if !ok || s > shiftBound {
check.invalidOpf(y, "invalid shift count %s", y)
check.errorf(y, invalidOp+"invalid shift count %s", y)
x.mode = invalid
return
}
@ -893,7 +893,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
// non-constant shift - lhs must be an integer
if !isInteger(x.typ) {
check.invalidOpf(x, "shifted operand %s must be integer", x)
check.errorf(x, invalidOp+"shifted operand %s must be integer", x)
x.mode = invalid
return
}
@ -963,7 +963,7 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
// only report an error if we have valid types
// (otherwise we had an error reported elsewhere already)
if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] {
check.invalidOpf(x, "mismatched types %s and %s", x.typ, y.typ)
check.errorf(x, invalidOp+"mismatched types %s and %s", x.typ, y.typ)
}
x.mode = invalid
return
@ -977,7 +977,7 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
if op == syntax.Div || op == syntax.Rem {
// check for zero divisor
if (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
check.invalidOpf(&y, "division by zero")
check.error(&y, invalidOp+"division by zero")
x.mode = invalid
return
}
@ -987,7 +987,7 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
re, im := constant.Real(y.val), constant.Imag(y.val)
re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
check.invalidOpf(&y, "division by zero")
check.error(&y, invalidOp+"division by zero")
x.mode = invalid
return
}
@ -1038,7 +1038,7 @@ func (check *Checker) index(index syntax.Expr, max int64) (typ Type, val int64)
// the index must be of integer type
if !isInteger(x.typ) {
check.invalidArgf(&x, "index %s must be integer", &x)
check.errorf(&x, invalidArg+"index %s must be integer", &x)
return
}
@ -1048,7 +1048,7 @@ func (check *Checker) index(index syntax.Expr, max int64) (typ Type, val int64)
// a constant index i must be in bounds
if constant.Sign(x.val) < 0 {
check.invalidArgf(&x, "index %s must not be negative", &x)
check.errorf(&x, invalidArg+"index %s must not be negative", &x)
return
}
@ -1242,7 +1242,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
x.mode = value
x.typ = sig
} else {
check.invalidASTf(e, "invalid function literal %s", e)
check.errorf(e, invalidAST+"invalid function literal %v", e)
goto Error
}
@ -1608,23 +1608,23 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
}
if !valid {
check.invalidOpf(x, "cannot index %s", x)
check.errorf(x, invalidOp+"cannot index %s", x)
goto Error
}
if e.Index == nil {
check.invalidASTf(e, "missing index for %s", x)
check.errorf(e, invalidAST+"missing index for %s", x)
goto Error
}
index := e.Index
if l, _ := index.(*syntax.ListExpr); l != nil {
if n := len(l.ElemList); n <= 1 {
check.invalidASTf(e, "invalid use of ListExpr for index expression %s with %d indices", e, n)
check.errorf(e, invalidAST+"invalid use of ListExpr for index expression %v with %d indices", e, n)
goto Error
}
// len(l.ElemList) > 1
check.invalidOpf(l.ElemList[1], "more than one index")
check.error(l.ElemList[1], invalidOp+"more than one index")
index = l.ElemList[0] // continue with first index
}
@ -1651,7 +1651,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
case *Basic:
if isString(typ) {
if e.Full {
check.invalidOpf(x, "3-index slice of string")
check.error(x, invalidOp+"3-index slice of string")
goto Error
}
valid = true
@ -1669,7 +1669,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
valid = true
length = typ.len
if x.mode != variable {
check.invalidOpf(x, "%s (slice of unaddressable value)", x)
check.errorf(x, invalidOp+"%s (slice of unaddressable value)", x)
goto Error
}
x.typ = &Slice{elem: typ.elem}
@ -1686,12 +1686,12 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// x.typ doesn't change
case *Sum, *TypeParam:
check.errorf(x, "generic slice expressions not yet implemented")
check.error(x, "generic slice expressions not yet implemented")
goto Error
}
if !valid {
check.invalidOpf(x, "cannot slice %s", x)
check.errorf(x, invalidOp+"cannot slice %s", x)
goto Error
}
@ -1699,7 +1699,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// spec: "Only the first index may be omitted; it defaults to 0."
if e.Full && (e.Index[1] == nil || e.Index[2] == nil) {
check.invalidASTf(e, "2nd and 3rd index required in 3-index slice")
check.error(e, invalidAST+"2nd and 3rd index required in 3-index slice")
goto Error
}
@ -1756,7 +1756,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
check.ordinaryType(x.Pos(), xtyp)
// x.(type) expressions are encoded via TypeSwitchGuards
if e.Type == nil {
check.invalidASTf(e, "invalid use of AssertExpr")
check.error(e, invalidAST+"invalid use of AssertExpr")
goto Error
}
T := check.varType(e.Type)
@ -1769,7 +1769,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
case *syntax.TypeSwitchGuard:
// x.(type) expressions are handled explicitly in type switches
check.invalidASTf(e, "use of .(type) outside type switch")
check.error(e, invalidAST+"use of .(type) outside type switch")
goto Error
case *syntax.CallExpr:
@ -1811,7 +1811,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
x.mode = variable
x.typ = typ.base
} else {
check.invalidOpf(x, "cannot indirect %s", x)
check.errorf(x, invalidOp+"cannot indirect %s", x)
goto Error
}
}
@ -1837,7 +1837,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
case *syntax.KeyValueExpr:
// key:value expressions are handled in composite literals
check.invalidASTf(e, "no key:value expected")
check.error(e, invalidAST+"no key:value expected")
goto Error
case *syntax.ArrayType, *syntax.SliceType, *syntax.StructType, *syntax.FuncType,

View File

@ -212,7 +212,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.Lab
}
default:
check.invalidASTf(s, "branch statement: %s %s", s.Tok, name)
check.errorf(s, invalidAST+"branch statement: %s %s", s.Tok, name)
return
}

View File

@ -92,14 +92,14 @@ func (check *Checker) declarePkgObj(ident *syntax.Name, obj Object, d *declInfo)
// spec: "A package-scope or file-scope identifier with name init
// may only be declared to be a function with this (func()) signature."
if ident.Value == "init" {
check.errorf(ident, "cannot declare init - must be func")
check.error(ident, "cannot declare init - must be func")
return
}
// spec: "The main package must have package name main and declare
// a function main that takes no arguments and returns no value."
if ident.Value == "main" && check.pkg.name == "main" {
check.errorf(ident, "cannot declare main - must be func")
check.error(ident, "cannot declare main - must be func")
return
}
@ -256,13 +256,13 @@ func (check *Checker) collectObjects() {
name = s.LocalPkgName.Value
if path == "C" {
// match cmd/compile (not prescribed by spec)
check.errorf(s.LocalPkgName, `cannot rename import "C"`)
check.error(s.LocalPkgName, `cannot rename import "C"`)
continue
}
}
if name == "init" {
check.errorf(s.LocalPkgName, "cannot import package as init - init must be a func")
check.error(s.LocalPkgName, "cannot import package as init - init must be a func")
continue
}
@ -428,8 +428,8 @@ func (check *Checker) collectObjects() {
// method
// d.Recv != nil
if !methodTypeParamsOk && len(d.TParamList) != 0 {
//check.invalidASTf(d.TParamList.Pos(), "method must have no type parameters")
check.invalidASTf(d, "method must have no type parameters")
//check.error(d.TParamList.Pos(), invalidAST + "method must have no type parameters")
check.error(d, invalidAST+"method must have no type parameters")
}
ptr, recv, _ := check.unpackRecv(d.Recv.Type, false)
// (Methods with invalid receiver cannot be associated to a type, and
@ -449,7 +449,7 @@ func (check *Checker) collectObjects() {
obj.setOrder(uint32(len(check.objMap)))
default:
check.invalidASTf(s, "unknown syntax.Decl node %T", s)
check.errorf(s, invalidAST+"unknown syntax.Decl node %T", s)
}
}
}
@ -530,7 +530,7 @@ L: // unpack receiver type
case *syntax.BadExpr:
// ignore - error already reported by parser
case nil:
check.invalidASTf(ptyp, "parameterized receiver contains nil parameters")
check.error(ptyp, invalidAST+"parameterized receiver contains nil parameters")
default:
check.errorf(arg, "receiver type parameter %s must be an identifier", arg)
}

View File

@ -357,12 +357,12 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
tch := asChan(ch.typ)
if tch == nil {
check.invalidOpf(s, "cannot send to non-chan type %s", ch.typ)
check.errorf(s, invalidOp+"cannot send to non-chan type %s", ch.typ)
return
}
if tch.dir == RecvOnly {
check.invalidOpf(s, "cannot send to receive-only type %s", tch)
check.errorf(s, invalidOp+"cannot send to receive-only type %s", tch)
return
}
@ -373,7 +373,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
if s.Rhs == nil {
// x++ or x--
if len(lhs) != 1 {
check.invalidASTf(s, "%s%s requires one operand", s.Op, s.Op)
check.errorf(s, invalidAST+"%s%s requires one operand", s.Op, s.Op)
return
}
var x operand
@ -382,7 +382,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
return
}
if !isNumeric(x.typ) {
check.invalidOpf(lhs[0], "%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
check.errorf(lhs[0], invalidOp+"%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
return
}
check.assignVar(lhs[0], &x)
@ -484,7 +484,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
// goto's must have labels, should have been caught above
fallthrough
default:
check.invalidASTf(s, "branch statement: %s", s.Tok)
check.errorf(s, invalidAST+"branch statement: %s", s.Tok)
}
case *syntax.BlockStmt:
@ -642,7 +642,7 @@ func (check *Checker) switchStmt(inner stmtContext, s *syntax.SwitchStmt) {
seen := make(valueMap) // map of seen case values to positions and types
for i, clause := range s.Body {
if clause == nil {
check.invalidASTf(clause, "incorrect expression switch case")
check.error(clause, invalidAST+"incorrect expression switch case")
continue
}
end := s.Rbrace
@ -699,7 +699,7 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
seen := make(map[Type]syntax.Pos) // map of seen types to positions
for i, clause := range s.Body {
if clause == nil {
check.invalidASTf(s, "incorrect type switch case")
check.error(s, invalidAST+"incorrect type switch case")
continue
}
end := s.Rbrace
@ -765,7 +765,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
var sValue syntax.Expr
if p, _ := sKey.(*syntax.ListExpr); p != nil {
if len(p.ElemList) != 2 {
check.invalidASTf(s, "invalid lhs in range clause")
check.error(s, invalidAST+"invalid lhs in range clause")
return
}
sKey = p.ElemList[0]

View File

@ -29,7 +29,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType boo
scope, obj := check.scope.LookupParent(e.Value, check.pos)
if obj == nil {
if e.Value == "_" {
check.errorf(e, "cannot use _ as value or type")
check.error(e, "cannot use _ as value or type")
} else {
if check.conf.CompilerErrorMessages {
check.errorf(e, "undefined: %s", e.Value)
@ -76,7 +76,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType boo
}
if obj == universeIota {
if check.iota == nil {
check.errorf(e, "cannot use iota outside constant declaration")
check.error(e, "cannot use iota outside constant declaration")
return
}
x.val = check.iota
@ -337,7 +337,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
// (A separate check is needed when type-checking interface method signatures because
// they don't have a receiver specification.)
if recvPar != nil && !check.conf.AcceptMethodTypeParams {
check.errorf(ftyp, "methods cannot have type parameters")
check.error(ftyp, "methods cannot have type parameters")
}
}
@ -511,7 +511,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
typ.len = check.arrayLength(e.Len)
} else {
// [...]array
check.errorf(e, "invalid use of [...] array (outside a composite literal)")
check.error(e, "invalid use of [...] array (outside a composite literal)")
typ.len = -1
}
typ.elem = check.varType(e.Elem)
@ -599,7 +599,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
case syntax.RecvOnly:
dir = RecvOnly
default:
check.invalidASTf(e, "unknown channel direction %d", e.Dir)
check.errorf(e, invalidAST+"unknown channel direction %d", e.Dir)
// ok to continue
}
@ -763,7 +763,7 @@ func (check *Checker) collectParams(scope *Scope, list []*syntax.Field, type0 sy
// named parameter
name := field.Name.Value
if name == "" {
check.invalidASTf(field.Name, "anonymous parameter")
check.error(field.Name, invalidAST+"anonymous parameter")
// ok to continue
}
par := NewParam(field.Name.Pos(), check.pkg, name, typ)
@ -780,7 +780,7 @@ func (check *Checker) collectParams(scope *Scope, list []*syntax.Field, type0 sy
}
if named && anonymous {
check.invalidASTf(list[0], "list contains both named and anonymous parameters")
check.error(list[0], invalidAST+"list contains both named and anonymous parameters")
// ok to continue
}
@ -817,9 +817,9 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
name := f.Name.Value
if name == "_" {
if check.conf.CompilerErrorMessages {
check.errorf(f.Name, "methods must have a unique non-blank name")
check.error(f.Name, "methods must have a unique non-blank name")
} else {
check.errorf(f.Name, "invalid method name _")
check.error(f.Name, "invalid method name _")
}
continue // ignore
}
@ -830,7 +830,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
// the author intended to include all types.
types = append(types, f.Type)
if tname != nil && tname != f.Name {
check.errorf(f.Name, "cannot have multiple type lists in an interface")
check.error(f.Name, "cannot have multiple type lists in an interface")
}
tname = f.Name
continue
@ -840,7 +840,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
sig, _ := typ.(*Signature)
if sig == nil {
if typ != Typ[Invalid] {
check.invalidASTf(f.Type, "%s is not a method signature", typ)
check.errorf(f.Type, invalidAST+"%s is not a method signature", typ)
}
continue // ignore
}
@ -849,7 +849,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
// (This extra check is needed here because interface method signatures don't have
// a receiver specification.)
if sig.tparams != nil && !check.conf.AcceptMethodTypeParams {
check.errorf(f.Type, "methods cannot have type parameters")
check.error(f.Type, "methods cannot have type parameters")
}
// use named receiver type if available (for better error messages)
@ -1087,7 +1087,7 @@ func (check *Checker) tag(t *syntax.BasicLit) string {
return val
}
}
check.invalidASTf(t, "incorrect tag syntax: %q", t.Value)
check.errorf(t, invalidAST+"incorrect tag syntax: %q", t.Value)
}
return ""
}
@ -1180,13 +1180,13 @@ func (check *Checker) structType(styp *Struct, e *syntax.StructType) {
}
// unsafe.Pointer is treated like a regular pointer
if t.kind == UnsafePointer {
check.errorf(embeddedPos, "embedded field type cannot be unsafe.Pointer")
check.error(embeddedPos, "embedded field type cannot be unsafe.Pointer")
}
case *Pointer:
check.errorf(embeddedPos, "embedded field type cannot be a pointer")
check.error(embeddedPos, "embedded field type cannot be a pointer")
case *Interface:
if isPtr {
check.errorf(embeddedPos, "embedded field type cannot be a pointer to an interface")
check.error(embeddedPos, "embedded field type cannot be a pointer to an interface")
}
}
})
@ -1220,7 +1220,7 @@ func (check *Checker) collectTypeConstraints(pos syntax.Pos, types []syntax.Expr
list := make([]Type, 0, len(types)) // assume all types are correct
for _, texpr := range types {
if texpr == nil {
check.invalidASTf(pos, "missing type constraint")
check.error(pos, invalidAST+"missing type constraint")
continue
}
list = append(list, check.varType(texpr))

View File

@ -21,7 +21,7 @@ func (check *Checker) langCompat(lit *syntax.BasicLit) {
}
// len(s) > 2
if strings.Contains(s, "_") {
check.errorf(lit, "underscores in numeric literals requires go1.13 or later")
check.error(lit, "underscores in numeric literals requires go1.13 or later")
return
}
if s[0] != '0' {
@ -29,15 +29,15 @@ func (check *Checker) langCompat(lit *syntax.BasicLit) {
}
radix := s[1]
if radix == 'b' || radix == 'B' {
check.errorf(lit, "binary literals requires go1.13 or later")
check.error(lit, "binary literals requires go1.13 or later")
return
}
if radix == 'o' || radix == 'O' {
check.errorf(lit, "0o/0O-style octal literals requires go1.13 or later")
check.error(lit, "0o/0O-style octal literals requires go1.13 or later")
return
}
if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
check.errorf(lit, "hexadecimal floating-point literals requires go1.13 or later")
check.error(lit, "hexadecimal floating-point literals requires go1.13 or later")
}
}