mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-02 21:49:02 +00:00
fix #25608
This pull request improves how the compiler handles warnings for
implicit range conversions, ensuring that only non-constant values
trigger downsizing warnings. It also adds new test cases to verify that
assignments and function calls involving compile-time constants do not
produce unnecessary warnings.
Improvements to range conversion warnings:
* Updated the logic in `compiler/sempass2.nim` to skip implicit range
conversion warnings for compile-time constants by checking if an
expression is constant with `getConstExpr`. Now, only non-constant
values will trigger the warning.
Testing enhancements:
* Added new test cases in `tests/range/timplicitrangedownsizing.nim` to
confirm that assignments and function calls with constant enum and
integer values do not trigger downsizing warnings.
(cherry picked from commit c70a4502d2)
106 lines
3.1 KiB
Nim
106 lines
3.1 KiB
Nim
discard """
|
|
cmd: "nim check $options --hints:off --warning:ImplicitRangeConversion --warningaserror:ImplicitRangeConversion $file"
|
|
action: "reject"
|
|
nimout: '''
|
|
timplicitrangedownsizing.nim(22, 5) Error: implicit range conversion int -> FakeUint8 [ImplicitRangeConversion]
|
|
timplicitrangedownsizing.nim(24, 5) Error: implicit range conversion OffByOneRange -> FakeUint8 [ImplicitRangeConversion]
|
|
timplicitrangedownsizing.nim(28, 5) Error: implicit range conversion int -> FakeUint8 [ImplicitRangeConversion]
|
|
timplicitrangedownsizing.nim(55, 6) Error: implicit range conversion float64 -> SmallFloat [ImplicitRangeConversion]
|
|
timplicitrangedownsizing.nim(59, 6) Error: implicit range conversion FloatRange -> SmallFloat [ImplicitRangeConversion]
|
|
timplicitrangedownsizing.nim(63, 6) Error: implicit range conversion float64 -> SmallFloat [ImplicitRangeConversion]
|
|
'''
|
|
"""
|
|
# Integer range tests
|
|
type FakeUint8 = range[0..255]
|
|
type OffByOneRange = range[1..256]
|
|
type WideRange = range[0..65535]
|
|
|
|
var v: FakeUint8
|
|
var x = 256
|
|
var y = OffByOneRange(256)
|
|
|
|
v = x # panics, should trigger warning
|
|
v = FakeUint8(x) # panics, should not trigger warning
|
|
v = y # panics should trigger warning
|
|
|
|
proc xxx(v: FakeUint8)= discard
|
|
|
|
xxx(x) # panics, should trigger warning
|
|
xxx(FakeUint8(x)) # panics, should not trigger warning
|
|
|
|
# Test narrower to wider range conversions (should NOT warn)
|
|
proc acceptWide(v: WideRange) = discard
|
|
|
|
var smallRange: FakeUint8 = FakeUint8(100)
|
|
acceptWide(smallRange) # OK - FakeUint8 (0..255) fits in WideRange (0..65535)
|
|
|
|
var medRange: OffByOneRange = OffByOneRange(150)
|
|
acceptWide(medRange) # OK - OffByOneRange (1..256) fits in WideRange (0..65535)
|
|
|
|
var w: WideRange
|
|
w = smallRange # OK - FakeUint8 range fits in WideRange
|
|
w = medRange # OK - OffByOneRange range fits in WideRange
|
|
|
|
# Test narrower range passed to function (should NOT warn)
|
|
xxx(smallRange) # OK - FakeUint8 value fits in range[0..255]
|
|
|
|
# Float range tests
|
|
type SmallFloat = range[0.0..10.0]
|
|
type FloatRange = range[5.0..15.0]
|
|
type WideFloatRange = range[0.0..100.0]
|
|
|
|
var fv: SmallFloat
|
|
var fx = 11.5 # Out of range
|
|
|
|
fv = fx # panics, should trigger warning
|
|
fv = SmallFloat(fx) # panics, should not trigger warning
|
|
|
|
var fy = FloatRange(7.5)
|
|
fv = fy # panics, should trigger warning (5.0..15.0 → 0.0..10.0)
|
|
|
|
proc fffx(v: SmallFloat) = discard
|
|
|
|
fffx(fx) # panics, should trigger warning
|
|
fffx(SmallFloat(fx)) # panics, should not trigger warning
|
|
|
|
# Test narrower to wider float range conversions (should NOT warn)
|
|
proc acceptWideFloat(v: WideFloatRange) = discard
|
|
|
|
var smallFloatRange: SmallFloat = SmallFloat(5.0)
|
|
acceptWideFloat(smallFloatRange) # OK - SmallFloat (0.0..10.0) fits in WideFloatRange (0.0..100.0)
|
|
|
|
var wf: WideFloatRange
|
|
wf = smallFloatRange # OK - SmallFloat range fits in WideFloatRange
|
|
|
|
proc foo(x: Natural) =
|
|
discard
|
|
|
|
foo(12)
|
|
|
|
block:
|
|
type
|
|
E = enum
|
|
ea, eb
|
|
|
|
R = range[eb..eb]
|
|
I = range[0..3]
|
|
|
|
proc accept(r: R) = discard
|
|
proc accept(i: I) = discard
|
|
|
|
var r: R
|
|
var i: I
|
|
const enumOk = eb
|
|
const enumAlias = enumOk
|
|
const intOk = 1 + 2
|
|
|
|
r = eb
|
|
r = enumOk
|
|
r = enumAlias
|
|
accept(eb)
|
|
accept(enumOk)
|
|
accept(enumAlias)
|
|
|
|
i = intOk
|
|
accept(intOk)
|