fixes #25608; ImplicitRangeConversion now skips compile-time constants

The warning gate previously only exempted literal AST nodes
(nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit). Enum constants,
named consts, and constant expressions passed through and triggered a
spurious ImplicitRangeConversion warning even though the compiler already
knows their value and can validate range membership exactly.

Replace the literal-kind check with a call to getConstExpr: if the
source node folds to a compile-time constant the warning is suppressed.
Non-constant values (variables, parameters, runtime expressions) are
unaffected and still warn as before.

Add tests/range/timplicitrangeconsts.nim to guard the fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
ringabout
2026-05-26 22:43:30 +08:00
parent 73986c03a1
commit 286b7eb6f6
2 changed files with 33 additions and 2 deletions

View File

@@ -1559,9 +1559,10 @@ proc track(tracked: PEffects, n: PNode) =
message(tracked.config, n.info, warnPtrToCstringConv,
$n[1].typ)
# Check for implicit range conversions
# Check for implicit range conversions. Compile-time constants are already
# fully known here, so only non-constant values need the downsizing warning.
if n.kind == nkHiddenStdConv and (not tracked.isArrayIndexing) and
n[1].kind notin {nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit} and
getConstExpr(tracked.ownerModule, n[1], tracked.c.idgen, tracked.graph) == nil and
shouldWarnRangeConversion(tracked.config, n.info, n.typ, n[1].typ):
message(tracked.config, n.info, warnImplicitRangeConversion,
typeToString(n[1].typ) & " -> " & typeToString(n.typ))

View File

@@ -0,0 +1,30 @@
discard """
cmd: "nim check $options --hints:off --warning:ImplicitRangeConversion --warningaserror:ImplicitRangeConversion $file"
action: "compile"
"""
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)