Skip to content

when foo: bar puts symbols declared in foo in scope #12030

Open
@timotheecour

Description

@timotheecour

after upgrading to latest nim, #11985 (new gensym handling) caused the following previously working (and IMO valid) code to fail:

Example1

  template boo(): untyped =
    template fun(a: int): int = a*2
    fun(2)

  # when (block: boo()) is type: # this would work
  when boo() is type:
    type T = boo()
  else:
    let a = boo()
  echo a

Current Output1

 Error: ambiguous call; both t0686.fun(a`gensym406407: int) [declared in /Users/timothee/git_clone/nim/timn/tests/nim/all/t0686.nim(89, 14)] and t0686.fun(a`gensym406601: int) [declared in /Users/timothee/git_clone/nim/timn/tests/nim/all/t0686.nim(89, 14)] match for: (int literal(2))

Expected Output1

should compile

Example2

  when (var a = 10; false): echo (a, "ok1")
  else: echo (a, "ok1")

this gives a codegen error:

/t06886.nim.c:155:15: error: use of undeclared identifier 'a__DsmUiYxdIJpEovXpT9c5NcQ'

Example3

  template boo(): untyped =
    var a {.inject.} = 10
    false
  var a = 3.5
  when boo(): discard
  else: echo (a, "ok1")

gives:

Error: redefinition of 'a';

this is especially odd since the else branch is taken; but symbols injected in condition of when condition: foo1 else: foo2 ; rest should IMO affect neither branch foo1 nor foo2 nor rest

Possible Solution

  • when foo: bar should evaluate foo in its own (block) scope, in case foo leaks inject'd declarations
  • likewise with if, elif (same issue)

Additional Information

  • Your Nim version (output of nim -v).
    f2e8c39

links

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions