1
0
mirror of https://github.com/golang/go synced 2024-09-30 14:38:33 -06:00

types2: provide error codes to error reporting

This CL adds a suitable error code to every error reporting,
matching what go/types already does.

For now, the error codes are not progagated through the API,
but eventually they will be available to clients.

Also, for now the errorcodes.go file is a 1:1 copy (with
adjusted package name) of go/types/errorcodes.go.
A subsequent CL will factor out this file.

In contrast to go/types, for errors due to incorrect Go version,
the error code is always _UnsupportedFeature. In go/types, the
error sometimes is related to the specific operation.

Change-Id: I18771bc3d00bbdbf6d705bf25f2aea3c3d977b1c
Reviewed-on: https://go-review.googlesource.com/c/go/+/429355
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
This commit is contained in:
Robert Griesemer 2022-09-07 18:45:09 -07:00 committed by Gopher Robot
parent 54182ff54a
commit f4a587ba6e
20 changed files with 1769 additions and 313 deletions

View File

@ -27,7 +27,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
// ok
default:
// we may get here because of other problems (issue #39634, crash 12)
check.errorf(x, "cannot assign %s to %s in %s", x, T, context)
check.errorf(x, 0, "cannot assign %s to %s in %s", x, T, context)
return
}
@ -40,7 +40,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
// complex, or string constant."
if x.isNil() {
if T == nil {
check.errorf(x, "use of untyped nil in %s", context)
check.errorf(x, _UntypedNil, "use of untyped nil in %s", context)
x.mode = invalid
return
}
@ -55,8 +55,10 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
msg += " (truncated)"
case _NumericOverflow:
msg += " (overflows)"
default:
code = _IncompatibleAssign
}
check.error(x, msg)
check.error(x, code, msg)
x.mode = invalid
return
}
@ -73,7 +75,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
// A generic (non-instantiated) function value cannot be assigned to a variable.
if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
check.errorf(x, "cannot use generic function %s without instantiation in %s", x, context)
check.errorf(x, _WrongTypeArgCount, "cannot use generic function %s without instantiation in %s", x, context)
}
// spec: "If a left-hand side is the blank identifier, any typed or
@ -84,18 +86,18 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
}
reason := ""
if ok, _ := x.assignableTo(check, T, &reason); !ok {
if ok, code := x.assignableTo(check, T, &reason); !ok {
if check.conf.CompilerErrorMessages {
if reason != "" {
check.errorf(x, "cannot use %s as type %s in %s:\n\t%s", x, T, context, reason)
check.errorf(x, code, "cannot use %s as type %s in %s:\n\t%s", x, T, context, reason)
} else {
check.errorf(x, "cannot use %s as type %s in %s", x, T, context)
check.errorf(x, code, "cannot use %s as type %s in %s", x, T, context)
}
} else {
if reason != "" {
check.errorf(x, "cannot use %s as %s value in %s: %s", x, T, context, reason)
check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, reason)
} else {
check.errorf(x, "cannot use %s as %s value in %s", x, T, context)
check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
}
}
x.mode = invalid
@ -112,7 +114,7 @@ func (check *Checker) initConst(lhs *Const, x *operand) {
// rhs must be a constant
if x.mode != constant_ {
check.errorf(x, "%s is not constant", x)
check.errorf(x, _InvalidConstInit, "%s is not constant", x)
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
}
@ -150,7 +152,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, context string) Type {
if isUntyped(typ) {
// convert untyped types to default types
if typ == Typ[UntypedNil] {
check.errorf(x, "use of untyped nil in %s", context)
check.errorf(x, _UntypedNil, "use of untyped nil in %s", context)
lhs.typ = Typ[Invalid]
return nil
}
@ -226,11 +228,11 @@ func (check *Checker) assignVar(lhs syntax.Expr, x *operand) Type {
var op operand
check.expr(&op, sel.X)
if op.mode == mapindex {
check.errorf(&z, "cannot assign to struct field %s in map", syntax.String(z.expr))
check.errorf(&z, _UnaddressableFieldAssign, "cannot assign to struct field %s in map", syntax.String(z.expr))
return nil
}
}
check.errorf(&z, "cannot assign to %s", &z)
check.errorf(&z, _UnassignableOperand, "cannot assign to %s", &z)
return nil
}
@ -308,11 +310,11 @@ func (check *Checker) assignError(rhs []syntax.Expr, nvars, nvals int) {
if len(rhs) == 1 {
if call, _ := unparen(rhs0).(*syntax.CallExpr); call != nil {
check.errorf(rhs0, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
check.errorf(rhs0, _WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
return
}
}
check.errorf(rhs0, "assignment mismatch: %s but %s", vars, vals)
check.errorf(rhs0, _WrongAssignCount, "assignment mismatch: %s but %s", vars, vals)
}
// If returnStmt != nil, initVars is called to type-check the assignment
@ -353,7 +355,7 @@ func (check *Checker) initVars(lhs []*Var, orig_rhs []syntax.Expr, returnStmt sy
if check.conf.CompilerErrorMessages {
check.assignError(orig_rhs, len(lhs), len(rhs))
} else {
check.errorf(rhs[0], "cannot initialize %d variables with %d values", len(lhs), len(rhs))
check.errorf(rhs[0], _WrongAssignCount, "cannot initialize %d variables with %d values", len(lhs), len(rhs))
}
return
}
@ -401,7 +403,7 @@ func (check *Checker) assignVars(lhs, orig_rhs []syntax.Expr) {
if check.conf.CompilerErrorMessages {
check.assignError(orig_rhs, len(lhs), len(rhs))
} else {
check.errorf(rhs[0], "cannot assign %d values to %d variables", len(rhs), len(lhs))
check.errorf(rhs[0], _WrongAssignCount, "cannot assign %d values to %d variables", len(rhs), len(lhs))
}
return
}
@ -466,7 +468,7 @@ func (check *Checker) shortVarDecl(pos syntax.Pos, lhs, rhs []syntax.Expr) {
ident, _ := lhs.(*syntax.Name)
if ident == nil {
check.use(lhs)
check.errorf(lhs, "non-name %s on left side of :=", lhs)
check.errorf(lhs, _BadDecl, "non-name %s on left side of :=", lhs)
hasErr = true
continue
}
@ -474,7 +476,7 @@ func (check *Checker) shortVarDecl(pos syntax.Pos, lhs, rhs []syntax.Expr) {
name := ident.Value
if name != "_" {
if seen[name] {
check.errorf(lhs, "%s repeated on left side of :=", lhs)
check.errorf(lhs, _RepeatedDecl, "%s repeated on left side of :=", lhs)
hasErr = true
continue
}
@ -491,7 +493,7 @@ func (check *Checker) shortVarDecl(pos syntax.Pos, lhs, rhs []syntax.Expr) {
if obj, _ := alt.(*Var); obj != nil {
lhsVars[i] = obj
} else {
check.errorf(lhs, "cannot assign to %s", lhs)
check.errorf(lhs, _UnassignableOperand, "cannot assign to %s", lhs)
hasErr = true
}
continue
@ -519,7 +521,7 @@ func (check *Checker) shortVarDecl(pos syntax.Pos, lhs, rhs []syntax.Expr) {
check.processDelayed(top)
if len(newVars) == 0 && !hasErr {
check.softErrorf(pos, "no new variables on left side of :=")
check.softErrorf(pos, _NoNewVar, "no new variables on left side of :=")
return
}

View File

@ -21,7 +21,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
bin := predeclaredFuncs[id]
if call.HasDots && id != _Append {
//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.errorf(call, _InvalidDotDotDot, invalidOp+"invalid use of ... with built-in %s", bin.name)
check.use(call.ArgList...)
return
}
@ -67,7 +67,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
msg = "too many"
}
if msg != "" {
check.errorf(call, invalidOp+"%s arguments for %v (expected %d, found %d)", msg, call, bin.nargs, nargs)
check.errorf(call, _WrongArgCount, invalidOp+"%s arguments for %v (expected %d, found %d)", msg, call, bin.nargs, nargs)
return
}
}
@ -98,7 +98,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
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)
check.errorf(x, _InvalidAppend, "first argument to append must be a slice; %s", cause)
return
}
@ -214,7 +214,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
if mode == invalid && under(x.typ) != Typ[Invalid] {
check.errorf(x, invalidArg+"%s for %s", x, bin.name)
code := _InvalidCap
if id == _Len {
code = _InvalidLen
}
check.errorf(x, code, invalidArg+"%s for %s", x, bin.name)
return
}
@ -232,11 +236,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
if !underIs(x.typ, func(u Type) bool {
uch, _ := u.(*Chan)
if uch == nil {
check.errorf(x, invalidOp+"cannot close non-channel %s", x)
check.errorf(x, _InvalidClose, invalidOp+"cannot close non-channel %s", x)
return false
}
if uch.dir == RecvOnly {
check.errorf(x, invalidOp+"cannot close receive-only channel %s", x)
check.errorf(x, _InvalidClose, invalidOp+"cannot close receive-only channel %s", x)
return false
}
return true
@ -303,7 +307,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// both argument types must be identical
if !Identical(x.typ, y.typ) {
check.errorf(x, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
check.errorf(x, _InvalidComplex, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
return
}
@ -325,7 +329,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
resTyp := check.applyTypeFunc(f, x, id)
if resTyp == nil {
check.errorf(x, invalidArg+"arguments have type %s, expected floating-point", x.typ)
check.errorf(x, _InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ)
return
}
@ -358,12 +362,12 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
src, _ := src0.(*Slice)
if dst == nil || src == nil {
check.errorf(x, invalidArg+"copy expects slice arguments; found %s and %s", x, &y)
check.errorf(x, _InvalidCopy, invalidArg+"copy expects slice arguments; found %s and %s", x, &y)
return
}
if !Identical(dst.elem, src.elem) {
check.errorf(x, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
check.errorf(x, _InvalidCopy, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
return
}
@ -382,11 +386,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
if !underIs(map_, func(u Type) bool {
map_, _ := u.(*Map)
if map_ == nil {
check.errorf(x, invalidArg+"%s is not a map", x)
check.errorf(x, _InvalidDelete, invalidArg+"%s is not a map", x)
return false
}
if key != nil && !Identical(map_.key, key) {
check.errorf(x, invalidArg+"maps of %s must have identical key types", x)
check.errorf(x, _InvalidDelete, invalidArg+"maps of %s must have identical key types", x)
return false
}
key = map_.key
@ -453,7 +457,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
resTyp := check.applyTypeFunc(f, x, id)
if resTyp == nil {
check.errorf(x, invalidArg+"argument has type %s, expected complex type", x.typ)
code := _InvalidImag
if id == _Real {
code = _InvalidReal
}
check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ)
return
}
@ -491,14 +499,14 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
case *Map, *Chan:
min = 1
case nil:
check.errorf(arg0, invalidArg+"cannot make %s: no core type", arg0)
check.errorf(arg0, _InvalidMake, invalidArg+"cannot make %s: no core type", arg0)
return
default:
check.errorf(arg0, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
check.errorf(arg0, _InvalidMake, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
return
}
if nargs < min || min+1 < nargs {
check.errorf(call, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
check.errorf(call, _WrongArgCount, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
return
}
@ -512,7 +520,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
}
if len(sizes) == 2 && sizes[0] > sizes[1] {
check.error(call.ArgList[1], invalidArg+"length and capacity swapped")
check.error(call.ArgList[1], _SwappedMakeArgs, invalidArg+"length and capacity swapped")
// safe to continue
}
x.mode = value
@ -606,7 +614,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
var y operand
arg(&y, 1)
if !check.isValidIndex(&y, "length", true) {
if !check.isValidIndex(&y, _InvalidUnsafeAdd, "length", true) {
return
}
@ -641,7 +649,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.errorf(arg0, invalidArg+"%s is not a selector expression", arg0)
check.errorf(arg0, _BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
check.use(arg0)
return
}
@ -656,18 +664,18 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
switch obj.(type) {
case nil:
check.errorf(x, invalidArg+"%s has no single field %s", base, sel)
check.errorf(x, _MissingFieldOrMethod, 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.errorf(arg0, invalidArg+"%s is a method value", arg0)
check.errorf(arg0, _InvalidOffsetof, invalidArg+"%s is a method value", arg0)
return
}
if indirect {
check.errorf(x, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
check.errorf(x, _InvalidOffsetof, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
return
}
@ -727,13 +735,13 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
ptr, _ := under(x.typ).(*Pointer) // TODO(gri) should this be coreType rather than under?
if ptr == nil {
check.errorf(x, invalidArg+"%s is not a pointer", x)
check.errorf(x, _InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
return
}
var y operand
arg(&y, 1)
if !check.isValidIndex(&y, "length", false) {
if !check.isValidIndex(&y, _InvalidUnsafeSlice, "length", false) {
return
}
@ -752,7 +760,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
slice, _ := under(x.typ).(*Slice) // TODO(gri) should this be coreType rather than under?
if slice == nil {
check.errorf(x, invalidArg+"%s is not a slice", x)
check.errorf(x, _InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
return
}
@ -776,7 +784,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
var y operand
arg(&y, 1)
if !check.isValidIndex(&y, "length", false) {
if !check.isValidIndex(&y, _InvalidUnsafeString, "length", false) {
return
}
@ -809,15 +817,15 @@ 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.errorf(x, invalidArg+"%s is not a boolean constant", x)
check.errorf(x, _Test, invalidArg+"%s is not a boolean constant", x)
return
}
if x.val.Kind() != constant.Bool {
check.errorf(x, "internal error: value of %s should be a boolean constant", x)
check.errorf(x, _Test, "internal error: value of %s should be a boolean constant", x)
return
}
if !constant.BoolVal(x.val) {
check.errorf(call, "%v failed", call)
check.errorf(call, _Test, "%v failed", call)
// compile-time assertion failure - safe to continue
}
// result is constant - no need to record signature
@ -915,7 +923,18 @@ func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId)
// type parameter for the result. It's not clear what the API
// implications are here. Report an error for 1.18 but continue
// type-checking.
check.softErrorf(x, "%s not supported as argument to %s for go1.18 (see issue #50937)", x, predeclaredFuncs[id].name)
var code errorCode
switch id {
case _Real:
code = _InvalidReal
case _Imag:
code = _InvalidImag
case _Complex:
code = _InvalidComplex
default:
unreachable()
}
check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see issue #50937)", x, predeclaredFuncs[id].name)
// Construct a suitable new type parameter for the result type.
// The type parameter is placed in the current package so export/import

View File

@ -32,7 +32,7 @@ func (check *Checker) funcInst(x *operand, inst *syntax.IndexExpr) {
sig := x.typ.(*Signature)
got, want := len(targs), sig.TypeParams().Len()
if !useConstraintTypeInference && got != want || got > want {
check.errorf(xlist[got-1], "got %d type arguments but want %d", got, want)
check.errorf(xlist[got-1], _WrongTypeArgCount, "got %d type arguments but want %d", got, want)
x.mode = invalid
x.expr = inst
return
@ -84,7 +84,7 @@ func (check *Checker) instantiateSignature(pos syntax.Pos, typ *Signature, targs
if i < len(xlist) {
pos = syntax.StartPos(xlist[i])
}
check.softErrorf(pos, "%s", err)
check.softErrorf(pos, _InvalidTypeArg, "%s", err)
} else {
check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
}
@ -126,25 +126,25 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
x.mode = invalid
switch n := len(call.ArgList); n {
case 0:
check.errorf(call, "missing argument in conversion to %s", T)
check.errorf(call, _WrongArgCount, "missing argument in conversion to %s", T)
case 1:
check.expr(x, call.ArgList[0])
if x.mode != invalid {
if t, _ := under(T).(*Interface); t != nil && !isTypeParam(T) {
if !t.IsMethodSet() {
check.errorf(call, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
check.errorf(call, _MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
break
}
}
if call.HasDots {
check.errorf(call.ArgList[0], "invalid use of ... in conversion to %s", T)
check.errorf(call.ArgList[0], _BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
break
}
check.conversion(x, T)
}
default:
check.use(call.ArgList...)
check.errorf(call.ArgList[n-1], "too many arguments in conversion to %s", T)
check.errorf(call.ArgList[n-1], _WrongArgCount, "too many arguments in conversion to %s", T)
}
x.expr = call
return conversion
@ -170,7 +170,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
// a type parameter may be "called" if all types have the same signature
sig, _ := coreType(x.typ).(*Signature)
if sig == nil {
check.errorf(x, invalidOp+"cannot call non-function %s", x)
check.errorf(x, _InvalidCall, invalidOp+"cannot call non-function %s", x)
x.mode = invalid
x.expr = call
return statement
@ -193,7 +193,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
// check number of type arguments (got) vs number of type parameters (want)
got, want := len(targs), sig.TypeParams().Len()
if got > want {
check.errorf(xlist[want], "got %d type arguments but want %d", got, want)
check.errorf(xlist[want], _WrongTypeArgCount, "got %d type arguments but want %d", got, want)
check.use(call.ArgList...)
x.mode = invalid
x.expr = call
@ -286,7 +286,7 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
for _, a := range args {
switch a.mode {
case typexpr:
check.errorf(a, "%s used as value", a)
check.errorf(a, 0, "%s used as value", a)
return
case invalid:
return
@ -315,7 +315,7 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
if len(call.ArgList) == 1 && nargs > 1 {
// f()... is not permitted if f() is multi-valued
//check.errorf(call.Ellipsis, "cannot use ... with %d-valued %s", nargs, call.ArgList[0])
check.errorf(call, "cannot use ... with %d-valued %s", nargs, call.ArgList[0])
check.errorf(call, _InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.ArgList[0])
return
}
} else {
@ -343,7 +343,7 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
if ddd {
// standard_func(a, b, c...)
//check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun)
check.errorf(call, "cannot use ... in call to non-variadic %s", call.Fun)
check.errorf(call, _NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
return
}
// standard_func(a, b, c)
@ -464,7 +464,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
}
}
if exp == nil {
check.errorf(e.Sel, "%s not declared by package C", sel)
check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package C", sel)
goto Error
}
check.objDecl(exp, nil)
@ -473,15 +473,15 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
if exp == nil {
if !pkg.fake {
if check.conf.CompilerErrorMessages {
check.errorf(e.Sel, "undefined: %s.%s", pkg.name, sel)
check.errorf(e.Sel, _UndeclaredImportedName, "undefined: %s.%s", pkg.name, sel)
} else {
check.errorf(e.Sel, "%s not declared by package %s", sel, pkg.name)
check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package %s", sel, pkg.name)
}
}
goto Error
}
if !exp.Exported() {
check.errorf(e.Sel, "%s not exported by package %s", sel, pkg.name)
check.errorf(e.Sel, _UnexportedName, "%s not exported by package %s", sel, pkg.name)
// ok to continue
}
}
@ -533,7 +533,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
goto Error
}
case builtin:
check.errorf(e.Pos(), "cannot select on %s", x)
check.errorf(e.Pos(), _UncalledBuiltin, "cannot select on %s", x)
goto Error
case invalid:
goto Error
@ -548,12 +548,12 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
if index != nil {
// TODO(gri) should provide actual type where the conflict happens
check.errorf(e.Sel, "ambiguous selector %s.%s", x.expr, sel)
check.errorf(e.Sel, _AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
goto Error
}
if indirect {
check.errorf(e.Sel, "cannot call pointer method %s on %s", sel, x.typ)
check.errorf(e.Sel, _InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
goto Error
}
@ -577,7 +577,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
}
}
}
check.errorf(e.Sel, "%s.%s undefined (%s)", x.expr, sel, why)
check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
goto Error
}
@ -591,7 +591,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
m, _ := obj.(*Func)
if m == nil {
// TODO(gri) should check if capitalization of sel matters and provide better error message in that case
check.errorf(e.Sel, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
goto Error
}
@ -599,7 +599,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
sig := m.typ.(*Signature)
if sig.recv == nil {
check.error(e, "illegal cycle in method declaration")
check.error(e, _InvalidDeclCycle, "illegal cycle in method declaration")
goto Error
}

View File

@ -267,7 +267,7 @@ func (check *Checker) initFiles(files []*syntax.File) {
if name != "_" {
pkg.name = name
} else {
check.error(file.PkgName, "invalid package name _")
check.error(file.PkgName, _BlankPkgName, "invalid package name _")
}
fallthrough
@ -275,7 +275,7 @@ func (check *Checker) initFiles(files []*syntax.File) {
check.files = append(check.files, file)
default:
check.errorf(file, "package %s; expected %s", name, pkg.name)
check.errorf(file, _MismatchedPkgName, "package %s; expected %s", name, pkg.name)
// ignore this file
}
}

View File

@ -378,7 +378,7 @@ func (check *Checker) constDecl(obj *Const, typ, init syntax.Expr, inherited boo
// don't report an error if the type is an invalid C (defined) type
// (issue #22090)
if under(t) != Typ[Invalid] {
check.errorf(typ, "invalid constant type %s", t)
check.errorf(typ, _InvalidConstType, "invalid constant type %s", t)
}
obj.typ = Typ[Invalid]
return
@ -505,7 +505,7 @@ 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.error(tdecl, "generic type cannot be alias")
check.error(tdecl, _BadDecl, "generic type cannot be alias")
alias = false
}
@ -548,7 +548,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
// use its underlying type (like we do for any RHS in a type declaration), and its
// underlying type is an interface and the type declaration is well defined.
if isTypeParam(rhs) {
check.error(tdecl.Type, "cannot use a type parameter as RHS in type declaration")
check.error(tdecl.Type, _MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration")
named.underlying = Typ[Invalid]
}
}
@ -594,7 +594,7 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list []*syntax.Fiel
// the underlying type and thus type set of a type parameter is.
// But we may need some additional form of cycle detection within
// type parameter lists.
check.error(f.Type, "cannot use a type parameter as constraint")
check.error(f.Type, _MisplacedTypeParam, "cannot use a type parameter as constraint")
bound = Typ[Invalid]
}
}
@ -674,6 +674,7 @@ func (check *Checker) collectMethods(obj *TypeName) {
assert(m.name != "_")
if alt := mset.insert(m); alt != nil {
var err error_
err.code = _DuplicateMethod
if check.conf.CompilerErrorMessages {
err.errorf(m.pos, "%s.%s redeclared in this block", obj.Name(), m.name)
} else {
@ -711,6 +712,7 @@ func (check *Checker) checkFieldUniqueness(base *Named) {
// For historical consistency, we report the primary error on the
// method, and the alt decl on the field.
var err error_
err.code = _DuplicateFieldAndMethod
err.errorf(alt, "field and method with the same name %s", fld.name)
err.recordAltDecl(fld)
check.report(&err)
@ -742,7 +744,7 @@ func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
obj.color_ = saved
if len(fdecl.TParamList) > 0 && fdecl.Body == nil {
check.softErrorf(fdecl, "parameterized function is missing function body")
check.softErrorf(fdecl, _BadDecl, "parameterized function is missing function body")
}
// function body must be type-checked after global declarations
@ -887,7 +889,7 @@ func (check *Checker) declStmt(list []syntax.Decl) {
check.pop().setColor(black)
default:
check.errorf(s, invalidAST+"unknown syntax.Decl node %T", s)
check.errorf(s, 0, invalidAST+"unknown syntax.Decl node %T", s)
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -38,6 +38,7 @@ func unreachable() {
// To report an error_, call Checker.report.
type error_ struct {
desc []errorDesc
code errorCode
soft bool // TODO(gri) eventually determine this from an error code
}
@ -197,7 +198,7 @@ func (check *Checker) report(err *error_) {
if err.empty() {
panic("no error to report")
}
check.err(err.pos(), err.msg(check.qualifier), err.soft)
check.err(err.pos(), err.code, err.msg(check.qualifier), err.soft)
}
func (check *Checker) trace(pos syntax.Pos, format string, args ...interface{}) {
@ -213,7 +214,7 @@ func (check *Checker) dump(format string, args ...interface{}) {
fmt.Println(sprintf(check.qualifier, true, format, args...))
}
func (check *Checker) err(at poser, msg string, soft bool) {
func (check *Checker) err(at poser, code errorCode, 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
@ -262,16 +263,16 @@ type poser interface {
Pos() syntax.Pos
}
func (check *Checker) error(at poser, msg string) {
check.err(at, msg, false)
func (check *Checker) error(at poser, code errorCode, msg string) {
check.err(at, code, msg, false)
}
func (check *Checker) errorf(at poser, format string, args ...interface{}) {
check.err(at, check.sprintf(format, args...), false)
func (check *Checker) errorf(at poser, code errorCode, format string, args ...interface{}) {
check.err(at, code, check.sprintf(format, args...), false)
}
func (check *Checker) softErrorf(at poser, format string, args ...interface{}) {
check.err(at, check.sprintf(format, args...), true)
func (check *Checker) softErrorf(at poser, code errorCode, format string, args ...interface{}) {
check.err(at, code, check.sprintf(format, args...), true)
}
func (check *Checker) versionErrorf(at poser, goVersion string, format string, args ...interface{}) {
@ -281,7 +282,7 @@ func (check *Checker) versionErrorf(at poser, goVersion string, format string, a
} else {
msg = fmt.Sprintf("%s requires %s or later", msg, goVersion)
}
check.err(at, msg, true)
check.err(at, _UnsupportedFeature, msg, true)
}
// posFor reports the left (= start) position of at.

View File

@ -73,11 +73,11 @@ func init() {
func (check *Checker) op(m opPredicates, x *operand, op syntax.Operator) bool {
if pred := m[op]; pred != nil {
if !pred(x.typ) {
check.errorf(x, invalidOp+"operator %s not defined on %s", op, x)
check.errorf(x, _UndefinedOp, invalidOp+"operator %s not defined on %s", op, x)
return false
}
} else {
check.errorf(x, invalidAST+"unknown operator %s", op)
check.errorf(x, 0, invalidAST+"unknown operator %s", op)
return false
}
return true
@ -93,7 +93,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.error(opPos(x.expr), "constant result is not representable")
check.error(opPos(x.expr), _InvalidConstVal, "constant result is not representable")
return
}
@ -113,7 +113,7 @@ func (check *Checker) overflow(x *operand) {
if op != "" {
op += " "
}
check.errorf(opPos(x.expr), "constant %soverflow", op)
check.errorf(opPos(x.expr), _InvalidConstVal, "constant %soverflow", op)
x.val = constant.MakeUnknown()
}
}
@ -182,7 +182,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.errorf(x, invalidOp+"cannot take address of %s", x)
check.errorf(x, _UnaddressableOperand, invalidOp+"cannot take address of %s", x)
x.mode = invalid
return
}
@ -193,18 +193,18 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
case syntax.Recv:
u := coreType(x.typ)
if u == nil {
check.errorf(x, invalidOp+"cannot receive from %s: no core type", x)
check.errorf(x, _InvalidReceive, invalidOp+"cannot receive from %s: no core type", x)
x.mode = invalid
return
}
ch, _ := u.(*Chan)
if ch == nil {
check.errorf(x, invalidOp+"cannot receive from non-channel %s", x)
check.errorf(x, _InvalidReceive, invalidOp+"cannot receive from non-channel %s", x)
x.mode = invalid
return
}
if ch.dir == SendOnly {
check.errorf(x, invalidOp+"cannot receive from send-only channel %s", x)
check.errorf(x, _InvalidReceive, invalidOp+"cannot receive from send-only channel %s", x)
x.mode = invalid
return
}
@ -215,7 +215,7 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
case syntax.Tilde:
// Provide a better error position and message than what check.op below could do.
check.error(e, "cannot use ~ outside of interface or type constraint")
check.error(e, _UndefinedOp, "cannot use ~ outside of interface or type constraint")
x.mode = invalid
return
}
@ -435,30 +435,6 @@ func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *c
return false
}
// An errorCode is a (constant) value uniquely identifing a specific error.
type errorCode int
// The following error codes are "borrowed" from go/types which codes for
// all errors. Here we list the few codes currently needed by the various
// conversion checking functions.
// Eventually we will switch to reporting codes for all errors, using a
// an error code table shared between types2 and go/types.
const (
_ = errorCode(iota)
_TruncatedFloat
_NumericOverflow
_InvalidConstVal
_InvalidUntypedConversion
// The following error codes are only returned by operand.assignableTo
// and none of its callers use the error. Still, we keep returning the
// error codes to make the transition to reporting error codes all the
// time easier in the future.
_IncompatibleAssign
_InvalidIfaceAssign
_InvalidChanAssign
)
// representable checks that a constant operand is representable in the given
// basic type.
func (check *Checker) representable(x *operand, typ *Basic) {
@ -507,7 +483,7 @@ func (check *Checker) invalidConversion(code errorCode, x *operand, target Type)
case _NumericOverflow:
msg = "%s overflows %s"
}
check.errorf(x, msg, x, target)
check.errorf(x, code, msg, x, target)
}
// updateExprType updates the type of x to typ and invokes itself
@ -641,9 +617,9 @@ func (check *Checker) updateExprType0(parent, x syntax.Expr, typ Type, final boo
// as an integer if it is a constant.
if !allInteger(typ) {
if check.conf.CompilerErrorMessages {
check.errorf(x, invalidOp+"%s (shift of type %s)", parent, typ)
check.errorf(x, _InvalidShiftOperand, invalidOp+"%s (shift of type %s)", parent, typ)
} else {
check.errorf(x, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
check.errorf(x, _InvalidShiftOperand, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
}
return
}
@ -802,6 +778,7 @@ func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase b
// spec: "In any comparison, the first operand must be assignable
// to the type of the second operand, or vice versa."
code := _MismatchedTypes
ok, _ := x.assignableTo(check, y.typ, nil)
if !ok {
ok, _ = y.assignableTo(check, x.typ, nil)
@ -821,6 +798,7 @@ func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase b
}
// check if comparison is defined for operands
code = _UndefinedOp
switch op {
case syntax.Eql, syntax.Neq:
// spec: "The equality operators == and != apply to operands that are comparable."
@ -900,12 +878,12 @@ Error:
}
}
if switchCase {
check.errorf(x, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
check.errorf(x, code, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
} else {
if check.conf.CompilerErrorMessages {
check.errorf(errOp, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
} else {
check.errorf(errOp, invalidOp+"cannot compare %s %s %s (%s)", x.expr, op, y.expr, cause)
check.errorf(errOp, code, invalidOp+"cannot compare %s %s %s (%s)", x.expr, op, y.expr, cause)
}
}
x.mode = invalid
@ -967,7 +945,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.errorf(x, invalidOp+"shifted operand %s must be integer", x)
check.errorf(x, _InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
x.mode = invalid
return
}
@ -981,7 +959,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
// Provide a good error message for negative shift counts.
yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
check.errorf(y, invalidOp+"negative shift count %s", y)
check.errorf(y, _InvalidShiftCount, invalidOp+"negative shift count %s", y)
x.mode = invalid
return
}
@ -1000,7 +978,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
switch {
case allInteger(y.typ):
if !allUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
check.errorf(y, invalidOp+"signed shift count %s requires go1.13 or later", y)
check.errorf(y, _InvalidShiftCount, invalidOp+"signed shift count %s requires go1.13 or later", y)
x.mode = invalid
return
}
@ -1013,7 +991,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
return
}
default:
check.errorf(y, invalidOp+"shift count %s must be integer", y)
check.errorf(y, _InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
x.mode = invalid
return
}
@ -1034,7 +1012,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.errorf(y, invalidOp+"invalid shift count %s", y)
check.errorf(y, _InvalidShiftCount, invalidOp+"invalid shift count %s", y)
x.mode = invalid
return
}
@ -1085,7 +1063,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
// non-constant shift - lhs must be an integer
if !allInteger(x.typ) {
check.errorf(x, invalidOp+"shifted operand %s must be integer", x)
check.errorf(x, _InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
x.mode = invalid
return
}
@ -1177,9 +1155,9 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
// (otherwise we had an error reported elsewhere already)
if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] {
if e != nil {
check.errorf(x, invalidOp+"%s (mismatched types %s and %s)", e, x.typ, y.typ)
check.errorf(x, _MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ, y.typ)
} else {
check.errorf(x, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ, y.typ)
check.errorf(x, _MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ, y.typ)
}
}
x.mode = invalid
@ -1194,7 +1172,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_ || allInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
check.error(&y, invalidOp+"division by zero")
check.error(&y, _DivByZero, invalidOp+"division by zero")
x.mode = invalid
return
}
@ -1204,7 +1182,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.error(&y, invalidOp+"division by zero")
check.error(&y, _DivByZero, invalidOp+"division by zero")
x.mode = invalid
return
}
@ -1287,7 +1265,7 @@ func (check *Checker) nonGeneric(x *operand) {
}
}
if what != "" {
check.errorf(x.expr, "cannot use generic %s %s without instantiation", what, x.expr)
check.errorf(x.expr, _WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
x.mode = invalid
x.typ = Typ[Invalid]
}
@ -1314,7 +1292,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
case *syntax.DotsType:
// dots are handled explicitly where they are legal
// (array composite literals and parameter lists)
check.error(e, "invalid use of '...'")
check.error(e, _BadDotDotDotSyntax, "invalid use of '...'")
goto Error
case *syntax.BasicLit:
@ -1335,7 +1313,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// allows for separators between all digits.
const limit = 10000
if len(e.Value) > limit {
check.errorf(e, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
check.errorf(e, _InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
goto Error
}
}
@ -1345,7 +1323,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// If we reach here it's because of number under-/overflow.
// TODO(gri) setConst (and in turn the go/constant package)
// should return an error describing the issue.
check.errorf(e, "malformed constant: %s", e.Value)
check.errorf(e, _InvalidConstVal, "malformed constant: %s", e.Value)
goto Error
}
// Ensure that integer values don't overflow (issue #54280).
@ -1371,7 +1349,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
x.mode = value
x.typ = sig
} else {
check.errorf(e, invalidAST+"invalid function literal %v", e)
check.errorf(e, 0, invalidAST+"invalid function literal %v", e)
goto Error
}
@ -1399,13 +1377,13 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
typ = hint
base, _ = deref(coreType(typ)) // *T implies &T{}
if base == nil {
check.errorf(e, "invalid composite literal element type %s: no core type", typ)
check.errorf(e, _InvalidLit, "invalid composite literal element type %s: no core type", typ)
goto Error
}
default:
// TODO(gri) provide better error messages depending on context
check.error(e, "missing type in composite literal")
check.error(e, _UntypedLit, "missing type in composite literal")
goto Error
}
@ -1414,7 +1392,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// Prevent crash if the struct referred to is not yet set up.
// See analogous comment for *Array.
if utyp.fields == nil {
check.error(e, "illegal cycle in type declaration")
check.error(e, _InvalidDeclCycle, "illegal cycle in type declaration")
goto Error
}
if len(e.ElemList) == 0 {
@ -1427,7 +1405,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
for _, e := range e.ElemList {
kv, _ := e.(*syntax.KeyValueExpr)
if kv == nil {
check.error(e, "mixture of field:value and value elements in struct literal")
check.error(e, _MixedStructLit, "mixture of field:value and value elements in struct literal")
continue
}
key, _ := kv.Key.(*syntax.Name)
@ -1435,15 +1413,15 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// so we don't drop information on the floor
check.expr(x, kv.Value)
if key == nil {
check.errorf(kv, "invalid field name %s in struct literal", kv.Key)
check.errorf(kv, _InvalidLitField, "invalid field name %s in struct literal", kv.Key)
continue
}
i := fieldIndex(utyp.fields, check.pkg, key.Value)
if i < 0 {
if check.conf.CompilerErrorMessages {
check.errorf(kv.Key, "unknown field '%s' in struct literal of type %s", key.Value, base)
check.errorf(kv.Key, _MissingLitField, "unknown field '%s' in struct literal of type %s", key.Value, base)
} else {
check.errorf(kv.Key, "unknown field %s in struct literal", key.Value)
check.errorf(kv.Key, _MissingLitField, "unknown field %s in struct literal", key.Value)
}
continue
}
@ -1453,7 +1431,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
check.assignment(x, etyp, "struct literal")
// 0 <= i < len(fields)
if visited[i] {
check.errorf(kv, "duplicate field name %s in struct literal", key.Value)
check.errorf(kv, _DuplicateLitField, "duplicate field name %s in struct literal", key.Value)
continue
}
visited[i] = true
@ -1462,25 +1440,25 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// no element must have a key
for i, e := range e.ElemList {
if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
check.error(kv, "mixture of field:value and value elements in struct literal")
check.error(kv, _MixedStructLit, "mixture of field:value and value elements in struct literal")
continue
}
check.expr(x, e)
if i >= len(fields) {
check.errorf(x, "too many values in %s{…}", base)
check.errorf(x, _InvalidStructLit, "too many values in %s{…}", base)
break // cannot continue
}
// i < len(fields)
fld := fields[i]
if !fld.Exported() && fld.pkg != check.pkg {
check.errorf(x, "implicit assignment to unexported field %s in %s literal", fld.name, typ)
check.errorf(x, _UnexportedLitField, "implicit assignment to unexported field %s in %s literal", fld.name, typ)
continue
}
etyp := fld.typ
check.assignment(x, etyp, "struct literal")
}
if len(e.ElemList) < len(fields) {
check.errorf(e.Rbrace, "too few values in %s{…}", base)
check.errorf(e.Rbrace, _InvalidStructLit, "too few values in %s{…}", base)
// ok to continue
}
}
@ -1490,7 +1468,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// This is a stop-gap solution. Should use Checker.objPath to report entire
// path starting with earliest declaration in the source. TODO(gri) fix this.
if utyp.elem == nil {
check.error(e, "illegal cycle in type declaration")
check.error(e, _InvalidTypeCycle, "illegal cycle in type declaration")
goto Error
}
n := check.indexedElts(e.ElemList, utyp.elem, utyp.len)
@ -1517,7 +1495,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// Prevent crash if the slice referred to is not yet set up.
// See analogous comment for *Array.
if utyp.elem == nil {
check.error(e, "illegal cycle in type declaration")
check.error(e, _InvalidTypeCycle, "illegal cycle in type declaration")
goto Error
}
check.indexedElts(e.ElemList, utyp.elem, -1)
@ -1526,7 +1504,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
// Prevent crash if the map referred to is not yet set up.
// See analogous comment for *Array.
if utyp.key == nil || utyp.elem == nil {
check.error(e, "illegal cycle in type declaration")
check.error(e, _InvalidTypeCycle, "illegal cycle in type declaration")
goto Error
}
// If the map key type is an interface (but not a type parameter),
@ -1537,7 +1515,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
for _, e := range e.ElemList {
kv, _ := e.(*syntax.KeyValueExpr)
if kv == nil {
check.error(e, "missing key in map literal")
check.error(e, _MissingLitKey, "missing key in map literal")
continue
}
check.exprWithHint(x, kv.Key, utyp.key)
@ -1561,7 +1539,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
visited[xkey] = nil
}
if duplicate {
check.errorf(x, "duplicate key %s in map literal", x.val)
check.errorf(x, _DuplicateLitKey, "duplicate key %s in map literal", x.val)
continue
}
}
@ -1583,7 +1561,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
}
// if utyp is invalid, an error was reported before
if utyp != Typ[Invalid] {
check.errorf(e, "invalid composite literal type %s", typ)
check.errorf(e, _InvalidLit, "invalid composite literal type %s", typ)
goto Error
}
}
@ -1620,16 +1598,16 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
}
// TODO(gri) we may want to permit type assertions on type parameter values at some point
if isTypeParam(x.typ) {
check.errorf(x, invalidOp+"cannot use type assertion on type parameter value %s", x)
check.errorf(x, _InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
goto Error
}
if _, ok := under(x.typ).(*Interface); !ok {
check.errorf(x, invalidOp+"%s is not an interface", x)
check.errorf(x, _InvalidAssert, invalidOp+"%s is not an interface", x)
goto Error
}
// x.(type) expressions are encoded via TypeSwitchGuards
if e.Type == nil {
check.error(e, invalidAST+"invalid use of AssertExpr")
check.error(e, 0, invalidAST+"invalid use of AssertExpr")
goto Error
}
T := check.varType(e.Type)
@ -1642,7 +1620,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.error(e, invalidAST+"use of .(type) outside type switch")
check.error(e, 0, invalidAST+"use of .(type) outside type switch")
goto Error
case *syntax.CallExpr:
@ -1650,7 +1628,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
case *syntax.ListExpr:
// catch-all for unexpected expression lists
check.error(e, "unexpected list of expressions")
check.error(e, 0, invalidAST+"unexpected list of expressions")
goto Error
// case *syntax.UnaryExpr:
@ -1690,11 +1668,11 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
if !underIs(x.typ, func(u Type) bool {
p, _ := u.(*Pointer)
if p == nil {
check.errorf(x, invalidOp+"cannot indirect %s", x)
check.errorf(x, _InvalidIndirection, invalidOp+"cannot indirect %s", x)
return false
}
if base != nil && !Identical(p.base, base) {
check.errorf(x, invalidOp+"pointers of %s must have identical base types", x)
check.errorf(x, _InvalidIndirection, invalidOp+"pointers of %s must have identical base types", x)
return false
}
base = p.base
@ -1727,7 +1705,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.error(e, invalidAST+"no key:value expected")
check.error(e, 0, invalidAST+"no key:value expected")
goto Error
case *syntax.ArrayType, *syntax.SliceType, *syntax.StructType, *syntax.FuncType,
@ -1806,11 +1784,11 @@ func (check *Checker) typeAssertion(e syntax.Expr, x *operand, T Type, typeSwitc
cause := check.missingMethodReason(T, x.typ, method, alt)
if typeSwitch {
check.errorf(e, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
check.errorf(e, _ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
return
}
check.errorf(e, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
check.errorf(e, _ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
}
// expr typechecks expression e and initializes x with the expression value.
@ -1853,6 +1831,7 @@ func (check *Checker) exprOrType(x *operand, e syntax.Expr, allowGeneric bool) {
func (check *Checker) exclude(x *operand, modeset uint) {
if modeset&(1<<x.mode) != 0 {
var msg string
var code errorCode
switch x.mode {
case novalue:
if modeset&(1<<typexpr) != 0 {
@ -1860,14 +1839,17 @@ func (check *Checker) exclude(x *operand, modeset uint) {
} else {
msg = "%s used as value or type"
}
code = _TooManyValues
case builtin:
msg = "%s must be called"
code = _UncalledBuiltin
case typexpr:
msg = "%s is not an expression"
code = _NotAnExpr
default:
unreachable()
}
check.errorf(x, msg, x)
check.errorf(x, code, msg, x)
x.mode = invalid
}
}
@ -1879,9 +1861,9 @@ func (check *Checker) singleValue(x *operand) {
if t, ok := x.typ.(*Tuple); ok {
assert(t.Len() != 1)
if check.conf.CompilerErrorMessages {
check.errorf(x, "multiple-value %s in single-value context", x)
check.errorf(x, _TooManyValues, "multiple-value %s in single-value context", x)
} else {
check.errorf(x, "%d-valued %s where single value is expected", t.Len(), x)
check.errorf(x, _TooManyValues, "%d-valued %s where single value is expected", t.Len(), x)
}
x.mode = invalid
}

View File

@ -182,7 +182,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
}
if !valid {
check.errorf(e.Pos(), invalidOp+"cannot index %s", x)
check.errorf(e.Pos(), _NonSliceableOperand, invalidOp+"cannot index %s", x)
x.mode = invalid
return false
}
@ -215,7 +215,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
length := int64(-1) // valid if >= 0
switch u := coreString(x.typ).(type) {
case nil:
check.errorf(x, invalidOp+"cannot slice %s: %s has no core type", x, x.typ)
check.errorf(x, _NonSliceableOperand, invalidOp+"cannot slice %s: %s has no core type", x, x.typ)
x.mode = invalid
return
@ -226,7 +226,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
if at == nil {
at = e // e.Index[2] should be present but be careful
}
check.error(at, invalidOp+"3-index slice of string")
check.error(at, _InvalidSliceExpr, invalidOp+"3-index slice of string")
x.mode = invalid
return
}
@ -245,7 +245,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
valid = true
length = u.len
if x.mode != variable {
check.errorf(x, invalidOp+"%s (slice of unaddressable value)", x)
check.errorf(x, _NonSliceableOperand, invalidOp+"%s (slice of unaddressable value)", x)
x.mode = invalid
return
}
@ -264,7 +264,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
}
if !valid {
check.errorf(x, invalidOp+"cannot slice %s", x)
check.errorf(x, _NonSliceableOperand, invalidOp+"cannot slice %s", x)
x.mode = invalid
return
}
@ -273,7 +273,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
// spec: "Only the first index may be omitted; it defaults to 0."
if e.Full && (e.Index[1] == nil || e.Index[2] == nil) {
check.error(e, invalidAST+"2nd and 3rd index required in 3-index slice")
check.error(e, 0, invalidAST+"2nd and 3rd index required in 3-index slice")
x.mode = invalid
return
}
@ -314,7 +314,7 @@ L:
// The value y corresponds to the expression e.Index[i+1+j].
// Because y >= 0, it must have been set from the expression
// when checking indices and thus e.Index[i+1+j] is not nil.
check.errorf(e.Index[i+1+j], "invalid slice indices: %d < %d", y, x)
check.errorf(e.Index[i+1+j], _SwappedSliceIndices, "invalid slice indices: %d < %d", y, x)
break L // only report one error, ok to continue
}
}
@ -328,16 +328,16 @@ L:
func (check *Checker) singleIndex(e *syntax.IndexExpr) syntax.Expr {
index := e.Index
if index == nil {
check.errorf(e, invalidAST+"missing index for %s", e.X)
check.errorf(e, 0, invalidAST+"missing index for %s", e.X)
return nil
}
if l, _ := index.(*syntax.ListExpr); l != nil {
if n := len(l.ElemList); n <= 1 {
check.errorf(e, invalidAST+"invalid use of ListExpr for index expression %v with %d indices", e, n)
check.errorf(e, 0, invalidAST+"invalid use of ListExpr for index expression %v with %d indices", e, n)
return nil
}
// len(l.ElemList) > 1
check.error(l.ElemList[1], invalidOp+"more than one index")
check.error(l.ElemList[1], _InvalidIndex, invalidOp+"more than one index")
index = l.ElemList[0] // continue with first index
}
return index
@ -353,7 +353,7 @@ func (check *Checker) index(index syntax.Expr, max int64) (typ Type, val int64)
var x operand
check.expr(&x, index)
if !check.isValidIndex(&x, "index", false) {
if !check.isValidIndex(&x, _InvalidIndex, "index", false) {
return
}
@ -368,7 +368,7 @@ func (check *Checker) index(index syntax.Expr, max int64) (typ Type, val int64)
v, ok := constant.Int64Val(x.val)
assert(ok)
if max >= 0 && v >= max {
check.errorf(&x, invalidArg+"index %s out of bounds [0:%d]", x.val.String(), max)
check.errorf(&x, _InvalidIndex, invalidArg+"index %s out of bounds [0:%d]", x.val.String(), max)
return
}
@ -380,7 +380,7 @@ func (check *Checker) index(index syntax.Expr, max int64) (typ Type, val int64)
// index values. If allowNegative is set, a constant operand may be negative.
// If the operand is not valid, an error is reported (using what as context)
// and the result is false.
func (check *Checker) isValidIndex(x *operand, what string, allowNegative bool) bool {
func (check *Checker) isValidIndex(x *operand, code errorCode, what string, allowNegative bool) bool {
if x.mode == invalid {
return false
}
@ -393,20 +393,20 @@ func (check *Checker) isValidIndex(x *operand, what string, allowNegative bool)
// spec: "the index x must be of integer type or an untyped constant"
if !allInteger(x.typ) {
check.errorf(x, invalidArg+"%s %s must be integer", what, x)
check.errorf(x, code, invalidArg+"%s %s must be integer", what, x)
return false
}
if x.mode == constant_ {
// spec: "a constant index must be non-negative ..."
if !allowNegative && constant.Sign(x.val) < 0 {
check.errorf(x, invalidArg+"%s %s must not be negative", what, x)
check.errorf(x, code, invalidArg+"%s %s must not be negative", what, x)
return false
}
// spec: "... and representable by a value of type int"
if !representableConst(x.val, check, Typ[Int], &x.val) {
check.errorf(x, invalidArg+"%s %s overflows int", what, x)
check.errorf(x, code, invalidArg+"%s %s overflows int", what, x)
return false
}
}
@ -431,12 +431,12 @@ func (check *Checker) indexedElts(elts []syntax.Expr, typ Type, length int64) in
index = i
validIndex = true
} else {
check.errorf(e, "index %s must be integer constant", kv.Key)
check.errorf(e, _InvalidLitIndex, "index %s must be integer constant", kv.Key)
}
}
eval = kv.Value
} else if length >= 0 && index >= length {
check.errorf(e, "index %d is out of bounds (>= %d)", index, length)
check.errorf(e, _OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
} else {
validIndex = true
}
@ -444,7 +444,7 @@ func (check *Checker) indexedElts(elts []syntax.Expr, typ Type, length int64) in
// if we have a valid index, check for duplicate entries
if validIndex {
if visited[index] {
check.errorf(e, "duplicate index %d in array or slice literal", index)
check.errorf(e, _DuplicateLitKey, "duplicate index %d in array or slice literal", index)
}
visited[index] = true
}

View File

@ -216,16 +216,20 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
}
}
if allFailed {
check.errorf(arg, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeParamsString(tparams))
check.errorf(arg, _CannotInferTypeArgs, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeParamsString(tparams))
return
}
}
smap := makeSubstMap(tparams, targs)
inferred := check.subst(arg.Pos(), tpar, smap, nil, check.context())
// _CannotInferTypeArgs indicates a failure of inference, though the actual
// error may be better attributed to a user-provided type argument (hence
// _InvalidTypeArg). We can't differentiate these cases, so fall back on
// the more general _CannotInferTypeArgs.
if inferred != tpar {
check.errorf(arg, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
check.errorf(arg, _CannotInferTypeArgs, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
} else {
check.errorf(arg, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
check.errorf(arg, _CannotInferTypeArgs, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
}
}
@ -319,7 +323,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
// At least one type argument couldn't be inferred.
assert(targs != nil && index >= 0 && targs[index] == nil)
tpar := tparams[index]
check.errorf(pos, "cannot infer %s (%s)", tpar.obj.name, tpar.obj.pos)
check.errorf(pos, _CannotInferTypeArgs, "cannot infer %s (%s)", tpar.obj.name, tpar.obj.pos)
return nil
}
@ -532,7 +536,7 @@ func (check *Checker) inferB(pos syntax.Pos, tparams []*TypeParam, targs []Type)
if core.tilde {
tilde = "~"
}
check.errorf(pos, "%s does not match %s%s", tpar, tilde, core.typ)
check.errorf(pos, _InvalidTypeArg, "%s does not match %s%s", tpar, tilde, core.typ)
return nil, 0
}

View File

@ -156,7 +156,7 @@ func (check *Checker) validateTArgLen(pos syntax.Pos, ntparams, ntargs int) bool
if ntargs != ntparams {
// TODO(gri) provide better error message
if check != nil {
check.errorf(pos, "got %d arguments but %d type parameters", ntargs, ntparams)
check.errorf(pos, _WrongTypeArgCount, "got %d arguments but %d type parameters", ntargs, ntparams)
return false
}
panic(fmt.Sprintf("%v: got %d arguments but %d type parameters", pos, ntargs, ntparams))

View File

@ -132,7 +132,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
// We have a method with name f.Name.
name := f.Name.Value
if name == "_" {
check.error(f.Name, "methods must have a unique non-blank name")
check.error(f.Name, _BlankIfaceMethod, "methods must have a unique non-blank name")
continue // ignore
}
@ -140,7 +140,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
sig, _ := typ.(*Signature)
if sig == nil {
if typ != Typ[Invalid] {
check.errorf(f.Type, invalidAST+"%s is not a method signature", typ)
check.errorf(f.Type, 0, invalidAST+"%s is not a method signature", typ)
}
continue // ignore
}

View File

@ -21,21 +21,24 @@ func (check *Checker) labels(body *syntax.BlockStmt) {
// for the respective gotos.
for _, jmp := range fwdJumps {
var msg string
var code errorCode
name := jmp.Label.Value
if alt := all.Lookup(name); alt != nil {
msg = "goto %s jumps into block"
alt.(*Label).used = true // avoid another error
code = _JumpIntoBlock
} else {
msg = "label %s not declared"
code = _UndeclaredLabel
}
check.errorf(jmp.Label, msg, name)
check.errorf(jmp.Label, code, msg, name)
}
// spec: "It is illegal to define a label that is never used."
for name, obj := range all.elems {
obj = resolve(name, obj)
if lbl := obj.(*Label); !lbl.used {
check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name)
check.softErrorf(lbl.pos, _UnusedLabel, "label %s declared but not used", lbl.name)
}
}
}
@ -149,6 +152,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.Lab
if jumpsOverVarDecl(jmp) {
check.softErrorf(
jmp.Label,
_JumpOverDecl,
"goto %s jumps over variable declaration at line %d",
name,
varDeclPos.Line(),
@ -186,7 +190,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.Lab
}
}
if !valid {
check.errorf(s.Label, "invalid break label %s", name)
check.errorf(s.Label, _MisplacedLabel, "invalid break label %s", name)
return
}
@ -201,7 +205,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.Lab
}
}
if !valid {
check.errorf(s.Label, "invalid continue label %s", name)
check.errorf(s.Label, _MisplacedLabel, "invalid continue label %s", name)
return
}
@ -213,7 +217,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.Lab
}
default:
check.errorf(s, invalidAST+"branch statement: %s %s", s.Tok, name)
check.errorf(s, 0, invalidAST+"branch statement: %s %s", s.Tok, name)
return
}

View File

@ -52,17 +52,18 @@ func (check *Checker) arity(pos syntax.Pos, names []*syntax.Name, inits []syntax
l := len(names)
r := len(inits)
const code = _WrongAssignCount
switch {
case l < r:
n := inits[l]
if inherited {
check.errorf(pos, "extra init expr at %s", n.Pos())
check.errorf(pos, code, "extra init expr at %s", n.Pos())
} else {
check.errorf(n, "extra init expr %s", n)
check.errorf(n, code, "extra init expr %s", n)
}
case l > r && (constDecl || r != 1): // if r == 1 it may be a multi-valued function and we can't say anything yet
n := names[r]
check.errorf(n, "missing init expr for %s", n.Value)
check.errorf(n, code, "missing init expr for %s", n.Value)
}
}
@ -91,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.error(ident, "cannot declare init - must be func")
check.error(ident, _InvalidInitDecl, "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.error(ident, "cannot declare main - must be func")
check.error(ident, _InvalidMainDecl, "cannot declare main - must be func")
return
}
@ -158,7 +159,7 @@ func (check *Checker) importPackage(pos syntax.Pos, path, dir string) *Package {
imp = nil // create fake package below
}
if err != nil {
check.errorf(pos, "could not import %s (%s)", path, err)
check.errorf(pos, _BrokenImport, "could not import %s (%s)", path, err)
if imp == nil {
// create a new fake package
// come up with a sensible package name (heuristic)
@ -245,7 +246,7 @@ func (check *Checker) collectObjects() {
}
path, err := validatedImportPath(s.Path.Value)
if err != nil {
check.errorf(s.Path, "invalid import path (%s)", err)
check.errorf(s.Path, _BadImportPath, "invalid import path (%s)", err)
continue
}
@ -260,13 +261,13 @@ func (check *Checker) collectObjects() {
name = s.LocalPkgName.Value
if path == "C" {
// match 1.17 cmd/compile (not prescribed by spec)
check.error(s.LocalPkgName, `cannot rename import "C"`)
check.error(s.LocalPkgName, _ImportCRenamed, `cannot rename import "C"`)
continue
}
}
if name == "init" {
check.error(s, "cannot import package as init - init must be a func")
check.error(s, _InvalidInitDecl, "cannot import package as init - init must be a func")
continue
}
@ -416,12 +417,16 @@ func (check *Checker) collectObjects() {
if s.Recv == nil {
// regular function
if name == "init" || name == "main" && pkg.name == "main" {
code := _InvalidInitDecl
if name == "main" {
code = _InvalidMainDecl
}
if len(s.TParamList) != 0 {
check.softErrorf(s.TParamList[0], "func %s must have no type parameters", name)
check.softErrorf(s.TParamList[0], code, "func %s must have no type parameters", name)
hasTParamError = true
}
if t := s.Type; len(t.ParamList) != 0 || len(t.ResultList) != 0 {
check.softErrorf(s.Name, "func %s must have no arguments and no return values", name)
check.softErrorf(s.Name, code, "func %s must have no arguments and no return values", name)
}
}
// don't declare init functions in the package scope - they are invisible
@ -431,7 +436,7 @@ func (check *Checker) collectObjects() {
// init functions must have a body
if s.Body == nil {
// TODO(gri) make this error message consistent with the others above
check.softErrorf(obj.pos, "missing function body")
check.softErrorf(obj.pos, _MissingInitBody, "missing function body")
}
} else {
check.declare(pkg.scope, s.Name, obj, nopos)
@ -460,7 +465,7 @@ func (check *Checker) collectObjects() {
obj.setOrder(uint32(len(check.objMap)))
default:
check.errorf(s, invalidAST+"unknown syntax.Decl node %T", s)
check.errorf(s, 0, invalidAST+"unknown syntax.Decl node %T", s)
}
}
}
@ -471,6 +476,7 @@ func (check *Checker) collectObjects() {
if alt := pkg.scope.Lookup(name); alt != nil {
obj = resolve(name, obj)
var err error_
err.code = _DuplicateDecl
if pkg, ok := obj.(*PkgName); ok {
err.errorf(alt, "%s already declared through import of %s", alt.Name(), pkg.Imported())
err.recordAltDecl(pkg)
@ -542,9 +548,9 @@ L: // unpack receiver type
case *syntax.BadExpr:
// ignore - error already reported by parser
case nil:
check.error(ptyp, invalidAST+"parameterized receiver contains nil parameters")
check.error(ptyp, 0, invalidAST+"parameterized receiver contains nil parameters")
default:
check.errorf(arg, "receiver type parameter %s must be an identifier", arg)
check.errorf(arg, _BadDecl, "receiver type parameter %s must be an identifier", arg)
}
if par == nil {
par = syntax.NewName(arg.Pos(), "_")
@ -721,15 +727,15 @@ func (check *Checker) errorUnusedPkg(obj *PkgName) {
}
if obj.name == "" || obj.name == "." || obj.name == elem {
if check.conf.CompilerErrorMessages {
check.softErrorf(obj, "imported and not used: %q", path)
check.softErrorf(obj, _UnusedImport, "imported and not used: %q", path)
} else {
check.softErrorf(obj, "%q imported but not used", path)
check.softErrorf(obj, _UnusedImport, "%q imported but not used", path)
}
} else {
if check.conf.CompilerErrorMessages {
check.softErrorf(obj, "imported and not used: %q as %s", path, obj.name)
check.softErrorf(obj, _UnusedImport, "imported and not used: %q as %s", path, obj.name)
} else {
check.softErrorf(obj, "%q imported but not used as %s", path, obj.name)
check.softErrorf(obj, _UnusedImport, "%q imported but not used as %s", path, obj.name)
}
}
}

View File

@ -151,7 +151,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
// may lead to follow-on errors (see issues #51339, #51343).
// TODO(gri) find a better solution
got := measure(len(tparams), "type parameter")
check.errorf(recvPar, "got %s, but receiver base type declares %d", got, len(recvTParams))
check.errorf(recvPar, _BadRecv, "got %s, but receiver base type declares %d", got, len(recvTParams))
}
}
}
@ -189,7 +189,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
recv = NewParam(nopos, nil, "", Typ[Invalid]) // ignore recv below
default:
// more than one receiver
check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
check.error(recvList[len(recvList)-1].Pos(), _InvalidRecv, "method must have exactly one receiver")
fallthrough // continue with first receiver
case 1:
recv = recvList[0]
@ -212,11 +212,11 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
// The receiver type may be an instantiated type referred to
// by an alias (which cannot have receiver parameters for now).
if T.TypeArgs() != nil && sig.RecvTypeParams() == nil {
check.errorf(recv, "cannot define new methods on instantiated type %s", rtyp)
check.errorf(recv, _InvalidRecv, "cannot define new methods on instantiated type %s", rtyp)
break
}
if T.obj.pkg != check.pkg {
check.errorf(recv, "cannot define new methods on non-local type %s", rtyp)
check.errorf(recv, _InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
break
}
var cause string
@ -234,12 +234,12 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
unreachable()
}
if cause != "" {
check.errorf(recv, "invalid receiver type %s (%s)", rtyp, cause)
check.errorf(recv, _InvalidRecv, "invalid receiver type %s (%s)", rtyp, cause)
}
case *Basic:
check.errorf(recv, "cannot define new methods on non-local type %s", rtyp)
check.errorf(recv, _InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
default:
check.errorf(recv, "invalid receiver type %s", recv.typ)
check.errorf(recv, _InvalidRecv, "invalid receiver type %s", recv.typ)
}
}).describef(recv, "validate receiver %s", recv)
}
@ -270,7 +270,7 @@ func (check *Checker) collectParams(scope *Scope, list []*syntax.Field, variadic
if variadicOk && i == len(list)-1 {
variadic = true
} else {
check.softErrorf(t, "can only use ... with final parameter in list")
check.softErrorf(t, _MisplacedDotDotDot, "can only use ... with final parameter in list")
// ignore ... and continue
}
}
@ -282,7 +282,7 @@ func (check *Checker) collectParams(scope *Scope, list []*syntax.Field, variadic
// named parameter
name := field.Name.Value
if name == "" {
check.error(field.Name, invalidAST+"anonymous parameter")
check.error(field.Name, 0, invalidAST+"anonymous parameter")
// ok to continue
}
par := NewParam(field.Name.Pos(), check.pkg, name, typ)
@ -299,7 +299,7 @@ func (check *Checker) collectParams(scope *Scope, list []*syntax.Field, variadic
}
if named && anonymous {
check.error(list[0], invalidAST+"list contains both named and anonymous parameters")
check.error(list[0], 0, invalidAST+"list contains both named and anonymous parameters")
// ok to continue
}

View File

@ -46,7 +46,7 @@ func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body
}
if sig.results.Len() > 0 && !check.isTerminating(body, "") {
check.error(body.Rbrace, "missing return")
check.error(body.Rbrace, _MissingReturn, "missing return")
}
// spec: "Implementation restriction: A compiler may make it illegal to
@ -66,7 +66,7 @@ func (check *Checker) usage(scope *Scope) {
return unused[i].pos.Cmp(unused[j].pos) < 0
})
for _, v := range unused {
check.softErrorf(v.pos, "%s declared but not used", v.name)
check.softErrorf(v.pos, _UnusedVar, "%s declared but not used", v.name)
}
for _, scope := range scope.children {
@ -128,7 +128,7 @@ func (check *Checker) multipleSwitchDefaults(list []*syntax.CaseClause) {
for _, c := range list {
if c.Cases == nil {
if first != nil {
check.errorf(c, "multiple defaults (first at %s)", first.Pos())
check.errorf(c, _DuplicateDefault, "multiple defaults (first at %s)", first.Pos())
// TODO(gri) probably ok to bail out after first error (and simplify this code)
} else {
first = c
@ -142,7 +142,7 @@ func (check *Checker) multipleSelectDefaults(list []*syntax.CommClause) {
for _, c := range list {
if c.Comm == nil {
if first != nil {
check.errorf(c, "multiple defaults (first at %s)", first.Pos())
check.errorf(c, _DuplicateDefault, "multiple defaults (first at %s)", first.Pos())
// TODO(gri) probably ok to bail out after first error (and simplify this code)
} else {
first = c
@ -166,8 +166,13 @@ func (check *Checker) closeScope() {
}
func (check *Checker) suspendedCall(keyword string, call syntax.Expr) {
code := _InvalidDefer
if keyword == "go" {
code = _InvalidGo
}
if _, ok := call.(*syntax.CallExpr); !ok {
check.errorf(call, "expression in %s must be function call", keyword)
check.errorf(call, code, "expression in %s must be function call", keyword)
check.use(call)
return
}
@ -179,12 +184,13 @@ func (check *Checker) suspendedCall(keyword string, call syntax.Expr) {
msg = "requires function call, not conversion"
case expression:
msg = "discards result of"
code = _UnusedResults
case statement:
return
default:
unreachable()
}
check.errorf(&x, "%s %s %s", keyword, msg, &x)
check.errorf(&x, code, "%s %s %s", keyword, msg, &x)
}
// goVal returns the Go value for val, or nil.
@ -395,18 +401,22 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
var x operand
kind := check.rawExpr(&x, s.X, nil, false)
var msg string
var code errorCode
switch x.mode {
default:
if kind == statement {
return
}
msg = "is not used"
code = _UnusedExpr
case builtin:
msg = "must be called"
code = _UncalledBuiltin
case typexpr:
msg = "is not an expression"
code = _NotAnExpr
}
check.errorf(&x, "%s %s", &x, msg)
check.errorf(&x, code, "%s %s", &x, msg)
case *syntax.SendStmt:
var ch, val operand
@ -417,16 +427,16 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
}
u := coreType(ch.typ)
if u == nil {
check.errorf(s, invalidOp+"cannot send to %s: no core type", &ch)
check.errorf(s, _InvalidSend, invalidOp+"cannot send to %s: no core type", &ch)
return
}
uch, _ := u.(*Chan)
if uch == nil {
check.errorf(s, invalidOp+"cannot send to non-channel %s", &ch)
check.errorf(s, _InvalidSend, invalidOp+"cannot send to non-channel %s", &ch)
return
}
if uch.dir == RecvOnly {
check.errorf(s, invalidOp+"cannot send to receive-only channel %s", &ch)
check.errorf(s, _InvalidSend, invalidOp+"cannot send to receive-only channel %s", &ch)
return
}
check.assignment(&val, uch.elem, "send")
@ -436,7 +446,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
if s.Rhs == nil {
// x++ or x--
if len(lhs) != 1 {
check.errorf(s, invalidAST+"%s%s requires one operand", s.Op, s.Op)
check.errorf(s, 0, invalidAST+"%s%s requires one operand", s.Op, s.Op)
return
}
var x operand
@ -445,7 +455,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
return
}
if !allNumeric(x.typ) {
check.errorf(lhs[0], invalidOp+"%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
check.errorf(lhs[0], _NonNumericIncDec, invalidOp+"%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
return
}
check.assignVar(lhs[0], &x)
@ -464,7 +474,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
// assignment operations
if len(lhs) != 1 || len(rhs) != 1 {
check.errorf(s, "assignment operation %s requires single-valued expressions", s.Op)
check.errorf(s, _MultiValAssignOp, "assignment operation %s requires single-valued expressions", s.Op)
return
}
@ -516,11 +526,11 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
switch s.Tok {
case syntax.Break:
if ctxt&breakOk == 0 {
check.error(s, "break not in for, switch, or select statement")
check.error(s, _MisplacedBreak, "break not in for, switch, or select statement")
}
case syntax.Continue:
if ctxt&continueOk == 0 {
check.error(s, "continue not in for statement")
check.error(s, _MisplacedContinue, "continue not in for statement")
}
case syntax.Fallthrough:
if ctxt&fallthroughOk == 0 {
@ -533,13 +543,13 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
default:
msg = "fallthrough statement out of place"
}
check.error(s, msg)
check.error(s, _MisplacedFallthrough, msg)
}
case syntax.Goto:
// goto's must have labels, should have been caught above
fallthrough
default:
check.errorf(s, invalidAST+"branch statement: %s", s.Tok)
check.errorf(s, 0, invalidAST+"branch statement: %s", s.Tok)
}
case *syntax.BlockStmt:
@ -556,7 +566,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
var x operand
check.expr(&x, s.Cond)
if x.mode != invalid && !allBoolean(x.typ) {
check.error(s.Cond, "non-boolean condition in if statement")
check.error(s.Cond, _InvalidCond, "non-boolean condition in if statement")
}
check.stmt(inner, s.Then)
// The parser produces a correct AST but if it was modified
@ -567,7 +577,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
case *syntax.IfStmt, *syntax.BlockStmt:
check.stmt(inner, s.Else)
default:
check.error(s.Else, "invalid else branch in if statement")
check.error(s.Else, 0, invalidAST+"invalid else branch in if statement")
}
case *syntax.SwitchStmt:
@ -615,7 +625,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
}
if !valid {
check.error(clause.Comm, "select case must be send or receive (possibly with assignment)")
check.error(clause.Comm, _InvalidSelectCase, "select case must be send or receive (possibly with assignment)")
continue
}
end := s.Rbrace
@ -646,7 +656,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
var x operand
check.expr(&x, s.Cond)
if x.mode != invalid && !allBoolean(x.typ) {
check.error(s.Cond, "non-boolean condition in for statement")
check.error(s.Cond, _InvalidCond, "non-boolean condition in for statement")
}
}
check.simpleStmt(s.Post)
@ -659,7 +669,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
check.stmt(inner, s.Body)
default:
check.error(s, "invalid statement")
check.error(s, 0, invalidAST+"invalid statement")
}
}
@ -673,7 +683,7 @@ func (check *Checker) switchStmt(inner stmtContext, s *syntax.SwitchStmt) {
// (as a compiler would), we get all the relevant checks.
check.assignment(&x, nil, "switch expression")
if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
check.errorf(&x, "cannot switch on %s (%s is not comparable)", &x, x.typ)
check.errorf(&x, _InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
x.mode = invalid
}
} else {
@ -695,7 +705,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.error(clause, invalidAST+"incorrect expression switch case")
check.error(clause, 0, invalidAST+"incorrect expression switch case")
continue
}
end := s.Rbrace
@ -726,7 +736,7 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
if lhs != nil {
if lhs.Value == "_" {
// _ := x.(type) is an invalid short variable declaration
check.softErrorf(lhs, "no new variable on left side of :=")
check.softErrorf(lhs, _NoNewVar, "no new variable on left side of :=")
lhs = nil // avoid declared but not used error below
} else {
check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause
@ -743,12 +753,12 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
// TODO(gri) we may want to permit type switches on type parameter values at some point
var sx *operand // switch expression against which cases are compared against; nil if invalid
if isTypeParam(x.typ) {
check.errorf(&x, "cannot use type switch on type parameter value %s", &x)
check.errorf(&x, _InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
} else {
if _, ok := under(x.typ).(*Interface); ok {
sx = &x
} else {
check.errorf(&x, "%s is not an interface", &x)
check.errorf(&x, _InvalidTypeSwitch, "%s is not an interface", &x)
}
}
@ -758,7 +768,7 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
seen := make(map[Type]syntax.Expr) // map of seen types to positions
for i, clause := range s.Body {
if clause == nil {
check.error(s, invalidAST+"incorrect type switch case")
check.error(s, 0, invalidAST+"incorrect type switch case")
continue
}
end := s.Rbrace
@ -810,7 +820,7 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
v.used = true // avoid usage error when checking entire function
}
if !used {
check.softErrorf(lhs, "%s declared but not used", lhs.Value)
check.softErrorf(lhs, _UnusedVar, "%s declared but not used", lhs.Value)
}
}
}
@ -821,7 +831,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
var sValue, sExtra syntax.Expr
if p, _ := sKey.(*syntax.ListExpr); p != nil {
if len(p.ElemList) < 2 {
check.error(s, invalidAST+"invalid lhs in range clause")
check.error(s, 0, invalidAST+"invalid lhs in range clause")
return
}
// len(p.ElemList) >= 2
@ -845,7 +855,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
u := coreType(x.typ)
if t, _ := u.(*Chan); t != nil {
if sValue != nil {
check.softErrorf(sValue, "range over %s permits only one iteration variable", &x)
check.softErrorf(sValue, _InvalidIterVar, "range over %s permits only one iteration variable", &x)
// ok to continue
}
if t.dir == SendOnly {
@ -853,7 +863,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
}
} else {
if sExtra != nil {
check.softErrorf(sExtra, "range clause permits at most two iteration variables")
check.softErrorf(sExtra, _InvalidIterVar, "range clause permits at most two iteration variables")
// ok to continue
}
if u == nil {
@ -863,9 +873,9 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
key, val = rangeKeyVal(u)
if key == nil || cause != "" {
if cause == "" {
check.softErrorf(&x, "cannot range over %s", &x)
check.softErrorf(&x, _InvalidRangeExpr, "cannot range over %s", &x)
} else {
check.softErrorf(&x, "cannot range over %s (%s)", &x, cause)
check.softErrorf(&x, _InvalidRangeExpr, "cannot range over %s (%s)", &x, cause)
}
// ok to continue
}
@ -903,7 +913,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
vars = append(vars, obj)
}
} else {
check.errorf(lhs, "cannot declare %s", lhs)
check.errorf(lhs, 0, invalidAST+"cannot declare %s", lhs)
obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
}
@ -926,7 +936,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
}
} else {
check.error(s, "no new variables on left side of :=")
check.error(s, _NoNewVar, "no new variables on left side of :=")
}
} else {
// ordinary assignment

View File

@ -129,7 +129,7 @@ func (check *Checker) structType(styp *Struct, e *syntax.StructType) {
pos := syntax.StartPos(f.Type)
name := embeddedFieldIdent(f.Type)
if name == nil {
check.errorf(pos, "invalid embedded field type %s", f.Type)
check.errorf(pos, 0, invalidAST+"invalid embedded field type %s", f.Type)
name = &syntax.Name{Value: "_"} // TODO(gri) need to set position to pos
addInvalid(name, pos)
continue
@ -152,17 +152,20 @@ func (check *Checker) structType(styp *Struct, e *syntax.StructType) {
}
// unsafe.Pointer is treated like a regular pointer
if u.kind == UnsafePointer {
check.error(embeddedPos, "embedded field type cannot be unsafe.Pointer")
check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
}
case *Pointer:
check.error(embeddedPos, "embedded field type cannot be a pointer")
check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer")
case *Interface:
if isTypeParam(t) {
check.error(embeddedPos, "embedded field type cannot be a (pointer to a) type parameter")
// The error code here is inconsistent with other error codes for
// invalid embedding, because this restriction may be relaxed in the
// future, and so it did not warrant a new error code.
check.error(embeddedPos, _MisplacedTypeParam, "embedded field type cannot be a (pointer to a) type parameter")
break
}
if isPtr {
check.error(embeddedPos, "embedded field type cannot be a pointer to an interface")
check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
}
}
}).describef(embeddedPos, "check embedded type %s", embeddedTyp)
@ -212,7 +215,7 @@ func (check *Checker) tag(t *syntax.BasicLit) string {
return val
}
}
check.errorf(t, invalidAST+"incorrect tag syntax: %q", t.Value)
check.errorf(t, 0, invalidAST+"incorrect tag syntax: %q", t.Value)
}
return ""
}

View File

@ -421,7 +421,7 @@ func computeUnionTypeSet(check *Checker, unionSets map[*Union]*_TypeSet, pos syn
allTerms = allTerms.union(terms)
if len(allTerms) > maxTermCount {
if check != nil {
check.errorf(pos, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
check.errorf(pos, _InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
}
unionSets[utyp] = &invalidTypeSet
return unionSets[utyp]

View File

@ -34,13 +34,13 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType boo
x.mode = typexpr
x.typ = tpar
} else {
check.error(e, "cannot use _ as value or type")
check.error(e, _InvalidBlank, "cannot use _ as value or type")
}
} else {
if check.conf.CompilerErrorMessages {
check.errorf(e, "undefined: %s", e.Value)
check.errorf(e, _UndeclaredName, "undefined: %s", e.Value)
} else {
check.errorf(e, "undeclared name: %s", e.Value)
check.errorf(e, _UndeclaredName, "undeclared name: %s", e.Value)
}
}
return
@ -77,7 +77,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType boo
switch obj := obj.(type) {
case *PkgName:
check.errorf(e, "use of package %s not in selector", obj.name)
check.errorf(e, _InvalidPkgUse, "use of package %s not in selector", obj.name)
return
case *Const:
@ -87,7 +87,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType boo
}
if obj == universeIota {
if check.iota == nil {
check.error(e, "cannot use iota outside constant declaration")
check.error(e, _InvalidIota, "cannot use iota outside constant declaration")
return
}
x.val = check.iota
@ -99,7 +99,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType boo
case *TypeName:
if check.isBrokenAlias(obj) {
check.errorf(e, "invalid use of type alias %s in recursive type (see issue #50729)", obj.name)
check.errorf(e, _InvalidDeclCycle, "invalid use of type alias %s in recursive type (see issue #50729)", obj.name)
return
}
x.mode = typexpr
@ -167,9 +167,9 @@ func (check *Checker) validVarType(e syntax.Expr, typ Type) {
tset := computeInterfaceTypeSet(check, pos, t) // TODO(gri) is this the correct position?
if !tset.IsMethodSet() {
if tset.comparable {
check.softErrorf(pos, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
check.softErrorf(pos, _MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
} else {
check.softErrorf(pos, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
check.softErrorf(pos, _MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
}
}
}
@ -184,7 +184,7 @@ func (check *Checker) definedType(e syntax.Expr, def *Named) Type {
typ := check.typInternal(e, def)
assert(isTyped(typ))
if isGeneric(typ) {
check.errorf(e, "cannot use generic type %s without instantiation", typ)
check.errorf(e, _WrongTypeArgCount, "cannot use generic type %s without instantiation", typ)
typ = Typ[Invalid]
}
check.recordTypeAndValue(e, typexpr, typ, nil)
@ -252,9 +252,9 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
case invalid:
// ignore - error reported before
case novalue:
check.errorf(&x, "%s used as type", &x)
check.errorf(&x, _NotAType, "%s used as type", &x)
default:
check.errorf(&x, "%s is not a type", &x)
check.errorf(&x, _NotAType, "%s is not a type", &x)
}
case *syntax.SelectorExpr:
@ -269,9 +269,9 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
case invalid:
// ignore - error reported before
case novalue:
check.errorf(&x, "%s used as type", &x)
check.errorf(&x, _NotAType, "%s used as type", &x)
default:
check.errorf(&x, "%s is not a type", &x)
check.errorf(&x, _NotAType, "%s is not a type", &x)
}
case *syntax.IndexExpr:
@ -292,7 +292,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
typ.len = check.arrayLength(e.Len)
} else {
// [...]array
check.error(e, "invalid use of [...] array (outside a composite literal)")
check.error(e, _BadDotDotDotSyntax, "invalid use of [...] array (outside a composite literal)")
typ.len = -1
}
typ.elem = check.varType(e.Elem)
@ -310,7 +310,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
case *syntax.DotsType:
// dots are handled explicitly where they are legal
// (array composite literals and parameter lists)
check.error(e, "invalid use of '...'")
check.error(e, _InvalidDotDotDot, "invalid use of '...'")
check.use(e.Elem)
case *syntax.StructType:
@ -335,7 +335,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
return typ
}
check.errorf(e0, "%s is not a type", e0)
check.errorf(e0, _NotAType, "%s is not a type", e0)
check.use(e0)
case *syntax.FuncType:
@ -369,7 +369,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
if isTypeParam(typ.key) {
why = " (missing comparable constraint)"
}
check.errorf(e.Key, "invalid map key type %s%s", typ.key, why)
check.errorf(e.Key, _IncomparableMapKey, "invalid map key type %s%s", typ.key, why)
}
}).describef(e.Key, "check map key %s", typ.key)
@ -388,7 +388,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
case syntax.RecvOnly:
dir = RecvOnly
default:
check.errorf(e, invalidAST+"unknown channel direction %d", e.Dir)
check.errorf(e, 0, invalidAST+"unknown channel direction %d", e.Dir)
// ok to continue
}
@ -397,7 +397,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
return typ
default:
check.errorf(e0, "%s is not a type", e0)
check.errorf(e0, _NotAType, "%s is not a type", e0)
check.use(e0)
}
@ -420,7 +420,7 @@ func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *
var reason string
gtyp := check.genericType(x, &reason)
if reason != "" {
check.errorf(x, invalidOp+"%s%s (%s)", x, xlist, reason)
check.errorf(x, _NotAGenericType, invalidOp+"%s%s (%s)", x, xlist, reason)
}
if gtyp == Typ[Invalid] {
return gtyp // error already reported
@ -456,7 +456,7 @@ func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *
if i < len(xlist) {
pos = syntax.StartPos(xlist[i])
}
check.softErrorf(pos, "%s", err)
check.softErrorf(pos, _InvalidTypeArg, "%s", err)
} else {
check.mono.recordInstance(check.pkg, x.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), xlist)
}
@ -482,11 +482,11 @@ func (check *Checker) arrayLength(e syntax.Expr) int64 {
if name, _ := e.(*syntax.Name); name != nil {
obj := check.lookup(name.Value)
if obj == nil {
check.errorf(name, "undeclared name %s for array length", name.Value)
check.errorf(name, _InvalidArrayLen, "undeclared name %s for array length", name.Value)
return -1
}
if _, ok := obj.(*Const); !ok {
check.errorf(name, "invalid array length %s", name.Value)
check.errorf(name, _InvalidArrayLen, "invalid array length %s", name.Value)
return -1
}
}
@ -495,7 +495,7 @@ func (check *Checker) arrayLength(e syntax.Expr) int64 {
check.expr(&x, e)
if x.mode != constant_ {
if x.mode != invalid {
check.errorf(&x, "array length %s must be constant", &x)
check.errorf(&x, _InvalidArrayLen, "array length %s must be constant", &x)
}
return -1
}
@ -506,13 +506,13 @@ func (check *Checker) arrayLength(e syntax.Expr) int64 {
if n, ok := constant.Int64Val(val); ok && n >= 0 {
return n
}
check.errorf(&x, "invalid array length %s", &x)
check.errorf(&x, _InvalidArrayLen, "invalid array length %s", &x)
return -1
}
}
}
check.errorf(&x, "array length %s must be integer", &x)
check.errorf(&x, _InvalidArrayLen, "array length %s must be integer", &x)
return -1
}

View File

@ -64,7 +64,7 @@ func parseUnion(check *Checker, uexpr syntax.Expr) Type {
}
if len(terms) >= maxTermCount {
if u != Typ[Invalid] {
check.errorf(x, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
check.errorf(x, _InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
u = Typ[Invalid]
}
} else {
@ -94,12 +94,12 @@ func parseUnion(check *Checker, uexpr syntax.Expr) Type {
f, _ := u.(*Interface)
if t.tilde {
if f != nil {
check.errorf(tlist[i], "invalid use of ~ (%s is an interface)", t.typ)
check.errorf(tlist[i], _InvalidUnion, "invalid use of ~ (%s is an interface)", t.typ)
continue // don't report another error for t
}
if !Identical(u, t.typ) {
check.errorf(tlist[i], "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
check.errorf(tlist[i], _InvalidUnion, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
continue
}
}
@ -112,11 +112,11 @@ func parseUnion(check *Checker, uexpr syntax.Expr) Type {
tset := f.typeSet()
switch {
case tset.NumMethods() != 0:
check.errorf(tlist[i], "cannot use %s in union (%s contains methods)", t, t)
check.errorf(tlist[i], _InvalidUnion, "cannot use %s in union (%s contains methods)", t, t)
case t.typ == universeComparable.Type():
check.error(tlist[i], "cannot use comparable in union")
check.error(tlist[i], _InvalidUnion, "cannot use comparable in union")
case tset.comparable:
check.errorf(tlist[i], "cannot use %s in union (%s embeds comparable)", t, t)
check.errorf(tlist[i], _InvalidUnion, "cannot use %s in union (%s embeds comparable)", t, t)
}
continue // terms with interface types are not subject to the no-overlap rule
}
@ -124,7 +124,7 @@ func parseUnion(check *Checker, uexpr syntax.Expr) Type {
// Report overlapping (non-disjoint) terms such as
// a|a, a|~a, ~a|~a, and ~a|A (where under(A) == a).
if j := overlappingTerm(terms[:i], t); j >= 0 {
check.softErrorf(tlist[i], "overlapping terms %s and %s", t, terms[j])
check.softErrorf(tlist[i], _InvalidUnion, "overlapping terms %s and %s", t, terms[j])
}
}
}).describef(uexpr, "check term validity %s", uexpr)
@ -147,9 +147,9 @@ func parseTilde(check *Checker, tx syntax.Expr) *Term {
// and since the underlying type is an interface the embedding is well defined.
if isTypeParam(typ) {
if tilde {
check.errorf(x, "type in term %s cannot be a type parameter", tx)
check.errorf(x, _MisplacedTypeParam, "type in term %s cannot be a type parameter", tx)
} else {
check.error(x, "term cannot be a type parameter")
check.error(x, _MisplacedTypeParam, "term cannot be a type parameter")
}
typ = Typ[Invalid]
}