From: Robert Findley Date: Mon, 15 Nov 2021 01:34:58 +0000 (-0500) Subject: go/types: assign error codes to new errors for Go 1.18 X-Git-Tag: go1.18beta1~323 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=0e654100382f345ea555cfc1e1dd50853316b368;p=gostls13.git go/types: assign error codes to new errors for Go 1.18 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 Run-TryBot: Robert Findley TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go index 923bd43b49..d77cf8f7fa 100644 --- a/src/go/types/assignments.go +++ b/src/go/types/assignments.go @@ -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 diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go index 4d3ff26b14..c2d36e9711 100644 --- a/src/go/types/builtins.go +++ b/src/go/types/builtins.go @@ -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 diff --git a/src/go/types/call.go b/src/go/types/call.go index da4b72a0c7..927c9f2a44 100644 --- a/src/go/types/call.go +++ b/src/go/types/call.go @@ -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 diff --git a/src/go/types/decl.go b/src/go/types/decl.go index 7e89e7be3a..e12961416e 100644 --- a/src/go/types/decl.go +++ b/src/go/types/decl.go @@ -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 diff --git a/src/go/types/errorcodes.go b/src/go/types/errorcodes.go index 88dd0fda2f..cbf00ba0b4 100644 --- a/src/go/types/errorcodes.go +++ b/src/go/types/errorcodes.go @@ -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 diff --git a/src/go/types/errorcodes_test.go b/src/go/types/errorcodes_test.go index 5da1cdadfc..629eac4912 100644 --- a/src/go/types/errorcodes_test.go +++ b/src/go/types/errorcodes_test.go @@ -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 { diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 138eb2f521..9d9eddfb95 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -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 diff --git a/src/go/types/infer.go b/src/go/types/infer.go index 41326a1be8..f4f9bfac8f 100644 --- a/src/go/types/infer.go +++ b/src/go/types/infer.go @@ -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 } } diff --git a/src/go/types/instantiate.go b/src/go/types/instantiate.go index 2d2d1718f4..13d6e3114d 100644 --- a/src/go/types/instantiate.go +++ b/src/go/types/instantiate.go @@ -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)) diff --git a/src/go/types/interface.go b/src/go/types/interface.go index 78813e665b..ef65bc6b2b 100644 --- a/src/go/types/interface.go +++ b/src/go/types/interface.go @@ -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) diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go index 5a82b4fd9c..7a2dcbffbb 100644 --- a/src/go/types/resolver.go +++ b/src/go/types/resolver.go @@ -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: "_"} diff --git a/src/go/types/signature.go b/src/go/types/signature.go index 698b89c462..306d86c0b7 100644 --- a/src/go/types/signature.go +++ b/src/go/types/signature.go @@ -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 diff --git a/src/go/types/stmt.go b/src/go/types/stmt.go index c000d935d6..2a3fb5f6f5 100644 --- a/src/go/types/stmt.go +++ b/src/go/types/stmt.go @@ -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 diff --git a/src/go/types/struct.go b/src/go/types/struct.go index 60640ac578..84af8a3f48 100644 --- a/src/go/types/struct.go +++ b/src/go/types/struct.go @@ -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") diff --git a/src/go/types/typeset.go b/src/go/types/typeset.go index f8e76ed400..1e6b9dd390 100644 --- a/src/go/types/typeset.go +++ b/src/go/types/typeset.go @@ -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 diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index cff9917185..c89e69db7b 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -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) } diff --git a/src/go/types/union.go b/src/go/types/union.go index c715839315..bb08174728 100644 --- a/src/go/types/union.go +++ b/src/go/types/union.go @@ -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