mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-03 10:24:44 +00:00
Fix int literals and range interaction (#11197)
* Fix int literals and range interaction * Fix test * remove float range fix; update changelog
This commit is contained in:
committed by
Andreas Rumpf
parent
6e01be34ef
commit
35268c500f
@@ -34,6 +34,8 @@ type
|
||||
|
||||
### Breaking changes in the compiler
|
||||
|
||||
- A bug allowing `int` to be implicitly converted to range types of smaller size (e.g `range[0'i8..10'i8]`) has been fixed.
|
||||
|
||||
|
||||
## Library additions
|
||||
|
||||
|
||||
@@ -401,18 +401,20 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||
else: result = isNone
|
||||
|
||||
proc isConvertibleToRange(f, a: PType): bool =
|
||||
# be less picky for tyRange, as that it is used for array indexing:
|
||||
if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and
|
||||
a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}:
|
||||
case f.kind
|
||||
of tyInt, tyInt64: result = true
|
||||
of tyInt8: result = a.kind in {tyInt8, tyInt}
|
||||
of tyInt16: result = a.kind in {tyInt8, tyInt16, tyInt}
|
||||
of tyInt32: result = a.kind in {tyInt8, tyInt16, tyInt32, tyInt}
|
||||
of tyUInt, tyUInt64: result = true
|
||||
of tyUInt8: result = a.kind in {tyUInt8, tyUInt}
|
||||
of tyUInt16: result = a.kind in {tyUInt8, tyUInt16, tyUInt}
|
||||
of tyUInt32: result = a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
|
||||
of tyInt8: result = isIntLit(a) or a.kind in {tyInt8}
|
||||
of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
|
||||
of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
|
||||
# This is wrong, but seems like there's a lot of code that relies on it :(
|
||||
of tyInt: result = true
|
||||
of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
|
||||
of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
|
||||
of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
|
||||
of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
|
||||
of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
|
||||
of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64}
|
||||
else: result = false
|
||||
elif f.kind in {tyFloat..tyFloat128}:
|
||||
# `isIntLit` is correct and should be used above as well, see PR:
|
||||
|
||||
@@ -2282,9 +2282,11 @@ algorithm returns true:
|
||||
proc isImplicitlyConvertible(a, b: PType): bool =
|
||||
if isSubtype(a, b) or isCovariant(a, b):
|
||||
return true
|
||||
if isIntLiteral(a):
|
||||
return b in {int8, int16, int32, int64, int, uint, uint8, uint16,
|
||||
uint32, uint64, float32, float64}
|
||||
case a.kind
|
||||
of int: result = b in {int8, int16, int32, int64, uint, uint8, uint16,
|
||||
uint32, uint64, float, float32, float64}
|
||||
of int: result = b in {int32, int64}
|
||||
of int8: result = b in {int16, int32, int64, int}
|
||||
of int16: result = b in {int32, int64, int}
|
||||
of int32: result = b in {int64, int}
|
||||
@@ -2292,9 +2294,8 @@ algorithm returns true:
|
||||
of uint8: result = b in {uint16, uint32, uint64}
|
||||
of uint16: result = b in {uint32, uint64}
|
||||
of uint32: result = b in {uint64}
|
||||
of float: result = b in {float32, float64}
|
||||
of float32: result = b in {float64, float}
|
||||
of float64: result = b in {float32, float}
|
||||
of float32: result = b in {float64}
|
||||
of float64: result = b in {float32}
|
||||
of seq:
|
||||
result = b == openArray and typeEquals(a.baseType, b.baseType)
|
||||
of array:
|
||||
|
||||
@@ -142,5 +142,5 @@ block tsubrange:
|
||||
var level: n16 = 1
|
||||
let maxLevel: n16 = 1
|
||||
|
||||
level = min(level + 2, maxLevel)
|
||||
level = min(level + 2, maxLevel).n16
|
||||
doAssert level == 1
|
||||
|
||||
@@ -122,10 +122,17 @@ block:
|
||||
block:
|
||||
var x1: range[0'f..1'f] = 1
|
||||
const x2: range[0'f..1'f] = 1
|
||||
var x3: range[0'u8..1'u8] = 1
|
||||
const x4: range[0'u8..1'u8] = 1
|
||||
|
||||
var x5: range[0'f32..1'f32] = 1'f64
|
||||
const x6: range[0'f32..1'f32] = 1'f64
|
||||
|
||||
reject:
|
||||
const x: range[0'f..1'f] = 2'f
|
||||
var x09: range[0'i8..1'i8] = 1.int
|
||||
reject:
|
||||
const x: range[0'f..1'f] = 2
|
||||
var x10: range[0'i64..1'i64] = 1'u64
|
||||
|
||||
const x11: range[0'f..1'f] = 2'f
|
||||
reject:
|
||||
const x12: range[0'f..1'f] = 2
|
||||
|
||||
Reference in New Issue
Block a user