diff options
author | Jacek Sieka <arnetheduck@gmail.com> | 2016-08-25 22:59:51 +0800 |
---|---|---|
committer | Jacek Sieka <arnetheduck@gmail.com> | 2016-08-25 22:59:51 +0800 |
commit | db2f96daba9c04db2f24cb783c79fb37799cd9ea (patch) | |
tree | 567beb43c7e4549abfcae1ea66e5232d7525e001 /compiler/lookups.nim | |
parent | 3116744c86f37ac4e4e5fec3d6d1635304ed717f (diff) | |
parent | 84a09d2f5b0866491e55fef0fef541e8cc548852 (diff) | |
download | Nim-db2f96daba9c04db2f24cb783c79fb37799cd9ea.tar.gz |
Merge remote-tracking branch 'origin/devel' into initallocator-fix
Diffstat (limited to 'compiler/lookups.nim')
-rw-r--r-- | compiler/lookups.nim | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/compiler/lookups.nim b/compiler/lookups.nim index a337bf0f3..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 = @@ -153,7 +156,8 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) = if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}: # XXX: implicit type params are currently skTypes # maybe they can be made skGenericParam as well. - if s.typ != nil and tfImplicitTypeParam notin s.typ.flags: + if s.typ != nil and tfImplicitTypeParam notin s.typ.flags and + s.typ.kind != tyGenericParam: message(s.info, hintXDeclaredButNotUsed, getSymRepr(s)) s = nextIter(it, scope.symbols) @@ -161,6 +165,10 @@ proc wrongRedefinition*(info: TLineInfo, s: string) = if gCmd != cmdInteractive: localError(info, errAttemptToRedefine, s) +proc addDecl*(c: PContext, sym: PSym, info: TLineInfo) = + if not c.currentScope.addUniqueSym(sym): + wrongRedefinition(info, sym.name.s) + proc addDecl*(c: PContext, sym: PSym) = if not c.currentScope.addUniqueSym(sym): wrongRedefinition(sym.info, sym.name.s) @@ -212,14 +220,27 @@ when defined(nimfix): of 'a'..'z': result = getIdent(toLower(x.s[0]) & x.s.substr(1)) else: result = x - template fixSpelling(n: PNode; ident: PIdent; op: expr) = + template fixSpelling(n: PNode; ident: PIdent; op: untyped) = let alt = ident.altSpelling result = op(c, alt).skipAlias(n) if result != nil: prettybase.replaceDeprecated(n.info, ident, alt) return result else: - template fixSpelling(n: PNode; ident: PIdent; op: expr) = discard + template fixSpelling(n: PNode; ident: PIdent; op: untyped) = discard + +proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) = + var err = "Error: ambiguous identifier: '" & s.name.s & "'" + var ti: TIdentIter + var candidate = initIdentIter(ti, c.importTable.symbols, s.name) + var i = 0 + while candidate != nil: + if i == 0: err.add " --use " + else: err.add " or " + err.add candidate.owner.name.s & "." & candidate.name.s + candidate = nextIdentIter(ti, c.importTable.symbols) + inc i + localError(info, errGenerated, err) proc lookUp*(c: PContext, n: PNode): PSym = # Looks up a symbol. Generates an error in case of nil. @@ -243,32 +264,36 @@ proc lookUp*(c: PContext, n: PNode): PSym = internalError(n.info, "lookUp") return if contains(c.ambiguousSymbols, result.id): - localError(n.info, errUseQualifier, result.name.s) + errorUseQualifier(c, n.info, result) if result.kind == skStub: loadStub(result) 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) result = errorSym(c, n) elif checkAmbiguity in flags and result != nil and contains(c.ambiguousSymbols, result.id): - localError(n.info, errUseQualifier, ident.s) + errorUseQualifier(c, n.info, result) of nkSym: result = n.sym if checkAmbiguity in flags and contains(c.ambiguousSymbols, result.id): - localError(n.info, errUseQualifier, n.sym.name.s) + 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: @@ -313,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: |