mirror of https://github.com/golang/go.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 <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
1dc9af5cdc
commit
0e65410038
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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: "_"}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue