Tighten the conversion from tyRange to scalar types (#10495)
* Tighten the conversion from tyRange to scalar types. Introduce the `isIntConv` rule for unsigned types. Do not allow mixed-signedness conversions between ranges and scalar types. * More json adjustments
This commit is contained in:
parent
c5dbb0379f
commit
71df1b060b
3 changed files with 66 additions and 14 deletions
|
|
@ -385,18 +385,19 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||||
result = isFromIntLit
|
result = isFromIntLit
|
||||||
elif f.kind == tyInt and k in {tyInt8..tyInt32}:
|
elif f.kind == tyInt and k in {tyInt8..tyInt32}:
|
||||||
result = isIntConv
|
result = isIntConv
|
||||||
|
elif f.kind == tyUInt and k in {tyUInt8..tyUInt32}:
|
||||||
|
result = isIntConv
|
||||||
elif k >= min and k <= max:
|
elif k >= min and k <= max:
|
||||||
result = isConvertible
|
result = isConvertible
|
||||||
elif a.kind == tyRange and a.sons[0].kind in {tyInt..tyInt64,
|
elif a.kind == tyRange and
|
||||||
tyUInt8..tyUInt32} and
|
# Make sure the conversion happens between types w/ same signedness
|
||||||
a.n[0].intVal >= firstOrd(nil, f) and
|
(f.kind in {tyInt..tyInt64} and a[0].kind in {tyInt..tyInt64} or
|
||||||
a.n[1].intVal <= lastOrd(nil, f):
|
f.kind in {tyUInt8..tyUInt32} and a[0].kind in {tyUInt8..tyInt32}) and
|
||||||
|
a.n[0].intVal >= firstOrd(nil, f) and a.n[1].intVal <= lastOrd(nil, f):
|
||||||
# passing 'nil' to firstOrd/lastOrd here as type checking rules should
|
# passing 'nil' to firstOrd/lastOrd here as type checking rules should
|
||||||
# not depent on the target integer size configurations!
|
# not depent on the target integer size configurations!
|
||||||
result = isConvertible
|
result = isConvertible
|
||||||
else: result = isNone
|
else: result = isNone
|
||||||
#elif f.kind == tyInt and k in {tyInt..tyInt32}: result = isIntConv
|
|
||||||
#elif f.kind == tyUInt and k in {tyUInt..tyUInt32}: result = isIntConv
|
|
||||||
|
|
||||||
proc isConvertibleToRange(f, a: PType): bool =
|
proc isConvertibleToRange(f, a: PType): bool =
|
||||||
# be less picky for tyRange, as that it is used for array indexing:
|
# be less picky for tyRange, as that it is used for array indexing:
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,24 @@ proc `%`*(s: string): JsonNode =
|
||||||
result.kind = JString
|
result.kind = JString
|
||||||
result.str = s
|
result.str = s
|
||||||
|
|
||||||
|
proc `%`*(n: uint): JsonNode =
|
||||||
|
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
||||||
|
new(result)
|
||||||
|
result.kind = JInt
|
||||||
|
result.num = BiggestInt(n)
|
||||||
|
|
||||||
|
proc `%`*(n: int): JsonNode =
|
||||||
|
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
||||||
|
new(result)
|
||||||
|
result.kind = JInt
|
||||||
|
result.num = n
|
||||||
|
|
||||||
|
proc `%`*(n: BiggestUInt): JsonNode =
|
||||||
|
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
||||||
|
new(result)
|
||||||
|
result.kind = JInt
|
||||||
|
result.num = BiggestInt(n)
|
||||||
|
|
||||||
proc `%`*(n: BiggestInt): JsonNode =
|
proc `%`*(n: BiggestInt): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
|
|
@ -1757,17 +1775,37 @@ when isMainModule:
|
||||||
# Generate constructors for range[T] types
|
# Generate constructors for range[T] types
|
||||||
block:
|
block:
|
||||||
type
|
type
|
||||||
Q1 = range[0..10]
|
Q1 = range[0'u8 .. 50'u8]
|
||||||
Q2 = range[0'i8..10'i8]
|
Q2 = range[0'u16 .. 50'u16]
|
||||||
Q3 = range[0'u16..10'u16]
|
Q3 = range[0'u32 .. 50'u32]
|
||||||
|
Q4 = range[0'i8 .. 50'i8]
|
||||||
|
Q5 = range[0'i16 .. 50'i16]
|
||||||
|
Q6 = range[0'i32 .. 50'i32]
|
||||||
|
Q7 = range[0'f32 .. 50'f32]
|
||||||
|
Q8 = range[0'f64 .. 50'f64]
|
||||||
|
Q9 = range[0 .. 50]
|
||||||
|
|
||||||
X = object
|
X = object
|
||||||
m1: Q1
|
m1: Q1
|
||||||
m2: Q2
|
m2: Q2
|
||||||
m3: Q3
|
m3: Q3
|
||||||
|
m4: Q4
|
||||||
|
m5: Q5
|
||||||
|
m6: Q6
|
||||||
|
m7: Q7
|
||||||
|
m8: Q8
|
||||||
|
m9: Q9
|
||||||
|
|
||||||
let
|
let obj = X(
|
||||||
obj = X(m1: 1, m2: 2'i8, m3: 3'u16)
|
m1: Q1(42),
|
||||||
jsonObj = %obj
|
m2: Q2(42),
|
||||||
desObj = to(jsonObj, type(obj))
|
m3: Q3(42),
|
||||||
|
m4: Q4(42),
|
||||||
|
m5: Q5(42),
|
||||||
|
m6: Q6(42),
|
||||||
|
m7: Q7(42),
|
||||||
|
m8: Q8(42),
|
||||||
|
m9: Q9(42)
|
||||||
|
)
|
||||||
|
|
||||||
doAssert(desObj == obj)
|
doAssert(obj == to(%obj, type(obj)))
|
||||||
|
|
|
||||||
|
|
@ -105,3 +105,16 @@ block tcolors:
|
||||||
return rgb(red(a) +! red(b), green(a) +! green(b), blue(a) +! blue(b))
|
return rgb(red(a) +! red(b), green(a) +! green(b), blue(a) +! blue(b))
|
||||||
|
|
||||||
rgb(34, 55, 255)
|
rgb(34, 55, 255)
|
||||||
|
|
||||||
|
block:
|
||||||
|
type
|
||||||
|
R8 = range[0'u8 .. 10'u8]
|
||||||
|
R16 = range[0'u16 .. 10'u16]
|
||||||
|
R32 = range[0'u32 .. 10'u32]
|
||||||
|
|
||||||
|
var
|
||||||
|
x1 = R8(4)
|
||||||
|
x2 = R16(4)
|
||||||
|
x3 = R32(4)
|
||||||
|
|
||||||
|
doAssert $x1 & $x2 & $x3 == "444"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue