@@ -373,14 +373,16 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
373
373
else :
374
374
result = t # Note: empty is valid here
375
375
376
- proc handleRange (f, a: PType , min, max: TTypeKind ): TTypeRelation =
376
+ proc handleRange (c: PContext , f, a: PType , min, max: TTypeKind ): TTypeRelation =
377
377
if a.kind == f.kind:
378
378
result = isEqual
379
379
else :
380
380
let ab = skipTypes (a, {tyRange})
381
381
let k = ab.kind
382
+ let nf = c.config.normalizeKind (f.kind)
383
+ let na = c.config.normalizeKind (k)
382
384
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,
384
386
tyUInt.. tyUInt64} and
385
387
isIntLit (ab) and getInt (ab.n) >= firstOrd (nil , f) and
386
388
getInt (ab.n) <= lastOrd (nil , f):
@@ -389,9 +391,13 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
389
391
# integer literal in the proper range; we want ``i16 + 4`` to stay an
390
392
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16
391
393
result = isFromIntLit
392
- elif f .kind == tyInt and k in {tyInt8 .. tyInt32} :
394
+ elif a .kind == tyInt and nf == c.config.targetSizeSignedToKind :
393
395
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}:
395
401
result = isIntConv
396
402
elif k >= min and k <= max:
397
403
result = isConvertible
@@ -405,21 +411,22 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
405
411
result = isConvertible
406
412
else : result = isNone
407
413
408
- proc isConvertibleToRange (f, a: PType ): bool =
414
+ proc isConvertibleToRange (c: PContext , f, a: PType ): bool =
409
415
if f.kind in {tyInt.. tyInt64, tyUInt.. tyUInt64} and
410
416
a.kind in {tyInt.. tyInt64, tyUInt.. tyUInt64}:
411
417
case f.kind
412
418
of tyInt8: result = isIntLit (a) or a.kind in {tyInt8}
413
419
of tyInt16: result = isIntLit (a) or a.kind in {tyInt8, tyInt16}
414
420
of tyInt32: result = isIntLit (a) or a.kind in {tyInt8, tyInt16, tyInt32}
415
421
# 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}
417
424
of tyInt64: result = isIntLit (a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
418
425
of tyUInt8: result = isIntLit (a) or a.kind in {tyUInt8}
419
426
of tyUInt16: result = isIntLit (a) or a.kind in {tyUInt8, tyUInt16}
420
427
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}
423
430
else : result = false
424
431
elif f.kind in {tyFloat.. tyFloat128}:
425
432
# `isIntLit` is correct and should be used above as well, see PR:
@@ -1148,18 +1155,18 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
1148
1155
let f = skipTypes (f, {tyRange})
1149
1156
if f.kind == a.kind and (f.kind != tyEnum or sameEnumTypes (f, a)):
1150
1157
result = isIntConv
1151
- elif isConvertibleToRange (f, a):
1158
+ elif isConvertibleToRange (c.c, f, a):
1152
1159
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)
1163
1170
of tyFloat: result = handleFloatRange (f, a)
1164
1171
of tyFloat32: result = handleFloatRange (f, a)
1165
1172
of tyFloat64: result = handleFloatRange (f, a)
@@ -2114,6 +2121,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
2114
2121
of isIntConv:
2115
2122
# I'm too lazy to introduce another ``*matches`` field, so we conflate
2116
2123
# ``isIntConv`` and ``isIntLit`` here:
2124
+ if f.skipTypes ({tyRange}).kind notin {tyInt, tyUInt}:
2125
+ inc (m.intConvMatches)
2117
2126
inc (m.intConvMatches)
2118
2127
result = implicitConv (nkHiddenStdConv, f, arg, m, c)
2119
2128
of isSubtype:
0 commit comments