]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: assign error codes to new errors for Go 1.18
authorRobert Findley <rfindley@google.com>
Mon, 15 Nov 2021 01:34:58 +0000 (20:34 -0500)
committerRobert Findley <rfindley@google.com>
Mon, 15 Nov 2021 18:43:07 +0000 (18:43 +0000)
During development, we used placeholder _Todo error codes for new
errors related to generics. Add real error codes in these places.

As a result, 9 new error codes are added for ~50 call sites.

Change-Id: Ib57b4cd9f0a2e160971a3aeea18f9fe26fc0f835
Reviewed-on: https://go-review.googlesource.com/c/go/+/363874
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
17 files changed:
src/go/types/assignments.go
src/go/types/builtins.go
src/go/types/call.go
src/go/types/decl.go
src/go/types/errorcodes.go
src/go/types/errorcodes_test.go
src/go/types/expr.go
src/go/types/infer.go
src/go/types/instantiate.go
src/go/types/interface.go
src/go/types/resolver.go
src/go/types/signature.go
src/go/types/stmt.go
src/go/types/struct.go
src/go/types/typeset.go
src/go/types/typexpr.go
src/go/types/union.go

index 923bd43b49992c1484994cea15948b98e1e79bb6..d77cf8f7faf74c46f99865f527e2c9c3e6b49cd8 100644 (file)
@@ -72,7 +72,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, _Todo, "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
index 4d3ff26b1437d1bcfdbd11626fa5cb82e083345f..c2d36e97114496260b1df211bb51bacf6c44e798 100644 (file)
@@ -370,7 +370,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                                return false
                        }
                        if key != nil && !Identical(map_.key, key) {
-                               check.invalidArg(x, _Todo, "maps of %s must have identical key types", x)
+                               check.invalidArg(x, _InvalidDelete, "maps of %s must have identical key types", x)
                                return false
                        }
                        key = map_.key
index da4b72a0c7b78df601cf80a61733544b1cf3fabb..927c9f2a44cf02a1d2b6e8cf9385f1e9d8a969c5 100644 (file)
@@ -18,7 +18,7 @@ import (
 // The operand x must be the evaluation of inst.X and its type must be a signature.
 func (check *Checker) funcInst(x *operand, ix *typeparams.IndexExpr) {
        if !check.allowVersion(check.pkg, 1, 18) {
-               check.softErrorf(inNode(ix.Orig, ix.Lbrack), _Todo, "function instantiation requires go1.18 or later")
+               check.softErrorf(inNode(ix.Orig, ix.Lbrack), _UnsupportedFeature, "function instantiation requires go1.18 or later")
        }
 
        targs := check.typeList(ix.Indices)
@@ -33,7 +33,7 @@ func (check *Checker) funcInst(x *operand, ix *typeparams.IndexExpr) {
        sig := x.typ.(*Signature)
        got, want := len(targs), sig.TypeParams().Len()
        if got > want {
-               check.errorf(ix.Indices[got-1], _Todo, "got %d type arguments but want %d", got, want)
+               check.errorf(ix.Indices[got-1], _WrongTypeArgCount, "got %d type arguments but want %d", got, want)
                x.mode = invalid
                x.expr = ix.Orig
                return
@@ -90,7 +90,7 @@ func (check *Checker) instantiateSignature(pos token.Pos, typ *Signature, targs
                if i < len(posList) {
                        pos = posList[i]
                }
-               check.softErrorf(atPos(pos), _Todo, err.Error())
+               check.softErrorf(atPos(pos), _InvalidTypeArg, err.Error())
        } else {
                check.mono.recordInstance(check.pkg, pos, tparams, targs, posList)
        }
@@ -143,7 +143,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
                                }
                                if t, _ := under(T).(*Interface); t != nil {
                                        if !t.IsMethodSet() {
-                                               check.errorf(call, _Todo, "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
                                        }
                                }
@@ -198,7 +198,7 @@ func (check *Checker) callExpr(x *operand, call *ast.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(ix.Indices[want], _Todo, "got %d type arguments but want %d", got, want)
+                       check.errorf(ix.Indices[want], _WrongTypeArgCount, "got %d type arguments but want %d", got, want)
                        check.use(call.Args...)
                        x.mode = invalid
                        x.expr = call
@@ -370,9 +370,9 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
                        switch call.Fun.(type) {
                        case *ast.IndexExpr, *ast.IndexListExpr:
                                ix := typeparams.UnpackIndexExpr(call.Fun)
-                               check.softErrorf(inNode(call.Fun, ix.Lbrack), _Todo, "function instantiation requires go1.18 or later")
+                               check.softErrorf(inNode(call.Fun, ix.Lbrack), _UnsupportedFeature, "function instantiation requires go1.18 or later")
                        default:
-                               check.softErrorf(inNode(call, call.Lparen), _Todo, "implicit function instantiation requires go1.18 or later")
+                               check.softErrorf(inNode(call, call.Lparen), _UnsupportedFeature, "implicit function instantiation requires go1.18 or later")
                        }
                }
                // TODO(gri) provide position information for targs so we can feed
index 7e89e7be3ac43fe5eb4f115f6a5eeff97e2e9462..e12961416e3fead5928c75e89989e5b8eed3c346 100644 (file)
@@ -623,7 +623,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
                check.validType(obj.typ, nil)
                // If typ is local, an error was already reported where typ is specified/defined.
                if check.isImportedConstraint(rhs) && !check.allowVersion(check.pkg, 1, 18) {
-                       check.errorf(tdecl.Type, _Todo, "using type constraint %s requires go1.18 or later", rhs)
+                       check.errorf(tdecl.Type, _UnsupportedFeature, "using type constraint %s requires go1.18 or later", rhs)
                }
        }).describef(obj, "validType(%s)", obj.Name())
 
@@ -631,7 +631,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
        if alias && tdecl.TypeParams.NumFields() != 0 {
                // The parser will ensure this but we may still get an invalid AST.
                // Complain and continue as regular type definition.
-               check.error(atPos(tdecl.Assign), _Todo, "generic type cannot be alias")
+               check.error(atPos(tdecl.Assign), _BadDecl, "generic type cannot be alias")
                alias = false
        }
 
@@ -673,7 +673,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
        // type (underlying not fully resolved yet) it cannot become a type parameter due
        // to this very restriction.
        if tpar, _ := named.underlying.(*TypeParam); tpar != nil {
-               check.error(tdecl.Type, _Todo, "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]
        }
 }
@@ -724,7 +724,7 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList
        check.later(func() {
                for i, bound := range bounds {
                        if _, ok := under(bound).(*TypeParam); ok {
-                               check.error(posns[i], _Todo, "cannot use a type parameter as constraint")
+                               check.error(posns[i], _MisplacedTypeParam, "cannot use a type parameter as constraint")
                        }
                }
                for _, tpar := range tparams {
@@ -861,7 +861,7 @@ func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
        obj.color_ = saved
 
        if fdecl.Type.TypeParams.NumFields() > 0 && fdecl.Body == nil {
-               check.softErrorf(fdecl.Name, _Todo, "parameterized function is missing function body")
+               check.softErrorf(fdecl.Name, _BadDecl, "parameterized function is missing function body")
        }
 
        // function body must be type-checked after global declarations
index 88dd0fda2f8aefbd03f42729592aeac3bdb1204c..cbf00ba0b4bcc630fe0c9f0eff0b1f26afaa9e24 100644 (file)
@@ -1301,6 +1301,54 @@ const (
        //  var _ = unsafe.Slice(&x, uint64(1) << 63)
        _InvalidUnsafeSlice
 
+       // All codes below were added in Go 1.18.
+
+       // _UnsupportedFeature occurs when a language feature is used that is not
+       // supported at this Go version.
+       _UnsupportedFeature
+
+       // _WrongTypeArgCount occurs when a type or function is instantiated with an
+       // incorrent number of type arguments, including when a generic type or
+       // function is used without instantiation.
+       //
+       // Errors inolving failed type inference are assigned other error codes.
+       //
+       // Example:
+       //  type T[p any] int
+       //
+       //  var _ T[int, string]
+       //
+       // Example:
+       //  func f[T any]() {}
+       //
+       //  var x = f
+       _WrongTypeArgCount
+
+       // _CannotInferTypeArgs occurs when type or function type argument inference
+       // fails to infer all type arguments.
+       //
+       // Example:
+       //  func f[T any]() {}
+       //
+       //  func _() {
+       //      f()
+       //  }
+       //
+       // Example:
+       //   type N[P, Q any] struct{}
+       //
+       //   var _ N[int]
+       _CannotInferTypeArgs
+
+       // _InvalidTypeArg occurs when a type argument does not satisfy its
+       // corresponding type parameter constraints.
+       //
+       // Example:
+       //  type T[P ~int] struct{}
+       //
+       //  var _ T[string]
+       _InvalidTypeArg // arguments? InferenceFailed
+
        // _InvalidInstanceCycle occurs when an invalid cycle is detected
        // within the instantiation graph.
        //
@@ -1308,6 +1356,42 @@ const (
        //  func f[T any]() { f[*T]() }
        _InvalidInstanceCycle
 
+       // _InvalidUnion occurs when an embedded union or approximation element is
+       // not valid.
+       //
+       // Example:
+       //  type _ interface {
+       //      ~int | interface{ m() }
+       //  }
+       _InvalidUnion
+
+       // _MisplacedConstraintIface occurs when a constraint-type interface is used
+       // outside of constraint position.
+       //
+       // Example:
+       //   type I interface { ~int }
+       //
+       //   var _ I
+       _MisplacedConstraintIface
+
+       // _InvalidMethodTypeParams occurs when methods have type parameters.
+       //
+       // Example:
+       //  type T int
+       //
+       //  func (T) m[P any]() {}
+       _InvalidMethodTypeParams
+
+       // _MisplacedTypeParam occurs when a type parameter is used in a place where
+       // it is not permitted.
+       //
+       // Example:
+       //  type T[P any] P
+       //
+       // Example:
+       //  type T[P any] struct{ *P }
+       _MisplacedTypeParam
+
        // _Todo is a placeholder for error codes that have not been decided.
        // TODO(rFindley) remove this error code after deciding on errors for generics code.
        _Todo
index 5da1cdadfc69144f20a408ea043948db62129b4f..629eac4912d3e2770e557902d6c79b90fde0b5d9 100644 (file)
@@ -171,8 +171,10 @@ func TestErrorCodeStyle(t *testing.T) {
                        }
                }
                doc := spec.Doc.Text()
-               if !strings.HasPrefix(doc, name) {
-                       t.Errorf("doc for %q does not start with identifier", name)
+               if doc == "" {
+                       t.Errorf("%q is undocumented", name)
+               } else if !strings.HasPrefix(doc, name) {
+                       t.Errorf("doc for %q does not start with the error code name", name)
                }
                lowerComment := strings.ToLower(strings.TrimPrefix(doc, name))
                for _, bad := range forbiddenInComment {
index 138eb2f5214ada4cc9313d8b15370f437994a59a..9d9eddfb95a7e79823b7a67701c1c9d1795b26b1 100644 (file)
@@ -186,7 +186,7 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
                                return false
                        }
                        if elem != nil && !Identical(ch.elem, elem) {
-                               check.invalidOp(x, _Todo, "channels of %s must have the same element type", x)
+                               check.invalidOp(x, _InvalidReceive, "channels of %s must have the same element type", x)
                                return false
                        }
                        elem = ch.elem
@@ -1116,7 +1116,7 @@ func (check *Checker) nonGeneric(x *operand) {
                }
        }
        if what != "" {
-               check.errorf(x.expr, _Todo, "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]
        }
@@ -1233,7 +1233,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                        // Prevent crash if the struct referred to is not yet set up.
                        // See analogous comment for *Array.
                        if utyp.fields == nil {
-                               check.error(e, _Todo, "illegal cycle in type declaration")
+                               check.error(e, _InvalidDeclCycle, "illegal cycle in type declaration")
                                goto Error
                        }
                        if len(e.Elts) == 0 {
@@ -1472,7 +1472,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                                        return false
                                }
                                if base != nil && !Identical(p.base, base) {
-                                       check.invalidOp(x, _Todo, "pointers of %s must have identical base types", x)
+                                       check.invalidOp(x, _InvalidIndirection, "pointers of %s must have identical base types", x)
                                        return false
                                }
                                base = p.base
index 41326a1be8bd3574ab632d63331418f7424f7416..f4f9bfac8fa13936a534da8f4164282cd61f3e2c 100644 (file)
@@ -118,17 +118,21 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
                                }
                        }
                        if allFailed {
-                               check.errorf(arg, _Todo, "%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)
                // TODO(rFindley): pass a positioner here, rather than arg.Pos().
                inferred := check.subst(arg.Pos(), tpar, smap, nil)
+               // _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, _Todo, "%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, _Todo, "%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)
                }
        }
 
@@ -214,7 +218,7 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
        // At least one type argument couldn't be inferred.
        assert(index >= 0 && targs[index] == nil)
        tpar := tparams[index]
-       check.errorf(posn, _Todo, "cannot infer %s (%v)", tpar.obj.name, tpar.obj.pos)
+       check.errorf(posn, _CannotInferTypeArgs, "cannot infer %s (%v)", tpar.obj.name, tpar.obj.pos)
        return nil
 }
 
@@ -383,7 +387,7 @@ func (check *Checker) inferB(tparams []*TypeParam, targs []Type) (types []Type,
                        if !u.unify(tpar, sbound) {
                                // TODO(gri) improve error message by providing the type arguments
                                //           which we know already
-                               check.errorf(tpar.obj, _Todo, "%s does not match %s", tpar, sbound)
+                               check.errorf(tpar.obj, _InvalidTypeArg, "%s does not match %s", tpar, sbound)
                                return nil, 0
                        }
                }
index 2d2d1718f46e17108b2e0f27ced23a92955c6af9..13d6e3114d6b12ef3e76b9f23d82fc6c48570f2c 100644 (file)
@@ -124,7 +124,7 @@ func (check *Checker) validateTArgLen(pos token.Pos, ntparams, ntargs int) bool
        if ntargs != ntparams {
                // TODO(gri) provide better error message
                if check != nil {
-                       check.errorf(atPos(pos), _Todo, "got %d arguments but %d type parameters", ntargs, ntparams)
+                       check.errorf(atPos(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))
index 78813e665bf1b605986eb202f8c73f320eaeb75b..ef65bc6b2bdf0fee7f27d8ba8b0945d57f94eb44 100644 (file)
@@ -181,7 +181,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
                        if ftyp, _ := f.Type.(*ast.FuncType); ftyp != nil && ftyp.TypeParams != nil {
                                at = ftyp.TypeParams
                        }
-                       check.errorf(at, _Todo, "methods cannot have type parameters")
+                       check.errorf(at, _InvalidMethodTypeParams, "methods cannot have type parameters")
                }
 
                // use named receiver type if available (for better error messages)
index 5a82b4fd9ca496f966a9b6ef5113ba53ab46ae70..7a2dcbffbb17e172de42d720a1adb38f9d4bd253 100644 (file)
@@ -382,7 +382,7 @@ func (check *Checker) collectObjects() {
                                }
                        case typeDecl:
                                if d.spec.TypeParams.NumFields() != 0 && !check.allowVersion(pkg, 1, 18) {
-                                       check.softErrorf(d.spec.TypeParams.List[0], _Todo, "type parameters require go1.18 or later")
+                                       check.softErrorf(d.spec.TypeParams.List[0], _UnsupportedFeature, "type parameters require go1.18 or later")
                                }
                                obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
                                check.declarePkgObj(d.spec.Name, obj, &declInfo{file: fileScope, tdecl: d.spec})
@@ -440,7 +440,7 @@ func (check *Checker) collectObjects() {
                                        check.recordDef(d.decl.Name, obj)
                                }
                                if d.decl.Type.TypeParams.NumFields() != 0 && !check.allowVersion(pkg, 1, 18) && !hasTParamError {
-                                       check.softErrorf(d.decl.Type.TypeParams.List[0], _Todo, "type parameters require go1.18 or later")
+                                       check.softErrorf(d.decl.Type.TypeParams.List[0], _UnsupportedFeature, "type parameters require go1.18 or later")
                                }
                                info := &declInfo{file: fileScope, fdecl: d.decl}
                                // Methods are not package-level objects but we still track them in the
@@ -527,7 +527,7 @@ L: // unpack receiver type
                                case nil:
                                        check.invalidAST(ix.Orig, "parameterized receiver contains nil parameters")
                                default:
-                                       check.errorf(arg, _Todo, "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 = &ast.Ident{NamePos: arg.Pos(), Name: "_"}
index 698b89c462f11a6e9bb3c963a8d204baab840d0c..306d86c0b75bd3a42d670b82e2f8fce05b7155e0 100644 (file)
@@ -168,7 +168,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast
                // (A separate check is needed when type-checking interface method signatures because
                // they don't have a receiver specification.)
                if recvPar != nil {
-                       check.errorf(ftyp.TypeParams, _Todo, "methods cannot have type parameters")
+                       check.errorf(ftyp.TypeParams, _InvalidMethodTypeParams, "methods cannot have type parameters")
                }
        }
 
@@ -215,7 +215,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast
                                // 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(atPos(recv.pos), _Todo, "cannot define methods on instantiated type %s", recv.typ)
+                                       check.errorf(atPos(recv.pos), _InvalidRecv, "cannot define methods on instantiated type %s", recv.typ)
                                        break
                                }
                                // spec: "The type denoted by T is called the receiver base type; it must not
index c000d935d6bbb799607f486d7902952db16e3125..2a3fb5f6f516a0dd09aa604cb9dddb9601b81c8f 100644 (file)
@@ -429,7 +429,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
                                return false
                        }
                        if elem != nil && !Identical(uch.elem, elem) {
-                               check.invalidOp(inNode(s, s.Arrow), _Todo, "channels of %s must have the same element type", &ch)
+                               check.invalidOp(inNode(s, s.Arrow), _InvalidSend, "channels of %s must have the same element type", &ch)
                                return false
                        }
                        elem = uch.elem
index 60640ac5786e4de742fd2a55897204604cf3c90f..84af8a3f48df29acedece4f1085d3aa4b11396d1 100644 (file)
@@ -124,9 +124,7 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) {
                        pos := f.Type.Pos()
                        name := embeddedFieldIdent(f.Type)
                        if name == nil {
-                               // TODO(rFindley): using invalidAST here causes test failures (all
-                               //                 errors should have codes). Clean this up.
-                               check.errorf(f.Type, _Todo, "invalid AST: embedded field type %s has no name", f.Type)
+                               check.invalidAST(f.Type, "embedded field type %s has no name", f.Type)
                                name = ast.NewIdent("_")
                                name.NamePos = pos
                                addInvalid(name, pos)
@@ -158,7 +156,10 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) {
                                case *Pointer:
                                        check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer")
                                case *TypeParam:
-                                       check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a (pointer to a) type parameter")
+                                       // This 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")
                                case *Interface:
                                        if isPtr {
                                                check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
index f8e76ed400f17587a0e6a96d55616d5533268d0f..1e6b9dd3906932efeb3e9a22606ce68d90112226 100644 (file)
@@ -269,7 +269,7 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
                        tset := computeInterfaceTypeSet(check, pos, u)
                        // If typ is local, an error was already reported where typ is specified/defined.
                        if check != nil && check.isImportedConstraint(typ) && !check.allowVersion(check.pkg, 1, 18) {
-                               check.errorf(atPos(pos), _Todo, "embedding constraint interface %s requires go1.18 or later", typ)
+                               check.errorf(atPos(pos), _UnsupportedFeature, "embedding constraint interface %s requires go1.18 or later", typ)
                                continue
                        }
                        if tset.comparable {
@@ -281,7 +281,7 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
                        terms = tset.terms
                case *Union:
                        if check != nil && !check.allowVersion(check.pkg, 1, 18) {
-                               check.errorf(atPos(pos), _Todo, "embedding interface element %s requires go1.18 or later", u)
+                               check.errorf(atPos(pos), _InvalidIfaceEmbed, "embedding interface element %s requires go1.18 or later", u)
                                continue
                        }
                        tset := computeUnionTypeSet(check, pos, u)
@@ -385,7 +385,7 @@ func computeUnionTypeSet(check *Checker, pos token.Pos, utyp *Union) *_TypeSet {
                allTerms = allTerms.union(terms)
                if len(allTerms) > maxTermCount {
                        if check != nil {
-                               check.errorf(atPos(pos), _Todo, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
+                               check.errorf(atPos(pos), _InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
                        }
                        utyp.tset = &invalidTypeSet
                        return utyp.tset
index cff99171858ed419fce9efff1755423eb82c0924..c89e69db7b1e37acf3f246cd0e7836f10d1d0e87 100644 (file)
@@ -149,9 +149,9 @@ func (check *Checker) varType(e ast.Expr) Type {
                        tset := computeInterfaceTypeSet(check, e.Pos(), t) // TODO(gri) is this the correct position?
                        if !tset.IsMethodSet() {
                                if tset.comparable {
-                                       check.softErrorf(e, _Todo, "interface is (or embeds) comparable")
+                                       check.softErrorf(e, _MisplacedConstraintIface, "interface is (or embeds) comparable")
                                } else {
-                                       check.softErrorf(e, _Todo, "interface contains type constraints")
+                                       check.softErrorf(e, _MisplacedConstraintIface, "interface contains type constraints")
                                }
                        }
                }
@@ -169,7 +169,7 @@ func (check *Checker) definedType(e ast.Expr, def *Named) Type {
        typ := check.typInternal(e, def)
        assert(isTyped(typ))
        if isGeneric(typ) {
-               check.errorf(e, _Todo, "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)
@@ -261,7 +261,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
        case *ast.IndexExpr, *ast.IndexListExpr:
                ix := typeparams.UnpackIndexExpr(e)
                if !check.allowVersion(check.pkg, 1, 18) {
-                       check.softErrorf(inNode(e, ix.Lbrack), _Todo, "type instantiation requires go1.18 or later")
+                       check.softErrorf(inNode(e, ix.Lbrack), _UnsupportedFeature, "type instantiation requires go1.18 or later")
                }
                return check.instantiatedType(ix.X, ix.Indices, def)
 
@@ -459,7 +459,7 @@ func (check *Checker) instantiatedType(x ast.Expr, targsx []ast.Expr, def *Named
                                if i < len(posList) {
                                        pos = posList[i]
                                }
-                               check.softErrorf(atPos(pos), _Todo, err.Error())
+                               check.softErrorf(atPos(pos), _InvalidTypeArg, err.Error())
                        } else {
                                check.mono.recordInstance(check.pkg, x.Pos(), inst.tparams.list(), inst.targs.list(), posList)
                        }
index c715839315cd1e4402972019e3b6348908a5a3aa..bb0817472849f0b8363abf82f428bb6fca3cd699 100644 (file)
@@ -63,7 +63,7 @@ func parseUnion(check *Checker, tlist []ast.Expr) Type {
                        return typ
                }
                if len(terms) >= maxTermCount {
-                       check.errorf(x, _Todo, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
+                       check.errorf(x, _InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
                        return Typ[Invalid]
                }
                terms = append(terms, NewTerm(tilde, typ))
@@ -82,12 +82,12 @@ func parseUnion(check *Checker, tlist []ast.Expr) Type {
                        f, _ := u.(*Interface)
                        if t.tilde {
                                if f != nil {
-                                       check.errorf(tlist[i], _Todo, "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], _Todo, "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 // don't report another error for t
                                }
                        }
@@ -96,14 +96,14 @@ func parseUnion(check *Checker, tlist []ast.Expr) Type {
                        // in the beginning. Embedded interfaces with tilde are excluded above. If we reach
                        // here, we must have at least two terms in the union.
                        if f != nil && !f.typeSet().IsTypeSet() {
-                               check.errorf(tlist[i], _Todo, "cannot use %s in union (interface contains methods)", t)
+                               check.errorf(tlist[i], _InvalidUnion, "cannot use %s in union (interface contains methods)", t)
                                continue // don't report another error for t
                        }
 
                        // 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], _Todo, "overlapping terms %s and %s", t, terms[j])
+                               check.softErrorf(tlist[i], _InvalidUnion, "overlapping terms %s and %s", t, terms[j])
                        }
                }
        })
@@ -124,7 +124,7 @@ func parseTilde(check *Checker, x ast.Expr) (tilde bool, typ Type) {
        //       check to later and could return Typ[Invalid] instead.
        check.later(func() {
                if _, ok := under(typ).(*TypeParam); ok {
-                       check.error(x, _Todo, "cannot embed a type parameter")
+                       check.error(x, _MisplacedTypeParam, "cannot embed a type parameter")
                }
        })
        return