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:
parent
7b47f9a5f2
commit
16ad1ea841
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
49
src/cmd/compile/internal/types2/errorcalls_test.go
Normal file
49
src/cmd/compile/internal/types2/errorcalls_test.go
Normal 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
|
||||
}
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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))
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user