Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stop gensym identifiers hijacking routine decl names in templates #23392

Merged
merged 4 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion compiler/lookups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,11 @@ proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string, extr
if name == "_":
err = "the special identifier '_' is ignored in declarations and cannot be used"
else:
err = "undeclared identifier: '" & name & "'" & extra
err = "undeclared identifier: '" & name & "'"
if "`gensym" in name:
err.add "; if declared in a template, this identifier may be inconsistently marked inject or gensym"
if extra.len != 0:
err.add extra
if c.recursiveDep.len > 0:
err.add "\nThis might be caused by a recursive module dependency:\n"
err.add c.recursiveDep
Expand Down
2 changes: 1 addition & 1 deletion compiler/semtempl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode =
if n.kind == nkIdent:
let s = qualifiedLookUp(c.c, n, {})
if s != nil:
if s.owner == c.owner and (s.kind == skParam or sfGenSym in s.flags):
if s.owner == c.owner and s.kind == skParam:
incl(s.flags, sfUsed)
result = newSymNode(s, n.info)
onUse(n.info, s)
Expand Down
6 changes: 3 additions & 3 deletions testament/important_packages.nim
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pkg "compactdict"
pkg "comprehension", "nimble test", "https://github.com/alehander92/comprehension"
pkg "cowstrings"
pkg "criterion", allowFailure = true # needs testing binary
pkg "datamancer"
pkg "datamancer", "nimble install -y arraymancer@#HEAD; nimble test"
pkg "dashing", "nim c tests/functional.nim"
pkg "delaunay"
pkg "docopt"
Expand All @@ -72,7 +72,7 @@ pkg "fragments", "nim c -r fragments/dsl.nim", allowFailure = true # pending htt
pkg "fusion"
pkg "gara"
pkg "glob"
pkg "ggplotnim", "nim c -d:noCairo -r tests/tests.nim"
pkg "ggplotnim", "nimble install -y arraymancer@#HEAD; nim c -d:noCairo -r tests/tests.nim"
pkg "gittyup", "nimble test", "https://github.com/disruptek/gittyup", allowFailure = true
pkg "gnuplot", "nim c gnuplot.nim"
# pkg "gram", "nim c -r --mm:arc --define:danger tests/test.nim", "https://github.com/disruptek/gram"
Expand Down Expand Up @@ -125,7 +125,7 @@ pkg "nimx", "nim c test/main.nim", allowFailure = true
pkg "nitter", "nim c src/nitter.nim", "https://github.com/zedeus/nitter"
pkg "norm", "testament r tests/common/tmodel.nim"
pkg "npeg", "nimble testarc"
pkg "numericalnim", "nimble nimCI"
pkg "numericalnim", "nimble install -y arraymancer@#HEAD; nimble nimCI"
pkg "optionsutils"
pkg "ormin", "nim c -o:orminn ormin.nim"
pkg "parsetoml"
Expand Down
25 changes: 25 additions & 0 deletions tests/errmsgs/tinconsistentgensym.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
discard """
cmd: "nim check --hints:off $file"
"""

block:
template foo =
when false:
let x = 123
else:
template x: untyped = 456
echo x #[tt.Error
^ undeclared identifier: 'x`gensym0'; if declared in a template, this identifier may be inconsistently marked inject or gensym]#
foo()

block:
template foo(y: static bool) =
block:
when y:
let x {.gensym.} = 123
else:
let x {.inject.} = 456
echo x #[tt.Error
^ undeclared identifier: 'x']#
foo(false)
foo(true)
37 changes: 37 additions & 0 deletions tests/template/tgensymhijack.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# issue #23326

type Result*[E] = object
e*: E

proc error*[E](v: Result[E]): E = discard

template valueOr*[E](self: Result[E], def: untyped): int =
when E isnot void:
when false:
# Comment line below to make it work
template error(): E {.used, gensym.} = s.e
discard
else:
template error(): E {.used, inject.} =
self.e

def
else:
def


block:
let rErr = Result[string](e: "a")
let rErrV = rErr.valueOr:
ord(error[0])

block:
template foo(x: static bool): untyped =
when x:
let a = 123
else:
template a: untyped {.gensym.} = 456
a

doAssert foo(false) == 456
doAssert foo(true) == 123
Loading