Skip to content

Commit 658b28d

Browse files
authored
tyInt tyUint fit target int bit width (nim-lang#20829)
1 parent a70d3ab commit 658b28d

17 files changed

+314
-275
lines changed

compiler/sigmatch.nim

+28-19
Original file line numberDiff line numberDiff line change
@@ -373,14 +373,16 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
373373
else:
374374
result = t # Note: empty is valid here
375375

376-
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
376+
proc handleRange(c: PContext, f, a: PType, min, max: TTypeKind): TTypeRelation =
377377
if a.kind == f.kind:
378378
result = isEqual
379379
else:
380380
let ab = skipTypes(a, {tyRange})
381381
let k = ab.kind
382+
let nf = c.config.normalizeKind(f.kind)
383+
let na = c.config.normalizeKind(k)
382384
if k == f.kind: result = isSubrange
383-
elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64,
385+
elif k == tyInt and f.kind in {tyRange, tyInt..tyInt64,
384386
tyUInt..tyUInt64} and
385387
isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and
386388
getInt(ab.n) <= lastOrd(nil, f):
@@ -389,9 +391,13 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
389391
# integer literal in the proper range; we want ``i16 + 4`` to stay an
390392
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16
391393
result = isFromIntLit
392-
elif f.kind == tyInt and k in {tyInt8..tyInt32}:
394+
elif a.kind == tyInt and nf == c.config.targetSizeSignedToKind:
393395
result = isIntConv
394-
elif f.kind == tyUInt and k in {tyUInt8..tyUInt32}:
396+
elif a.kind == tyUInt and nf == c.config.targetSizeUnsignedToKind:
397+
result = isIntConv
398+
elif f.kind == tyInt and na in {tyInt8 .. c.config.targetSizeSignedToKind}:
399+
result = isIntConv
400+
elif f.kind == tyUInt and na in {tyUInt8 .. c.config.targetSizeUnsignedToKind}:
395401
result = isIntConv
396402
elif k >= min and k <= max:
397403
result = isConvertible
@@ -405,21 +411,22 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
405411
result = isConvertible
406412
else: result = isNone
407413

408-
proc isConvertibleToRange(f, a: PType): bool =
414+
proc isConvertibleToRange(c: PContext, f, a: PType): bool =
409415
if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and
410416
a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}:
411417
case f.kind
412418
of tyInt8: result = isIntLit(a) or a.kind in {tyInt8}
413419
of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
414420
of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
415421
# This is wrong, but seems like there's a lot of code that relies on it :(
416-
of tyInt, tyUInt, tyUInt64: result = true
422+
of tyInt, tyUInt: result = true
423+
# of tyInt: result = isIntLit(a) or a.kind in {tyInt8 .. c.config.targetSizeSignedToKind}
417424
of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
418425
of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
419426
of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
420427
of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
421-
#of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
422-
#of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64}
428+
# of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8 .. c.config.targetSizeUnsignedToKind}
429+
of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt64}
423430
else: result = false
424431
elif f.kind in {tyFloat..tyFloat128}:
425432
# `isIntLit` is correct and should be used above as well, see PR:
@@ -1148,18 +1155,18 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
11481155
let f = skipTypes(f, {tyRange})
11491156
if f.kind == a.kind and (f.kind != tyEnum or sameEnumTypes(f, a)):
11501157
result = isIntConv
1151-
elif isConvertibleToRange(f, a):
1158+
elif isConvertibleToRange(c.c, f, a):
11521159
result = isConvertible # a convertible to f
1153-
of tyInt: result = handleRange(f, a, tyInt8, tyInt32)
1154-
of tyInt8: result = handleRange(f, a, tyInt8, tyInt8)
1155-
of tyInt16: result = handleRange(f, a, tyInt8, tyInt16)
1156-
of tyInt32: result = handleRange(f, a, tyInt8, tyInt32)
1157-
of tyInt64: result = handleRange(f, a, tyInt, tyInt64)
1158-
of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32)
1159-
of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8)
1160-
of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16)
1161-
of tyUInt32: result = handleRange(f, a, tyUInt8, tyUInt32)
1162-
of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64)
1160+
of tyInt: result = handleRange(c.c, f, a, tyInt8, c.c.config.targetSizeSignedToKind)
1161+
of tyInt8: result = handleRange(c.c, f, a, tyInt8, tyInt8)
1162+
of tyInt16: result = handleRange(c.c, f, a, tyInt8, tyInt16)
1163+
of tyInt32: result = handleRange(c.c, f, a, tyInt8, tyInt32)
1164+
of tyInt64: result = handleRange(c.c, f, a, tyInt, tyInt64)
1165+
of tyUInt: result = handleRange(c.c, f, a, tyUInt8, c.c.config.targetSizeUnsignedToKind)
1166+
of tyUInt8: result = handleRange(c.c, f, a, tyUInt8, tyUInt8)
1167+
of tyUInt16: result = handleRange(c.c, f, a, tyUInt8, tyUInt16)
1168+
of tyUInt32: result = handleRange(c.c, f, a, tyUInt8, tyUInt32)
1169+
of tyUInt64: result = handleRange(c.c, f, a, tyUInt, tyUInt64)
11631170
of tyFloat: result = handleFloatRange(f, a)
11641171
of tyFloat32: result = handleFloatRange(f, a)
11651172
of tyFloat64: result = handleFloatRange(f, a)
@@ -2114,6 +2121,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
21142121
of isIntConv:
21152122
# I'm too lazy to introduce another ``*matches`` field, so we conflate
21162123
# ``isIntConv`` and ``isIntLit`` here:
2124+
if f.skipTypes({tyRange}).kind notin {tyInt, tyUInt}:
2125+
inc(m.intConvMatches)
21172126
inc(m.intConvMatches)
21182127
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
21192128
of isSubtype:

compiler/types.nim

+37-3
Original file line numberDiff line numberDiff line change
@@ -753,8 +753,13 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 =
753753
assert(t.n.kind == nkRange)
754754
result = getOrdValue(t.n[0])
755755
of tyInt:
756-
if conf != nil and conf.target.intSize == 4:
757-
result = toInt128(-2147483648)
756+
if conf != nil:
757+
case conf.target.intSize
758+
of 8: result = toInt128(0x8000000000000000'i64)
759+
of 4: result = toInt128(-2147483648)
760+
of 2: result = toInt128(-32768)
761+
of 1: result = toInt128(-128)
762+
else: discard
758763
else:
759764
result = toInt128(0x8000000000000000'i64)
760765
of tyInt8: result = toInt128(-128)
@@ -797,6 +802,29 @@ proc firstFloat*(t: PType): BiggestFloat =
797802
internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')')
798803
NaN
799804

805+
proc targetSizeSignedToKind*(conf: ConfigRef): TTypeKind =
806+
case conf.target.intSize
807+
of 8: result = tyInt64
808+
of 4: result = tyInt32
809+
of 2: result = tyInt16
810+
else: discard
811+
812+
proc targetSizeUnsignedToKind*(conf: ConfigRef): TTypeKind =
813+
case conf.target.intSize
814+
of 8: result = tyUInt64
815+
of 4: result = tyUInt32
816+
of 2: result = tyUInt16
817+
else: discard
818+
819+
proc normalizeKind*(conf: ConfigRef, k: TTypeKind): TTypeKind =
820+
case k
821+
of tyInt:
822+
result = conf.targetSizeSignedToKind()
823+
of tyUInt:
824+
result = conf.targetSizeUnsignedToKind()
825+
else:
826+
result = k
827+
800828
proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
801829
case t.kind
802830
of tyBool: result = toInt128(1'u)
@@ -808,7 +836,13 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
808836
assert(t.n.kind == nkRange)
809837
result = getOrdValue(t.n[1])
810838
of tyInt:
811-
if conf != nil and conf.target.intSize == 4: result = toInt128(0x7FFFFFFF)
839+
if conf != nil:
840+
case conf.target.intSize
841+
of 8: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
842+
of 4: result = toInt128(0x7FFFFFFF)
843+
of 2: result = toInt128(0x00007FFF)
844+
of 1: result = toInt128(0x0000007F)
845+
else: discard
812846
else: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
813847
of tyInt8: result = toInt128(0x0000007F)
814848
of tyInt16: result = toInt128(0x00007FFF)

lib/std/formatfloat.nim

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: BiggestFloat)
2828
##
2929
## returns the amount of bytes written to `buf` not counting the
3030
## terminating '\0' character.
31-
result = toChars(buf, value, forceTrailingDotZero=true)
31+
result = toChars(buf, value, forceTrailingDotZero=true).int
3232
buf[result] = '\0'
3333

3434
proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: float32): int =
35-
result = float32ToChars(buf, value, forceTrailingDotZero=true)
35+
result = float32ToChars(buf, value, forceTrailingDotZero=true).int
3636
buf[result] = '\0'
3737

3838
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
@@ -49,7 +49,7 @@ proc writeFloatToBufferSprintf*(buf: var array[65, char]; value: BiggestFloat):
4949
##
5050
## returns the amount of bytes written to `buf` not counting the
5151
## terminating '\0' character.
52-
var n: int = c_sprintf(cast[cstring](addr buf), "%.16g", value)
52+
var n = c_sprintf(cast[cstring](addr buf), "%.16g", value).int
5353
var hasDot = false
5454
for i in 0..n-1:
5555
if buf[i] == ',':

lib/std/private/digitsutils.nim

+3-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ proc utoa2Digits*(buf: var openArray[char]; pos: int; digits: uint32) {.inline.}
3434
#copyMem(buf, unsafeAddr(digits100[2 * digits]), 2 * sizeof((char)))
3535

3636
proc trailingZeros2Digits*(digits: uint32): int32 {.inline.} =
37-
return trailingZeros100[digits]
37+
return trailingZeros100[digits.int8]
3838

3939
when defined(js):
4040
proc numToString(a: SomeInteger): cstring {.importjs: "((#) + \"\")".}
@@ -63,14 +63,14 @@ func addIntImpl(result: var string, x: uint64) {.inline.} =
6363
while num >= nbatch:
6464
let originNum = num
6565
num = num div nbatch
66-
let index = (originNum - num * nbatch) shl 1
66+
let index = int16((originNum - num * nbatch) shl 1)
6767
tmp[next] = digits100[index + 1]
6868
tmp[next - 1] = digits100[index]
6969
dec(next, 2)
7070

7171
# process last 1-2 digits
7272
if num < 10:
73-
tmp[next] = chr(ord('0') + num)
73+
tmp[next] = chr(ord('0') + num.uint8)
7474
else:
7575
let index = num * 2
7676
tmp[next] = digits100[index + 1]

lib/std/private/dragonbox.nim

+19-19
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ proc printDecimalDigitsBackwards*(buf: var openArray[char]; pos: int; output64:
11461146
buf[pos] = chr(ord('0') + q)
11471147
return tz
11481148

1149-
proc decimalLength*(v: uint64): int32 {.inline.} =
1149+
proc decimalLength*(v: uint64): int {.inline.} =
11501150
dragonbox_Assert(v >= 1)
11511151
dragonbox_Assert(v <= 99999999999999999'u64)
11521152
if cast[uint32](v shr 32) != 0:
@@ -1166,48 +1166,48 @@ proc decimalLength*(v: uint64): int32 {.inline.} =
11661166
return 11
11671167
return 10
11681168
let v32: uint32 = cast[uint32](v)
1169-
if v32 >= 1000000000'u:
1169+
if v32 >= 1000000000'u32:
11701170
return 10
1171-
if v32 >= 100000000'u:
1171+
if v32 >= 100000000'u32:
11721172
return 9
1173-
if v32 >= 10000000'u:
1173+
if v32 >= 10000000'u32:
11741174
return 8
1175-
if v32 >= 1000000'u:
1175+
if v32 >= 1000000'u32:
11761176
return 7
1177-
if v32 >= 100000'u:
1177+
if v32 >= 100000'u32:
11781178
return 6
1179-
if v32 >= 10000'u:
1179+
if v32 >= 10000'u32:
11801180
return 5
1181-
if v32 >= 1000'u:
1181+
if v32 >= 1000'u32:
11821182
return 4
1183-
if v32 >= 100'u:
1183+
if v32 >= 100'u32:
11841184
return 3
1185-
if v32 >= 10'u:
1185+
if v32 >= 10'u32:
11861186
return 2
11871187
return 1
11881188

1189-
proc formatDigits*(buffer: var openArray[char]; pos: int; digits: uint64; decimalExponent: int32;
1189+
proc formatDigits*[T: Ordinal](buffer: var openArray[char]; pos: T; digits: uint64; decimalExponent: int;
11901190
forceTrailingDotZero = false): int {.inline.} =
11911191
const
1192-
minFixedDecimalPoint: int32 = -6
1192+
minFixedDecimalPoint = -6
11931193
const
1194-
maxFixedDecimalPoint: int32 = 17
1195-
var pos = pos
1194+
maxFixedDecimalPoint = 17
1195+
var pos:int = pos.int
11961196
assert(minFixedDecimalPoint <= -1, "internal error")
11971197
assert(maxFixedDecimalPoint >= 17, "internal error")
11981198
dragonbox_Assert(digits >= 1)
11991199
dragonbox_Assert(digits <= 99999999999999999'u64)
12001200
dragonbox_Assert(decimalExponent >= -999)
12011201
dragonbox_Assert(decimalExponent <= 999)
1202-
var numDigits: int32 = decimalLength(digits)
1203-
let decimalPoint: int32 = numDigits + decimalExponent
1202+
var numDigits = decimalLength(digits)
1203+
let decimalPoint = numDigits + decimalExponent
12041204
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
12051205
decimalPoint <= maxFixedDecimalPoint
12061206
## Prepare the buffer.
12071207
for i in 0..<32: buffer[pos+i] = '0'
12081208
assert(minFixedDecimalPoint >= -30, "internal error")
12091209
assert(maxFixedDecimalPoint <= 32, "internal error")
1210-
var decimalDigitsPosition: int32
1210+
var decimalDigitsPosition: int
12111211
if useFixed:
12121212
if decimalPoint <= 0:
12131213
## 0.[000]digits
@@ -1258,7 +1258,7 @@ proc formatDigits*(buffer: var openArray[char]; pos: int; digits: uint64; decima
12581258
## d.igitsE+123
12591259
buffer[pos+1] = '.'
12601260
pos = digitsEnd
1261-
let scientificExponent: int32 = decimalPoint - 1
1261+
let scientificExponent: int = decimalPoint - 1
12621262
## SF_ASSERT(scientific_exponent != 0);
12631263
buffer[pos] = 'e'
12641264
buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
@@ -1291,7 +1291,7 @@ proc toChars*(buffer: var openArray[char]; v: float; forceTrailingDotZero = fals
12911291
if exponent != 0 or significand != 0:
12921292
## != 0
12931293
let dec = toDecimal64(significand, exponent)
1294-
return formatDigits(buffer, pos, dec.significand, dec.exponent,
1294+
return formatDigits(buffer, pos, dec.significand, dec.exponent.int,
12951295
forceTrailingDotZero)
12961296
else:
12971297
buffer[pos] = '0'

lib/std/private/schubfach.nim

+8-8
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ proc toDecimal32(ieeeSignificand: uint32; ieeeExponent: uint32): FloatingDecimal
244244
## ToChars
245245
## ==================================================================================================
246246

247-
proc printDecimalDigitsBackwards(buf: var openArray[char]; pos: int; output: uint32): int32 {.inline.} =
247+
proc printDecimalDigitsBackwards[T: Ordinal](buf: var openArray[char]; pos: T; output: uint32): int32 {.inline.} =
248248
var output = output
249249
var pos = pos
250250
var tz: int32 = 0
@@ -300,7 +300,7 @@ proc printDecimalDigitsBackwards(buf: var openArray[char]; pos: int; output: uin
300300
buf[pos] = chr(uint32('0') + q)
301301
return tz
302302

303-
proc decimalLength(v: uint32): int32 {.inline.} =
303+
proc decimalLength(v: uint32): int {.inline.} =
304304
sf_Assert(v >= 1)
305305
sf_Assert(v <= 999999999'u)
306306
if v >= 100000000'u:
@@ -321,7 +321,7 @@ proc decimalLength(v: uint32): int32 {.inline.} =
321321
return 2
322322
return 1
323323

324-
proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimalExponent: int32;
324+
proc formatDigits[T: Ordinal](buffer: var openArray[char]; pos: T; digits: uint32; decimalExponent: int;
325325
forceTrailingDotZero: bool = false): int {.inline.} =
326326
const
327327
minFixedDecimalPoint: int32 = -4
@@ -333,16 +333,16 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
333333
sf_Assert(digits <= 999999999'u)
334334
sf_Assert(decimalExponent >= -99)
335335
sf_Assert(decimalExponent <= 99)
336-
var numDigits: int32 = decimalLength(digits)
337-
let decimalPoint: int32 = numDigits + decimalExponent
336+
var numDigits = decimalLength(digits)
337+
let decimalPoint = numDigits + decimalExponent
338338
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
339339
decimalPoint <= maxFixedDecimalPoint
340340
## Prepare the buffer.
341341
## Avoid calling memset/memcpy with variable arguments below...
342342
for i in 0..<32: buffer[pos+i] = '0'
343343
assert(minFixedDecimalPoint >= -30, "internal error")
344344
assert(maxFixedDecimalPoint <= 32, "internal error")
345-
var decimalDigitsPosition: int32
345+
var decimalDigitsPosition: int
346346
if useFixed:
347347
if decimalPoint <= 0:
348348
## 0.[000]digits
@@ -386,7 +386,7 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
386386
## d.igitsE+123
387387
buffer[pos+1] = '.'
388388
pos = digitsEnd
389-
let scientificExponent: int32 = decimalPoint - 1
389+
let scientificExponent = decimalPoint - 1
390390
## SF_ASSERT(scientific_exponent != 0);
391391
buffer[pos] = 'e'
392392
buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
@@ -412,7 +412,7 @@ proc float32ToChars*(buffer: var openArray[char]; v: float32; forceTrailingDotZe
412412
if exponent != 0 or significand != 0:
413413
## != 0
414414
let dec: auto = toDecimal32(significand, exponent)
415-
return formatDigits(buffer, pos, dec.digits, dec.exponent, forceTrailingDotZero)
415+
return formatDigits(buffer, pos, dec.digits, dec.exponent.int, forceTrailingDotZero)
416416
else:
417417
buffer[pos] = '0'
418418
buffer[pos+1] = '.'

lib/std/syncio.nim

+3-3
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ proc readAllFile(file: File, len: int64): string =
573573
result = newString(len)
574574
let bytes = readBuffer(file, addr(result[0]), len)
575575
if endOfFile(file):
576-
if bytes < len:
576+
if bytes.int64 < len:
577577
result.setLen(bytes)
578578
else:
579579
# We read all the bytes but did not reach the EOF
@@ -717,7 +717,7 @@ proc open*(f: var File, filename: string,
717717

718718
result = true
719719
f = cast[File](p)
720-
if bufSize > 0 and bufSize <= high(cint).int:
720+
if bufSize > 0 and bufSize.uint <= high(uint):
721721
discard c_setvbuf(f, nil, IOFBF, cast[csize_t](bufSize))
722722
elif bufSize == 0:
723723
discard c_setvbuf(f, nil, IONBF, 0)
@@ -821,7 +821,7 @@ when defined(windows) and appType == "console" and
821821
proc getConsoleCP(): cuint {.stdcall, dynlib: "kernel32",
822822
importc: "GetConsoleCP".}
823823

824-
const Utf8codepage = 65001
824+
const Utf8codepage = 65001'u32
825825

826826
let
827827
consoleOutputCP = getConsoleOutputCP()

0 commit comments

Comments
 (0)