mirror of https://github.com/golang/go.git
go/types, types2: fix incorrect logic in assignability check
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>
This commit is contained in:
parent
96d16803c2
commit
05293d6b49
|
|
@ -290,13 +290,21 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -277,13 +277,21 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
// 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
|
||||
}
|
||||
Loading…
Reference in New Issue