mirror of
https://github.com/golang/go
synced 2024-11-17 15:54:39 -07:00
cmd/compile/internal/types2: use correct types when checking generic conversions
Iterate through the actual, possibly defined types of constraints when type-checking generic conversions, not the underlying types. For #47150. Change-Id: Ia7af313bf46d6f6b0ad5292ff793b030b8e2d3d8 Reviewed-on: https://go-review.googlesource.com/c/go/+/357333 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
4320949f36
commit
3ff39c5eda
@ -98,21 +98,21 @@ func (x *operand) convertibleTo(check *Checker, T Type) bool {
|
||||
switch {
|
||||
case Vp != nil && Tp != nil:
|
||||
x := *x // don't modify outer x
|
||||
return Vp.underIs(func(V Type) bool {
|
||||
x.typ = V
|
||||
return Tp.underIs(func(T Type) bool {
|
||||
return x.convertibleToImpl(check, T)
|
||||
return Vp.is(func(V *term) bool {
|
||||
x.typ = V.typ
|
||||
return Tp.is(func(T *term) bool {
|
||||
return x.convertibleToImpl(check, T.typ)
|
||||
})
|
||||
})
|
||||
case Vp != nil:
|
||||
x := *x // don't modify outer x
|
||||
return Vp.underIs(func(V Type) bool {
|
||||
x.typ = V
|
||||
return Vp.is(func(V *term) bool {
|
||||
x.typ = V.typ
|
||||
return x.convertibleToImpl(check, T)
|
||||
})
|
||||
case Tp != nil:
|
||||
return Tp.underIs(func(T Type) bool {
|
||||
return x.convertibleToImpl(check, T)
|
||||
return Tp.is(func(T *term) bool {
|
||||
return x.convertibleToImpl(check, T.typ)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,20 @@ func _[X ~*Foo|~*Bar, T ~*Bar](x X) T { return T(x) }
|
||||
func _[X ~*Foo, T ~*Foo|~*Bar](x X) T { return T(x) }
|
||||
func _[X ~*Foo, T ~*Far](x X) T { return T(x /* ERROR cannot convert */ ) }
|
||||
|
||||
// Verify that the defined types in constraints are considered for the rule above.
|
||||
|
||||
type (
|
||||
B int
|
||||
C int
|
||||
X0 *B
|
||||
T0 *C
|
||||
)
|
||||
|
||||
func _(x X0) T0 { return T0(x /* ERROR cannot convert */ ) } // non-generic reference
|
||||
func _[X X0, T T0](x X) T { return T(x /* ERROR cannot convert */ ) }
|
||||
func _[T T0](x X0) T { return T(x /* ERROR cannot convert */ ) }
|
||||
func _[X X0](x X) T0 { return T0(x /* ERROR cannot convert */ ) }
|
||||
|
||||
// "x's type and T are both integer or floating point types"
|
||||
|
||||
func _[X Integer, T Integer](x X) T { return T(x) }
|
||||
|
Loading…
Reference in New Issue
Block a user