summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-08-09 20:18:49 +0200
committerAraq <rumpf_a@web.de>2015-08-09 20:29:03 +0200
commit35f8cc0bdde8e923eaca8830676f1b2ad6ffe300 (patch)
treec2e8517a7530a71dd1c6ed9dc9e9bc506172782f
parentf8bababa2af97bfa85c627fb8c394a619c015b47 (diff)
downloadNim-35f8cc0bdde8e923eaca8830676f1b2ad6ffe300.tar.gz
fixes #2752
-rw-r--r--compiler/seminst.nim7
-rw-r--r--tests/generics/tdont_use_inner_scope.nim27
-rw-r--r--todo.txt4
3 files changed, 31 insertions, 7 deletions
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index b2aef63a8..df5865b6b 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -226,13 +226,14 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
   # NOTE: for access of private fields within generics from a different module
   # we set the friend module:
   c.friendModules.add(getModule(fn))
-  #let oldScope = c.currentScope
-  #c.currentScope = fn.scope
+  let oldScope = c.currentScope
+  while not isTopLevel(c): c.currentScope = c.currentScope.parent
   result = copySym(fn, false)
   incl(result.flags, sfFromGeneric)
   result.owner = fn
   result.ast = n
   pushOwner(result)
+
   openScope(c)
   internalAssert n.sons[genericParamsPos].kind != nkEmpty
   n.sons[namePos] = newSymNode(result)
@@ -264,7 +265,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
   popInfoContext()
   closeScope(c)           # close scope for parameters
   popOwner()
-  #c.currentScope = oldScope
+  c.currentScope = oldScope
   discard c.friendModules.pop()
   dec(c.instCounter)
   if result.kind == skMethod: finishMethod(c, result)
diff --git a/tests/generics/tdont_use_inner_scope.nim b/tests/generics/tdont_use_inner_scope.nim
new file mode 100644
index 000000000..45b11fc22
--- /dev/null
+++ b/tests/generics/tdont_use_inner_scope.nim
@@ -0,0 +1,27 @@
+
+# bug #2752
+
+import future, sequtils
+
+proc myFilter[T](it: (iterator(): T), f: (proc(anything: T):bool)): (iterator(): T) =
+  iterator aNameWhichWillConflict(): T {.closure.}=
+    for x in it():
+      if f(x):
+        yield x
+  result = aNameWhichWillConflict
+
+
+iterator testIt():int {.closure.}=
+  yield -1
+  yield 2
+
+#let unusedVariable = myFilter(testIt, (x: int) => x > 0)
+
+proc onlyPos(it: (iterator(): int)): (iterator(): int)=
+  iterator aNameWhichWillConflict(): int {.closure.}=
+    var filtered = onlyPos(myFilter(it, (x:int) => x > 0))
+    for x in filtered():
+      yield x
+  result = aNameWhichWillConflict
+
+let x = onlyPos(testIt)
diff --git a/todo.txt b/todo.txt
index 2955f2917..d7e1f3504 100644
--- a/todo.txt
+++ b/todo.txt
@@ -61,10 +61,8 @@ Bugs
 
 - VM: Pegs do not work at compile-time
 - VM: ptr/ref T cannot work in general
-- scopes are still broken for generic instantiation!
 - blocks can "export" an identifier but the CCG generates {} for them ...
 - ConcreteTypes in a 'case' means we don't check for duplicated case branches
-- typedesc matches a generic type T!
 
 
 version 0.9.x
@@ -79,8 +77,6 @@ version 0.9.x
 - implement 'bits' pragmas
 - we need a magic thisModule symbol
 - optimize 'genericReset'; 'newException' leads to code bloat
-- The 'do' notation might be trimmed so that its only purpose is to pass
-  multiple multi line constructs to a macro.
 
 
 version 0.9.X