fixes #26062; ResultUsed warning behaves inconsistently with manual c… (#26087)

…haracterization with--warning:ResultUsed:on

fixes #26062

> A return statement with no expression is shorthand for return result.

> ResultUsed: Warn about the usage of the built-in result variable.

> A procedure that does not have any return statement and does not use
the special result variable returns the value of its last expression.

(cherry picked from commit 0ec8682abe)
This commit is contained in:
ringabout
2026-08-10 13:38:49 +08:00
committed by narimiran
parent 445d46dd9e
commit 4ce3d87c7e
2 changed files with 49 additions and 1 deletions

View File

@@ -1409,7 +1409,11 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
# not sure the symbol really ends up being used:
# var len = 0 # but won't be called
# genericThatUsesLen(x) # marked as taking a closure?
if hasWarn(c.config, warnResultUsed):
# Lowered returns use resolved symbol nodes internally; warn only for
# source-level references to the implicit result variable.
if s.kind == skResult and
(n.kind != nkSym or nfFromTemplate in n.flags) and
hasWarn(c.config, warnResultUsed):
message(c.config, n.info, warnResultUsed)
of skGenericParam:
@@ -2089,6 +2093,8 @@ proc semReturn(c: PContext, n: PNode): PNode =
# optimize away ``result = result``:
if result[0][1].kind == nkSym and result[0][1].sym == c.p.resultSym:
result[0] = c.graph.emptyNode
elif c.p.resultSym != nil and hasWarn(c.config, warnResultUsed):
message(c.config, n.info, warnResultUsed)
else:
localError(c.config, n.info, "'return' not allowed here")

View File

@@ -0,0 +1,42 @@
discard """
action: compile
cmd: "nim check --hints:off --warning:ResultUsed:on $file"
nimout: '''
tresultused.nim(34, 3) Warning: used 'result' variable [ResultUsed]
tresultused.nim(37, 3) Warning: used 'result' variable [ResultUsed]
'''
"""
let value = 0
discard value
for item in 0 .. 0:
discard item
proc usesLocal() =
var local = 0
discard local
block:
let result = 0
discard result
proc voidReturn() =
return
proc implicitReturn(): int =
0
proc explicitReturn(): int =
return 0
proc usesResult(): int =
result = 0
proc usesBareReturn(): int =
return
doAssert implicitReturn() == 0
doAssert explicitReturn() == 0
doAssert usesResult() == 0
doAssert usesBareReturn() == 0