Do not return prematurely in assignableTo.
Fixes #54424.
Change-Id: I769b3b4ad9d79b7bce60b92cc59c3564117e36db
Reviewed-on: https://go-review.googlesource.com/c/go/+/498400
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
return true, 0
}
- // 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.
+ // T is an interface type, but not a type parameter, and V implements T.
+ // Also handle the case where T is a pointer to an interface so that we get
+ // the Checker.implements error cause.
if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
- if !check.implements(x.Pos(), V, T, false, cause) {
+ if check.implements(x.Pos(), V, T, false, cause) {
+ return true, 0
+ }
+ // V doesn't implement T but V may still be assignable to T if V
+ // is a type parameter; do not report an error in that case yet.
+ if Vp == nil {
return false, InvalidIfaceAssign
}
- return true, 0
+ if cause != nil {
+ *cause = ""
+ }
}
// If V is an interface, check if a missing type assertion is the problem.
return true, 0
}
- // 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.
+ // T is an interface type, but not a type parameter, and V implements T.
+ // Also handle the case where T is a pointer to an interface so that we get
+ // the Checker.implements error cause.
if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
- if !check.implements(x.Pos(), V, T, false, cause) {
+ if check.implements(x.Pos(), V, T, false, cause) {
+ return true, 0
+ }
+ // V doesn't implement T but V may still be assignable to T if V
+ // is a type parameter; do not report an error in that case yet.
+ if Vp == nil {
return false, InvalidIfaceAssign
}
- return true, 0
+ if cause != nil {
+ *cause = ""
+ }
}
// If V is an interface, check if a missing type assertion is the problem.
--- /dev/null
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f[P ~*T, T any]() {
+ var p P
+ var tp *T
+ tp = p // this assignment is valid
+ _ = tp
+}