cmd/compile: fix type error reported on the wrong line

The 'Does not match' type error shoud be reported where
the function is called, not where the function is declared.

And fix the todo by gri of issue45985

Fixes #45985
Fixes #49800

Change-Id: I15aac44dd44f2a57c485a1c273fcd79db912c389
Reviewed-on: https://go-review.googlesource.com/c/go/+/362634
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Jason7602 2021-11-09 23:46:41 +08:00 committed by Robert Findley
parent 78b4518e31
commit ece493eb83
4 changed files with 14 additions and 16 deletions

View File

@ -60,7 +60,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
// If we have type arguments, see how far we get with constraint type inference. // If we have type arguments, see how far we get with constraint type inference.
if len(targs) > 0 && useConstraintTypeInference { if len(targs) > 0 && useConstraintTypeInference {
var index int var index int
targs, index = check.inferB(tparams, targs) targs, index = check.inferB(pos, tparams, targs)
if targs == nil || index < 0 { if targs == nil || index < 0 {
return targs return targs
} }
@ -171,7 +171,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
// Note that even if we don't have any type arguments, constraint type inference // Note that even if we don't have any type arguments, constraint type inference
// may produce results for constraints that explicitly specify a type. // may produce results for constraints that explicitly specify a type.
if useConstraintTypeInference { if useConstraintTypeInference {
targs, index = check.inferB(tparams, targs) targs, index = check.inferB(pos, tparams, targs)
if targs == nil || index < 0 { if targs == nil || index < 0 {
return targs return targs
} }
@ -209,7 +209,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
// Again, follow up with constraint type inference. // Again, follow up with constraint type inference.
if useConstraintTypeInference { if useConstraintTypeInference {
targs, index = check.inferB(tparams, targs) targs, index = check.inferB(pos, tparams, targs)
if targs == nil || index < 0 { if targs == nil || index < 0 {
return targs return targs
} }
@ -360,7 +360,7 @@ func (w *tpWalker) isParameterizedTypeList(list []Type) bool {
// first type argument in that list that couldn't be inferred (and thus is nil). If all // first type argument in that list that couldn't be inferred (and thus is nil). If all
// type arguments were inferred successfully, index is < 0. The number of type arguments // type arguments were inferred successfully, index is < 0. The number of type arguments
// provided may be less than the number of type parameters, but there must be at least one. // provided may be less than the number of type parameters, but there must be at least one.
func (check *Checker) inferB(tparams []*TypeParam, targs []Type) (types []Type, index int) { func (check *Checker) inferB(pos syntax.Pos, tparams []*TypeParam, targs []Type) (types []Type, index int) {
assert(len(tparams) >= len(targs) && len(targs) > 0) assert(len(tparams) >= len(targs) && len(targs) > 0)
// Setup bidirectional unification between constraints // Setup bidirectional unification between constraints
@ -388,7 +388,7 @@ func (check *Checker) inferB(tparams []*TypeParam, targs []Type) (types []Type,
if !u.unify(tpar, sbound) { if !u.unify(tpar, sbound) {
// TODO(gri) improve error message by providing the type arguments // TODO(gri) improve error message by providing the type arguments
// which we know already // which we know already
check.errorf(tpar.obj, "%s does not match %s", tpar, sbound) check.errorf(pos, "%s does not match %s", tpar, sbound)
return nil, 0 return nil, 0
} }
} }

View File

@ -4,11 +4,10 @@
package issue45985 package issue45985
// TODO(gri): this error should be on app[int] below. func app[S interface{ ~[]T }, T any](s S, e T) S {
func app[S /* ERROR "S does not match" */ interface{ ~[]T }, T any](s S, e T) S {
return append(s, e) return append(s, e)
} }
func _() { func _() {
_ = app[int] _ = app[/* ERROR "S does not match" */int]
} }

View File

@ -59,7 +59,7 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
// If we have type arguments, see how far we get with constraint type inference. // If we have type arguments, see how far we get with constraint type inference.
if len(targs) > 0 { if len(targs) > 0 {
var index int var index int
targs, index = check.inferB(tparams, targs) targs, index = check.inferB(posn, tparams, targs)
if targs == nil || index < 0 { if targs == nil || index < 0 {
return targs return targs
} }
@ -174,7 +174,7 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
// See how far we get with constraint type inference. // See how far we get with constraint type inference.
// Note that even if we don't have any type arguments, constraint type inference // Note that even if we don't have any type arguments, constraint type inference
// may produce results for constraints that explicitly specify a type. // may produce results for constraints that explicitly specify a type.
targs, index = check.inferB(tparams, targs) targs, index = check.inferB(posn, tparams, targs)
if targs == nil || index < 0 { if targs == nil || index < 0 {
return targs return targs
} }
@ -210,7 +210,7 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
} }
// Again, follow up with constraint type inference. // Again, follow up with constraint type inference.
targs, index = check.inferB(tparams, targs) targs, index = check.inferB(posn, tparams, targs)
if targs == nil || index < 0 { if targs == nil || index < 0 {
return targs return targs
} }
@ -359,7 +359,7 @@ func (w *tpWalker) isParameterizedTypeList(list []Type) bool {
// first type argument in that list that couldn't be inferred (and thus is nil). If all // first type argument in that list that couldn't be inferred (and thus is nil). If all
// type arguments were inferred successfully, index is < 0. The number of type arguments // type arguments were inferred successfully, index is < 0. The number of type arguments
// provided may be less than the number of type parameters, but there must be at least one. // provided may be less than the number of type parameters, but there must be at least one.
func (check *Checker) inferB(tparams []*TypeParam, targs []Type) (types []Type, index int) { func (check *Checker) inferB(posn positioner, tparams []*TypeParam, targs []Type) (types []Type, index int) {
assert(len(tparams) >= len(targs) && len(targs) > 0) assert(len(tparams) >= len(targs) && len(targs) > 0)
// Setup bidirectional unification between constraints // Setup bidirectional unification between constraints
@ -387,7 +387,7 @@ func (check *Checker) inferB(tparams []*TypeParam, targs []Type) (types []Type,
if !u.unify(tpar, sbound) { if !u.unify(tpar, sbound) {
// TODO(gri) improve error message by providing the type arguments // TODO(gri) improve error message by providing the type arguments
// which we know already // which we know already
check.errorf(tpar.obj, _InvalidTypeArg, "%s does not match %s", tpar, sbound) check.errorf(posn, _InvalidTypeArg, "%s does not match %s", tpar, sbound)
return nil, 0 return nil, 0
} }
} }

View File

@ -4,11 +4,10 @@
package issue45985 package issue45985
// TODO(rFindley): this error should be on app[int] below. func app[S interface{ ~[]T }, T any](s S, e T) S {
func app[S /* ERROR "S does not match" */ interface{ ~[]T }, T any](s S, e T) S {
return append(s, e) return append(s, e)
} }
func _() { func _() {
_ = app[int] _ = app/* ERROR "S does not match" */[int]
} }