mirror of https://github.com/golang/go.git
go/types: fix numeric conversions between type parameter types
The implementation of conversions T(x) between integers and floating-point numbers checks that both T and x have either integer or floating-point type. When the type of T or x is a type parameter, the respective simple predicate disjunction in the implementation was wrong because if a type list contains both an integer and a floating-point type, the type parameter is neither an integer or a floating-point number. Change-Id: I007aa956007ab1a0228e0ee2fca05804686b404c Reviewed-on: https://team-review.git.corp.google.com/c/golang/go2-dev/+/759562 Reviewed-by: Robert Griesemer <gri@google.com>
This commit is contained in:
parent
716d51681b
commit
0fa4f81317
|
|
@ -104,7 +104,7 @@ func (x *operand) convertibleTo(check *Checker, T Type) bool {
|
|||
}
|
||||
|
||||
// "x's type and T are both integer or floating point types"
|
||||
if (isInteger(V) || isFloat(V)) && (isInteger(T) || isFloat(T)) {
|
||||
if isIntegerOrFloat(V) && isIntegerOrFloat(T) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@ func isComplex(typ Type) bool { return is(typ, IsComplex) }
|
|||
func isNumeric(typ Type) bool { return is(typ, IsNumeric) }
|
||||
func isString(typ Type) bool { return is(typ, IsString) }
|
||||
|
||||
// Note that if typ is a type parameter, isInteger(typ) || isFloat(typ) does not
|
||||
// produce the expected result because a type list that contains both an integer
|
||||
// and a floating-point type is neither (all) integers, nor (all) floats.
|
||||
// Use isIntegerOrFloat instead.
|
||||
func isIntegerOrFloat(typ Type) bool { return is(typ, IsInteger|IsFloat) }
|
||||
|
||||
// isTyped reports whether typ is typed; i.e., not an untyped
|
||||
// constant or boolean. isTyped may be called with types that
|
||||
// are not fully set up.
|
||||
|
|
|
|||
|
|
@ -232,3 +232,17 @@ type List3(type TElem) struct {
|
|||
// Infinite generic type declarations must lead to an error.
|
||||
type inf1(type T) struct{ _ inf1 /* ERROR illegal cycle */ (T) }
|
||||
type inf2(type T) struct{ (inf2 /* ERROR illegal cycle */ (T)) }
|
||||
|
||||
// The implementation of conversions T(x) between integers and floating-point
|
||||
// numbers checks that both T and x have either integer or floating-point
|
||||
// type. When the type of T or x is a type parameter, the respective simple
|
||||
// predicate disjunction in the implementation was wrong because if a type list
|
||||
// contains both an integer and a floating-point type, the type parameter is
|
||||
// neither an integer or a floating-point number.
|
||||
func convert(type T1, T2 interface{type int, uint, float32})(v T1) T2 {
|
||||
return T2(v)
|
||||
}
|
||||
|
||||
func _() {
|
||||
convert(int, uint)(5)
|
||||
}
|
||||
Loading…
Reference in New Issue