From 35f8cc0bdde8e923eaca8830676f1b2ad6ffe300 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 9 Aug 2015 20:18:49 +0200 Subject: [PATCH] fixes #2752 --- compiler/seminst.nim | 7 +++--- tests/generics/tdont_use_inner_scope.nim | 27 ++++++++++++++++++++++++ todo.txt | 4 ---- 3 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 tests/generics/tdont_use_inner_scope.nim diff --git a/compiler/seminst.nim b/compiler/seminst.nim index b2aef63a80..df5865b6be 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 0000000000..45b11fc228 --- /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 2955f29176..d7e1f3504d 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