mirror of https://github.com/golang/go.git
go/types: better error messages for type inference
Change-Id: I8a5b07eca76b084901cce6f1bae4f8d107d10701
This commit is contained in:
parent
1ad26bf1a7
commit
ac135a4bcf
|
|
@ -18,6 +18,17 @@ func (check *Checker) infer(pos token.Pos, tparams []*TypeName, params *Tuple, a
|
|||
u := check.unifier()
|
||||
u.x.init(tparams)
|
||||
|
||||
errorf := func(kind string, tpar, targ Type, arg *operand) {
|
||||
// provide a better error message if we can
|
||||
if tpar, _ := tpar.(*TypeParam); tpar != nil {
|
||||
if inferred := u.x.at(tpar.index); inferred != nil {
|
||||
check.errorf(arg.pos(), "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
|
||||
return
|
||||
}
|
||||
}
|
||||
check.errorf(arg.pos(), "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
|
||||
}
|
||||
|
||||
// Terminology: generic parameter = function parameter with a type-parameterized type
|
||||
|
||||
// 1st pass: Unify parameter and argument types for generic parameters with typed arguments
|
||||
|
|
@ -34,17 +45,12 @@ func (check *Checker) infer(pos token.Pos, tparams []*TypeName, params *Tuple, a
|
|||
// simply ignoring (continue) invalid args
|
||||
return nil // error was reported earlier
|
||||
}
|
||||
if isTyped(arg.typ) {
|
||||
// If we permit bidirectional unification, and arg.typ is
|
||||
// a generic function, we need to initialize u.y with the
|
||||
// respectice type parameters of arg.typ.
|
||||
if !u.unify(par.typ, arg.typ) {
|
||||
// Calling subst for an error message can cause problems.
|
||||
// TODO(gri) Determine best approach here.
|
||||
// check.errorf(arg.pos(), "type %s for %s does not match %s = %s",
|
||||
// arg.typ, arg.expr, par.typ, check.subst(pos, par.typ, tparams, targs),
|
||||
// )
|
||||
check.errorf(arg.pos(), "type %s for %s does not match %s", arg.typ, arg.expr, par.typ)
|
||||
if targ := arg.typ; isTyped(targ) {
|
||||
// If we permit bidirectional unification, and targ is
|
||||
// a generic function, we need to initialize u.y with
|
||||
// the respectice type parameters of targ.
|
||||
if !u.unify(par.typ, targ) {
|
||||
errorf("type", par.typ, targ, arg)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
|
|
@ -83,11 +89,7 @@ func (check *Checker) infer(pos token.Pos, tparams []*TypeName, params *Tuple, a
|
|||
// infer an untyped nil type as type parameter type. Ignore untyped
|
||||
// nil by making sure all default argument types are typed.
|
||||
if isTyped(targ) && !u.unify(par.typ, targ) {
|
||||
// TODO(gri) see TODO comment above
|
||||
// check.errorf(arg.pos(), "default type %s for %s does not match %s = %s",
|
||||
// Default(arg.typ), arg.expr, par.typ, check.subst(pos, par.typ, tparams, targs),
|
||||
// )
|
||||
check.errorf(arg.pos(), "default type %s for %s does not match %s", Default(arg.typ), arg.expr, par.typ)
|
||||
errorf("default type", par.typ, targ, arg)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,10 @@
|
|||
|
||||
package p
|
||||
|
||||
func f(type _ interface{ m() })()
|
||||
|
||||
type T struct{}
|
||||
func (*T) m()
|
||||
|
||||
func _() {
|
||||
f(T)()
|
||||
func f(type T comparable)(x, y T) bool {
|
||||
return x == y
|
||||
}
|
||||
|
||||
func _(){
|
||||
f(1, 2i /* ERROR does not match */)
|
||||
}
|
||||
Loading…
Reference in New Issue