mirror of
https://github.com/golang/go
synced 2024-11-18 06:24:47 -07:00
go/types, types2: consistently use "cause" instead of "reason" for error details (cleanup)
There were many more uses of the variable name "cause" than "reason" to hold error message details. Consistently use "cause" throughout. Accordingly, s/MissingMethodReason/MissingMethodCause/. Change-Id: I171d784faabc66a4c58ba8944784204687595203 Reviewed-on: https://go-review.googlesource.com/c/go/+/435418 Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Auto-Submit: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@google.com>
This commit is contained in:
parent
5612215d32
commit
ffdfa9ff41
@ -1764,7 +1764,7 @@ func (check *Checker) typeAssertion(e syntax.Expr, x *operand, T Type, typeSwitc
|
|||||||
return // success
|
return // success
|
||||||
}
|
}
|
||||||
|
|
||||||
cause := check.missingMethodReason(T, x.typ, method, alt)
|
cause := check.missingMethodCause(T, x.typ, method, alt)
|
||||||
|
|
||||||
if typeSwitch {
|
if typeSwitch {
|
||||||
check.errorf(e, _ImpossibleAssert, "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)
|
||||||
|
@ -174,9 +174,9 @@ func (check *Checker) verify(pos syntax.Pos, tparams []*TypeParam, targs []Type,
|
|||||||
// need to instantiate it with the type arguments with which we instantiated
|
// need to instantiate it with the type arguments with which we instantiated
|
||||||
// the parameterized type.
|
// the parameterized type.
|
||||||
bound := check.subst(pos, tpar.bound, smap, nil, ctxt)
|
bound := check.subst(pos, tpar.bound, smap, nil, ctxt)
|
||||||
var reason string
|
var cause string
|
||||||
if !check.implements(targs[i], bound, &reason) {
|
if !check.implements(targs[i], bound, &cause) {
|
||||||
return i, errors.New(reason)
|
return i, errors.New(cause)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1, nil
|
return -1, nil
|
||||||
@ -185,9 +185,9 @@ func (check *Checker) verify(pos syntax.Pos, tparams []*TypeParam, targs []Type,
|
|||||||
// implements checks if V implements T. The receiver may be nil if implements
|
// implements checks if V implements T. The receiver may be nil if implements
|
||||||
// is called through an exported API call such as AssignableTo.
|
// is called through an exported API call such as AssignableTo.
|
||||||
//
|
//
|
||||||
// If the provided reason is non-nil, it may be set to an error string
|
// If the provided cause is non-nil, it may be set to an error string
|
||||||
// explaining why V does not implement T.
|
// explaining why V does not implement T.
|
||||||
func (check *Checker) implements(V, T Type, reason *string) bool {
|
func (check *Checker) implements(V, T Type, cause *string) bool {
|
||||||
Vu := under(V)
|
Vu := under(V)
|
||||||
Tu := under(T)
|
Tu := under(T)
|
||||||
if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
|
if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
|
||||||
@ -199,14 +199,14 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
|
|
||||||
Ti, _ := Tu.(*Interface)
|
Ti, _ := Tu.(*Interface)
|
||||||
if Ti == nil {
|
if Ti == nil {
|
||||||
var cause string
|
var detail string
|
||||||
if isInterfacePtr(Tu) {
|
if isInterfacePtr(Tu) {
|
||||||
cause = check.sprintf("type %s is pointer to interface, not interface", T)
|
detail = check.sprintf("type %s is pointer to interface, not interface", T)
|
||||||
} else {
|
} else {
|
||||||
cause = check.sprintf("%s is not an interface", T)
|
detail = check.sprintf("%s is not an interface", T)
|
||||||
}
|
}
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s does not implement %s (%s)", V, T, cause)
|
*cause = check.sprintf("%s does not implement %s (%s)", V, T, detail)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -227,16 +227,16 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
|
|
||||||
// No type with non-empty type set satisfies the empty type set.
|
// No type with non-empty type set satisfies the empty type set.
|
||||||
if Ti.typeSet().IsEmpty() {
|
if Ti.typeSet().IsEmpty() {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("cannot implement %s (empty type set)", T)
|
*cause = check.sprintf("cannot implement %s (empty type set)", T)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// V must implement T's methods, if any.
|
// V must implement T's methods, if any.
|
||||||
if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
|
if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s does not implement %s %s", V, T, check.missingMethodReason(V, T, m, wrong))
|
*cause = check.sprintf("%s does not implement %s %s", V, T, check.missingMethodCause(V, T, m, wrong))
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -245,8 +245,8 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
checkComparability := func() bool {
|
checkComparability := func() bool {
|
||||||
// If T is comparable, V must be comparable.
|
// If T is comparable, V must be comparable.
|
||||||
if Ti.IsComparable() && !comparable(V, false, nil, nil) {
|
if Ti.IsComparable() && !comparable(V, false, nil, nil) {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s does not implement comparable", V)
|
*cause = check.sprintf("%s does not implement comparable", V)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -265,8 +265,8 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
if Vi != nil {
|
if Vi != nil {
|
||||||
if !Vi.typeSet().subsetOf(Ti.typeSet()) {
|
if !Vi.typeSet().subsetOf(Ti.typeSet()) {
|
||||||
// TODO(gri) report which type is missing
|
// TODO(gri) report which type is missing
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s does not implement %s", V, T)
|
*cause = check.sprintf("%s does not implement %s", V, T)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -291,11 +291,11 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}) {
|
}) {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
if alt != nil {
|
if alt != nil {
|
||||||
*reason = check.sprintf("%s does not implement %s (possibly missing ~ for %s in constraint %s)", V, T, alt, T)
|
*cause = check.sprintf("%s does not implement %s (possibly missing ~ for %s in constraint %s)", V, T, alt, T)
|
||||||
} else {
|
} else {
|
||||||
*reason = check.sprintf("%s does not implement %s (%s missing in %s)", V, T, V, Ti.typeSet().terms)
|
*cause = check.sprintf("%s does not implement %s (%s missing in %s)", V, T, V, Ti.typeSet().terms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -364,13 +364,13 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// missingMethodReason returns a string giving the detailed reason for a missing method m,
|
// missingMethodCause returns a string giving the detailed cause for a missing method m,
|
||||||
// where m is missing from V, but required by T. It puts the reason in parentheses,
|
// where m is missing from V, but required by T. It puts the cause in parentheses,
|
||||||
// and may include more have/want info after that. If non-nil, alt is a relevant
|
// and may include more have/want info after that. If non-nil, alt is a relevant
|
||||||
// method that matches in some way. It may have the correct name, but wrong type, or
|
// method that matches in some way. It may have the correct name, but wrong type, or
|
||||||
// it may have a pointer receiver, or it may have the correct name except wrong case.
|
// it may have a pointer receiver, or it may have the correct name except wrong case.
|
||||||
// check may be nil.
|
// check may be nil.
|
||||||
func (check *Checker) missingMethodReason(V, T Type, m, alt *Func) string {
|
func (check *Checker) missingMethodCause(V, T Type, m, alt *Func) string {
|
||||||
mname := "method " + m.Name()
|
mname := "method " + m.Name()
|
||||||
|
|
||||||
if alt != nil {
|
if alt != nil {
|
||||||
|
@ -234,12 +234,12 @@ func (x *operand) setConst(k syntax.LitKind, lit string) {
|
|||||||
func (x *operand) isNil() bool { return x.mode == nilvalue }
|
func (x *operand) isNil() bool { return x.mode == nilvalue }
|
||||||
|
|
||||||
// assignableTo reports whether x is assignable to a variable of type T. If the
|
// assignableTo reports whether x is assignable to a variable of type T. If the
|
||||||
// result is false and a non-nil reason is provided, it may be set to a more
|
// result is false and a non-nil cause is provided, it may be set to a more
|
||||||
// detailed explanation of the failure (result != ""). The returned error code
|
// detailed explanation of the failure (result != ""). The returned error code
|
||||||
// is only valid if the (first) result is false. The check parameter may be nil
|
// is only valid if the (first) result is false. The check parameter may be nil
|
||||||
// if assignableTo is invoked through an exported API call, i.e., when all
|
// if assignableTo is invoked through an exported API call, i.e., when all
|
||||||
// methods have been type-checked.
|
// methods have been type-checked.
|
||||||
func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, errorCode) {
|
func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, errorCode) {
|
||||||
if x.mode == invalid || T == Typ[Invalid] {
|
if x.mode == invalid || T == Typ[Invalid] {
|
||||||
return true, 0 // avoid spurious errors
|
return true, 0 // avoid spurious errors
|
||||||
}
|
}
|
||||||
@ -288,7 +288,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
// T is an interface type and x implements T and T is not a type parameter.
|
// T is an interface type and x implements T and T is not a type parameter.
|
||||||
// Also handle the case where T is a pointer to an interface.
|
// Also handle the case where T is a pointer to an interface.
|
||||||
if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
|
if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
|
||||||
if !check.implements(V, T, reason) {
|
if !check.implements(V, T, cause) {
|
||||||
return false, _InvalidIfaceAssign
|
return false, _InvalidIfaceAssign
|
||||||
}
|
}
|
||||||
return true, 0
|
return true, 0
|
||||||
@ -298,8 +298,8 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
|
if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
|
||||||
if check.implements(T, V, nil) {
|
if check.implements(T, V, nil) {
|
||||||
// T implements V, so give hint about type assertion.
|
// T implements V, so give hint about type assertion.
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = "need type assertion"
|
*cause = "need type assertion"
|
||||||
}
|
}
|
||||||
return false, _IncompatibleAssign
|
return false, _IncompatibleAssign
|
||||||
}
|
}
|
||||||
@ -320,12 +320,12 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorf := func(format string, args ...interface{}) {
|
errorf := func(format string, args ...interface{}) {
|
||||||
if check != nil && reason != nil {
|
if check != nil && cause != nil {
|
||||||
msg := check.sprintf(format, args...)
|
msg := check.sprintf(format, args...)
|
||||||
if *reason != "" {
|
if *cause != "" {
|
||||||
msg += "\n\t" + *reason
|
msg += "\n\t" + *cause
|
||||||
}
|
}
|
||||||
*reason = msg
|
*cause = msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,7 +338,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
if T == nil {
|
if T == nil {
|
||||||
return false // no specific types
|
return false // no specific types
|
||||||
}
|
}
|
||||||
ok, code = x.assignableTo(check, T.typ, reason)
|
ok, code = x.assignableTo(check, T.typ, cause)
|
||||||
if !ok {
|
if !ok {
|
||||||
errorf("cannot assign %s to %s (in %s)", x.typ, T.typ, Tp)
|
errorf("cannot assign %s to %s (in %s)", x.typ, T.typ, Tp)
|
||||||
return false
|
return false
|
||||||
@ -360,7 +360,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
return false // no specific types
|
return false // no specific types
|
||||||
}
|
}
|
||||||
x.typ = V.typ
|
x.typ = V.typ
|
||||||
ok, code = x.assignableTo(check, T, reason)
|
ok, code = x.assignableTo(check, T, cause)
|
||||||
if !ok {
|
if !ok {
|
||||||
errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
|
errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
|
||||||
return false
|
return false
|
||||||
|
@ -188,14 +188,14 @@ func (check *Checker) definedType(e syntax.Expr, def *Named) Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// genericType is like typ but the type must be an (uninstantiated) generic
|
// genericType is like typ but the type must be an (uninstantiated) generic
|
||||||
// type. If reason is non-nil and the type expression was a valid type but not
|
// type. If cause is non-nil and the type expression was a valid type but not
|
||||||
// generic, reason will be populated with a message describing the error.
|
// generic, cause will be populated with a message describing the error.
|
||||||
func (check *Checker) genericType(e syntax.Expr, reason *string) Type {
|
func (check *Checker) genericType(e syntax.Expr, cause *string) Type {
|
||||||
typ := check.typInternal(e, nil)
|
typ := check.typInternal(e, nil)
|
||||||
assert(isTyped(typ))
|
assert(isTyped(typ))
|
||||||
if typ != Typ[Invalid] && !isGeneric(typ) {
|
if typ != Typ[Invalid] && !isGeneric(typ) {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s is not a generic type", typ)
|
*cause = check.sprintf("%s is not a generic type", typ)
|
||||||
}
|
}
|
||||||
typ = Typ[Invalid]
|
typ = Typ[Invalid]
|
||||||
}
|
}
|
||||||
@ -413,10 +413,10 @@ func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
var reason string
|
var cause string
|
||||||
gtyp := check.genericType(x, &reason)
|
gtyp := check.genericType(x, &cause)
|
||||||
if reason != "" {
|
if cause != "" {
|
||||||
check.errorf(x, _NotAGenericType, invalidOp+"%s%s (%s)", x, xlist, reason)
|
check.errorf(x, _NotAGenericType, invalidOp+"%s%s (%s)", x, xlist, cause)
|
||||||
}
|
}
|
||||||
if gtyp == Typ[Invalid] {
|
if gtyp == Typ[Invalid] {
|
||||||
return gtyp // error already reported
|
return gtyp // error already reported
|
||||||
|
@ -1711,7 +1711,7 @@ func (check *Checker) typeAssertion(e ast.Expr, x *operand, T Type, typeSwitch b
|
|||||||
return // success
|
return // success
|
||||||
}
|
}
|
||||||
|
|
||||||
cause := check.missingMethodReason(T, x.typ, method, alt)
|
cause := check.missingMethodCause(T, x.typ, method, alt)
|
||||||
|
|
||||||
if typeSwitch {
|
if typeSwitch {
|
||||||
check.errorf(e, _ImpossibleAssert, "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)
|
||||||
|
@ -174,9 +174,9 @@ func (check *Checker) verify(pos token.Pos, tparams []*TypeParam, targs []Type,
|
|||||||
// need to instantiate it with the type arguments with which we instantiated
|
// need to instantiate it with the type arguments with which we instantiated
|
||||||
// the parameterized type.
|
// the parameterized type.
|
||||||
bound := check.subst(pos, tpar.bound, smap, nil, ctxt)
|
bound := check.subst(pos, tpar.bound, smap, nil, ctxt)
|
||||||
var reason string
|
var cause string
|
||||||
if !check.implements(targs[i], bound, &reason) {
|
if !check.implements(targs[i], bound, &cause) {
|
||||||
return i, errors.New(reason)
|
return i, errors.New(cause)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1, nil
|
return -1, nil
|
||||||
@ -185,9 +185,9 @@ func (check *Checker) verify(pos token.Pos, tparams []*TypeParam, targs []Type,
|
|||||||
// implements checks if V implements T. The receiver may be nil if implements
|
// implements checks if V implements T. The receiver may be nil if implements
|
||||||
// is called through an exported API call such as AssignableTo.
|
// is called through an exported API call such as AssignableTo.
|
||||||
//
|
//
|
||||||
// If the provided reason is non-nil, it may be set to an error string
|
// If the provided cause is non-nil, it may be set to an error string
|
||||||
// explaining why V does not implement T.
|
// explaining why V does not implement T.
|
||||||
func (check *Checker) implements(V, T Type, reason *string) bool {
|
func (check *Checker) implements(V, T Type, cause *string) bool {
|
||||||
Vu := under(V)
|
Vu := under(V)
|
||||||
Tu := under(T)
|
Tu := under(T)
|
||||||
if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
|
if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
|
||||||
@ -199,14 +199,14 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
|
|
||||||
Ti, _ := Tu.(*Interface)
|
Ti, _ := Tu.(*Interface)
|
||||||
if Ti == nil {
|
if Ti == nil {
|
||||||
var cause string
|
var detail string
|
||||||
if isInterfacePtr(Tu) {
|
if isInterfacePtr(Tu) {
|
||||||
cause = check.sprintf("type %s is pointer to interface, not interface", T)
|
detail = check.sprintf("type %s is pointer to interface, not interface", T)
|
||||||
} else {
|
} else {
|
||||||
cause = check.sprintf("%s is not an interface", T)
|
detail = check.sprintf("%s is not an interface", T)
|
||||||
}
|
}
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s does not implement %s (%s)", V, T, cause)
|
*cause = check.sprintf("%s does not implement %s (%s)", V, T, detail)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -227,16 +227,16 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
|
|
||||||
// No type with non-empty type set satisfies the empty type set.
|
// No type with non-empty type set satisfies the empty type set.
|
||||||
if Ti.typeSet().IsEmpty() {
|
if Ti.typeSet().IsEmpty() {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("cannot implement %s (empty type set)", T)
|
*cause = check.sprintf("cannot implement %s (empty type set)", T)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// V must implement T's methods, if any.
|
// V must implement T's methods, if any.
|
||||||
if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
|
if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s does not implement %s %s", V, T, check.missingMethodReason(V, T, m, wrong))
|
*cause = check.sprintf("%s does not implement %s %s", V, T, check.missingMethodCause(V, T, m, wrong))
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -245,8 +245,8 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
checkComparability := func() bool {
|
checkComparability := func() bool {
|
||||||
// If T is comparable, V must be comparable.
|
// If T is comparable, V must be comparable.
|
||||||
if Ti.IsComparable() && !comparable(V, false, nil, nil) {
|
if Ti.IsComparable() && !comparable(V, false, nil, nil) {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s does not implement comparable", V)
|
*cause = check.sprintf("%s does not implement comparable", V)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -265,8 +265,8 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
if Vi != nil {
|
if Vi != nil {
|
||||||
if !Vi.typeSet().subsetOf(Ti.typeSet()) {
|
if !Vi.typeSet().subsetOf(Ti.typeSet()) {
|
||||||
// TODO(gri) report which type is missing
|
// TODO(gri) report which type is missing
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s does not implement %s", V, T)
|
*cause = check.sprintf("%s does not implement %s", V, T)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -291,11 +291,11 @@ func (check *Checker) implements(V, T Type, reason *string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}) {
|
}) {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
if alt != nil {
|
if alt != nil {
|
||||||
*reason = check.sprintf("%s does not implement %s (possibly missing ~ for %s in constraint %s)", V, T, alt, T)
|
*cause = check.sprintf("%s does not implement %s (possibly missing ~ for %s in constraint %s)", V, T, alt, T)
|
||||||
} else {
|
} else {
|
||||||
*reason = check.sprintf("%s does not implement %s (%s missing in %s)", V, T, V, Ti.typeSet().terms)
|
*cause = check.sprintf("%s does not implement %s (%s missing in %s)", V, T, V, Ti.typeSet().terms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -364,13 +364,13 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// missingMethodReason returns a string giving the detailed reason for a missing method m,
|
// missingMethodCause returns a string giving the detailed cause for a missing method m,
|
||||||
// where m is missing from V, but required by T. It puts the reason in parentheses,
|
// where m is missing from V, but required by T. It puts the cause in parentheses,
|
||||||
// and may include more have/want info after that. If non-nil, alt is a relevant
|
// and may include more have/want info after that. If non-nil, alt is a relevant
|
||||||
// method that matches in some way. It may have the correct name, but wrong type, or
|
// method that matches in some way. It may have the correct name, but wrong type, or
|
||||||
// it may have a pointer receiver, or it may have the correct name except wrong case.
|
// it may have a pointer receiver, or it may have the correct name except wrong case.
|
||||||
// check may be nil.
|
// check may be nil.
|
||||||
func (check *Checker) missingMethodReason(V, T Type, m, alt *Func) string {
|
func (check *Checker) missingMethodCause(V, T Type, m, alt *Func) string {
|
||||||
mname := "method " + m.Name()
|
mname := "method " + m.Name()
|
||||||
|
|
||||||
if alt != nil {
|
if alt != nil {
|
||||||
|
@ -223,12 +223,12 @@ func (x *operand) isNil() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// assignableTo reports whether x is assignable to a variable of type T. If the
|
// assignableTo reports whether x is assignable to a variable of type T. If the
|
||||||
// result is false and a non-nil reason is provided, it may be set to a more
|
// result is false and a non-nil cause is provided, it may be set to a more
|
||||||
// detailed explanation of the failure (result != ""). The returned error code
|
// detailed explanation of the failure (result != ""). The returned error code
|
||||||
// is only valid if the (first) result is false. The check parameter may be nil
|
// is only valid if the (first) result is false. The check parameter may be nil
|
||||||
// if assignableTo is invoked through an exported API call, i.e., when all
|
// if assignableTo is invoked through an exported API call, i.e., when all
|
||||||
// methods have been type-checked.
|
// methods have been type-checked.
|
||||||
func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, errorCode) {
|
func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, errorCode) {
|
||||||
if x.mode == invalid || T == Typ[Invalid] {
|
if x.mode == invalid || T == Typ[Invalid] {
|
||||||
return true, 0 // avoid spurious errors
|
return true, 0 // avoid spurious errors
|
||||||
}
|
}
|
||||||
@ -277,7 +277,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
// T is an interface type and x implements T and T is not a type parameter.
|
// T is an interface type and x implements T and T is not a type parameter.
|
||||||
// Also handle the case where T is a pointer to an interface.
|
// Also handle the case where T is a pointer to an interface.
|
||||||
if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
|
if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
|
||||||
if !check.implements(V, T, reason) {
|
if !check.implements(V, T, cause) {
|
||||||
return false, _InvalidIfaceAssign
|
return false, _InvalidIfaceAssign
|
||||||
}
|
}
|
||||||
return true, 0
|
return true, 0
|
||||||
@ -287,8 +287,8 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
|
if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
|
||||||
if check.implements(T, V, nil) {
|
if check.implements(T, V, nil) {
|
||||||
// T implements V, so give hint about type assertion.
|
// T implements V, so give hint about type assertion.
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = "need type assertion"
|
*cause = "need type assertion"
|
||||||
}
|
}
|
||||||
return false, _IncompatibleAssign
|
return false, _IncompatibleAssign
|
||||||
}
|
}
|
||||||
@ -309,12 +309,12 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorf := func(format string, args ...any) {
|
errorf := func(format string, args ...any) {
|
||||||
if check != nil && reason != nil {
|
if check != nil && cause != nil {
|
||||||
msg := check.sprintf(format, args...)
|
msg := check.sprintf(format, args...)
|
||||||
if *reason != "" {
|
if *cause != "" {
|
||||||
msg += "\n\t" + *reason
|
msg += "\n\t" + *cause
|
||||||
}
|
}
|
||||||
*reason = msg
|
*cause = msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
if T == nil {
|
if T == nil {
|
||||||
return false // no specific types
|
return false // no specific types
|
||||||
}
|
}
|
||||||
ok, code = x.assignableTo(check, T.typ, reason)
|
ok, code = x.assignableTo(check, T.typ, cause)
|
||||||
if !ok {
|
if !ok {
|
||||||
errorf("cannot assign %s to %s (in %s)", x.typ, T.typ, Tp)
|
errorf("cannot assign %s to %s (in %s)", x.typ, T.typ, Tp)
|
||||||
return false
|
return false
|
||||||
@ -349,7 +349,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
|
|||||||
return false // no specific types
|
return false // no specific types
|
||||||
}
|
}
|
||||||
x.typ = V.typ
|
x.typ = V.typ
|
||||||
ok, code = x.assignableTo(check, T, reason)
|
ok, code = x.assignableTo(check, T, cause)
|
||||||
if !ok {
|
if !ok {
|
||||||
errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
|
errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
|
||||||
return false
|
return false
|
||||||
|
@ -188,14 +188,14 @@ func (check *Checker) definedType(e ast.Expr, def *Named) Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// genericType is like typ but the type must be an (uninstantiated) generic
|
// genericType is like typ but the type must be an (uninstantiated) generic
|
||||||
// type. If reason is non-nil and the type expression was a valid type but not
|
// type. If cause is non-nil and the type expression was a valid type but not
|
||||||
// generic, reason will be populated with a message describing the error.
|
// generic, cause will be populated with a message describing the error.
|
||||||
func (check *Checker) genericType(e ast.Expr, reason *string) Type {
|
func (check *Checker) genericType(e ast.Expr, cause *string) Type {
|
||||||
typ := check.typInternal(e, nil)
|
typ := check.typInternal(e, nil)
|
||||||
assert(isTyped(typ))
|
assert(isTyped(typ))
|
||||||
if typ != Typ[Invalid] && !isGeneric(typ) {
|
if typ != Typ[Invalid] && !isGeneric(typ) {
|
||||||
if reason != nil {
|
if cause != nil {
|
||||||
*reason = check.sprintf("%s is not a generic type", typ)
|
*cause = check.sprintf("%s is not a generic type", typ)
|
||||||
}
|
}
|
||||||
typ = Typ[Invalid]
|
typ = Typ[Invalid]
|
||||||
}
|
}
|
||||||
@ -404,10 +404,10 @@ func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *Named) (re
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
var reason string
|
var cause string
|
||||||
gtyp := check.genericType(ix.X, &reason)
|
gtyp := check.genericType(ix.X, &cause)
|
||||||
if reason != "" {
|
if cause != "" {
|
||||||
check.invalidOp(ix.Orig, _NotAGenericType, "%s (%s)", ix.Orig, reason)
|
check.invalidOp(ix.Orig, _NotAGenericType, "%s (%s)", ix.Orig, cause)
|
||||||
}
|
}
|
||||||
if gtyp == Typ[Invalid] {
|
if gtyp == Typ[Invalid] {
|
||||||
return gtyp // error already reported
|
return gtyp // error already reported
|
||||||
|
Loading…
Reference in New Issue
Block a user