diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-08-02 12:47:02 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-08-02 12:47:02 +0200 |
commit | de6198c747afc32a9bd41b70eb9d217054a916f0 (patch) | |
tree | 5da64c63fbd8a00c1bb1be5afe1206c79c075e5f | |
parent | 24b72cebe7b30120eec9a5dce822f65f93881362 (diff) | |
download | Nim-de6198c747afc32a9bd41b70eb9d217054a916f0.tar.gz |
fixes #4555
-rw-r--r-- | compiler/lookups.nim | 21 | ||||
-rw-r--r-- | compiler/pragmas.nim | 4 | ||||
-rw-r--r-- | compiler/semexprs.nim | 2 | ||||
-rw-r--r-- | compiler/semgnrc.nim | 2 | ||||
-rw-r--r-- | compiler/semmagic.nim | 2 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 | ||||
-rw-r--r-- | compiler/semtempl.nim | 2 | ||||
-rw-r--r-- | tests/lookups/test.nim | 17 |
8 files changed, 38 insertions, 14 deletions
diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 9ca864406..df19a6afb 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -99,8 +99,11 @@ proc debugScopes*(c: PContext; limit=0) {.deprecated.} = proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym = for scope in walkScopes(c.currentScope): - result = strTableGet(scope.symbols, s) - if result != nil and result.kind in filter: return + var ti: TIdentIter + var candidate = initIdentIter(ti, scope.symbols, s) + while candidate != nil: + if candidate.kind in filter: return candidate + candidate = nextIdentIter(ti, scope.symbols) result = nil proc errorSym*(c: PContext, n: PNode): PSym = @@ -266,13 +269,17 @@ proc lookUp*(c: PContext, n: PNode): PSym = type TLookupFlag* = enum - checkAmbiguity, checkUndeclared + checkAmbiguity, checkUndeclared, checkModule -proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = +proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym = + const allExceptModule = {low(TSymKind)..high(TSymKind)}-{skModule,skPackage} case n.kind of nkIdent, nkAccQuoted: var ident = considerQuotedIdent(n) - result = searchInScopes(c, ident).skipAlias(n) + if checkModule in flags: + result = searchInScopes(c, ident).skipAlias(n) + else: + result = searchInScopes(c, ident, allExceptModule).skipAlias(n) if result == nil and checkUndeclared in flags: fixSpelling(n, ident, searchInScopes) localError(n.info, errUndeclaredIdentifier, ident.s) @@ -286,7 +293,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = errorUseQualifier(c, n.info, n.sym) of nkDotExpr: result = nil - var m = qualifiedLookUp(c, n.sons[0], flags*{checkUndeclared}) + var m = qualifiedLookUp(c, n.sons[0], (flags*{checkUndeclared})+{checkModule}) if m != nil and m.kind == skModule: var ident: PIdent = nil if n.sons[1].kind == nkIdent: @@ -331,7 +338,7 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = o.mode = oimDone of nkDotExpr: o.mode = oimOtherModule - o.m = qualifiedLookUp(c, n.sons[0]) + o.m = qualifiedLookUp(c, n.sons[0], {checkUndeclared, checkModule}) if o.m != nil and o.m.kind == skModule: var ident: PIdent = nil if n.sons[1].kind == nkIdent: diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 50d5bb1b5..781aab687 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -569,7 +569,7 @@ proc deprecatedStmt(c: PContext; pragma: PNode) = localError(pragma.info, "list of key:value pairs expected"); return for n in pragma: if n.kind in {nkExprColonExpr, nkExprEqExpr}: - let dest = qualifiedLookUp(c, n[1]) + let dest = qualifiedLookUp(c, n[1], {checkUndeclared}) let src = considerQuotedIdent(n[0]) let alias = newSym(skAlias, src, dest, n[0].info) incl(alias.flags, sfExported) @@ -594,7 +594,7 @@ proc pragmaGuard(c: PContext; it: PNode; kind: TSymKind): PSym = # and perform the lookup on demand instead. result = newSym(skUnknown, considerQuotedIdent(n), nil, n.info) else: - result = qualifiedLookUp(c, n) + result = qualifiedLookUp(c, n, {checkUndeclared}) proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, validPragmas: TSpecialWords): bool = diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 2d5e97fa1..70f795d4a 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1107,7 +1107,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = # here at all! #if isSymChoice(n.sons[1]): return - var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) + var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared, checkModule}) if s != nil: if s.kind in OverloadableSyms: result = symChoice(c, n, s, scClosed) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index e4fd715da..9ea3efd0c 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -127,7 +127,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, assert n.kind == nkDotExpr semIdeForTemplateOrGenericCheck(n, ctx.cursorInBody) - let luf = if withinMixin notin flags: {checkUndeclared} else: {} + let luf = if withinMixin notin flags: {checkUndeclared, checkModule} else: {checkModule} var s = qualifiedLookUp(c, n, luf) if s != nil: diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 451745884..d9fec6275 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -133,7 +133,7 @@ proc semBindSym(c: PContext, n: PNode): PNode = return errorNode(c, n) let id = newIdentNode(getIdent(sl.strVal), n.info) - let s = qualifiedLookUp(c, id) + let s = qualifiedLookUp(c, id, {checkUndeclared}) if s != nil: # we need to mark all symbols: var sc = symChoice(c, id, s, TSymChoiceRule(isMixin.intVal)) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index f59acd7be..ab9ecd1a6 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -675,7 +675,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = let name = a.sons[0] var s: PSym if name.kind == nkDotExpr: - s = qualifiedLookUp(c, name) + s = qualifiedLookUp(c, name, {checkUndeclared, checkModule}) if s.kind != skType or s.typ.skipTypes(abstractPtrs).kind != tyObject or tfPartial notin s.typ.skipTypes(abstractPtrs).flags: localError(name.info, "only .partial objects can be extended") else: diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 9341e2929..4d3b6d038 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -80,7 +80,7 @@ proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode = # the same symbol! # This is however not true anymore for hygienic templates as semantic # processing for them changes the symbol table... - let s = qualifiedLookUp(c, a) + let s = qualifiedLookUp(c, a, {checkUndeclared}) if s != nil: # we need to mark all symbols: let sc = symChoice(c, n, s, scClosed) diff --git a/tests/lookups/test.nim b/tests/lookups/test.nim new file mode 100644 index 000000000..a17d235a4 --- /dev/null +++ b/tests/lookups/test.nim @@ -0,0 +1,17 @@ +# This file needs to be called 'test' nim to provoke a clash +# with the unittest.test name. Issue # + +import unittest, macros + +# bug #4555 + +macro memo(n: untyped): typed = + result = n + +proc fastFib(n: int): int {.memo.} = 40 +proc fib(n: int): int = 40 + +suite "memoization": + test "recursive function memoization": + check fastFib(40) == fib(40) + |