lookups compiles again

This commit is contained in:
Andreas Rumpf
2018-05-10 15:05:05 +02:00
parent a6e53ec47b
commit e1a921ce4f
3 changed files with 80 additions and 81 deletions

View File

@@ -188,7 +188,7 @@ errYieldNotAllowedInTryStmt: "'yield' cannot be used within 'try' in a non-inlin
errInvalidNumberOfYieldExpr: "invalid number of 'yield' expressions",
errCannotReturnExpr: "current routine cannot return an expression",
errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type",
errAttemptToRedefine: "redefinition of '$1'",
errAttemptToRedefine: ,
errStmtInvalidAfterReturn: "statement not allowed after 'return', 'break', 'raise', 'continue' or proc call with noreturn pragma",
errStmtExpected: "statement expected",
errInvalidLabel: "'$1' is no label",
@@ -283,7 +283,7 @@ errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters",
errXCannotBePassedToProcVar: "'$1' cannot be passed to a procvar",
errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1",
errImplOfXNotAllowed: "implementation of '$1' is not allowed",
errImplOfXexpected: "implementation of '$1' expected",
errImplOfXexpected: ,
errNoSymbolToBorrowFromFound: "no symbol to borrow from found",
errDiscardValueX: "value of type '$1' has to be discarded",
errInvalidDiscard: "statement returns no value that can be discarded",

View File

@@ -11,23 +11,23 @@
import
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
renderer, wordrecg, idgen, nimfix.prettybase
renderer, wordrecg, idgen, nimfix.prettybase, configuration, strutils
proc ensureNoMissingOrUnusedSymbols(scope: PScope)
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)
proc noidentError(n, origin: PNode) =
proc noidentError(conf: ConfigRef; n, origin: PNode) =
var m = ""
if origin != nil:
m.add "in expression '" & origin.renderTree & "': "
m.add "identifier expected, but found '" & n.renderTree & "'"
localError(n.info, m)
localError(conf, n.info, m)
proc considerQuotedIdent*(n: PNode, origin: PNode = nil): PIdent =
proc considerQuotedIdent*(conf: ConfigRef; n: PNode, origin: PNode = nil): PIdent =
## Retrieve a PIdent from a PNode, taking into account accent nodes.
## ``origin`` can be nil. If it is not nil, it is used for a better
## error message.
template handleError(n, origin: PNode) =
noidentError(n, origin)
noidentError(conf, n, origin)
result = getIdent"<Error>"
case n.kind
@@ -36,7 +36,7 @@ proc considerQuotedIdent*(n: PNode, origin: PNode = nil): PIdent =
of nkAccQuoted:
case n.len
of 0: handleError(n, origin)
of 1: result = considerQuotedIdent(n.sons[0], origin)
of 1: result = considerQuotedIdent(conf, n.sons[0], origin)
else:
var id = ""
for i in 0..<n.len:
@@ -71,7 +71,7 @@ proc rawCloseScope*(c: PContext) =
c.currentScope = c.currentScope.parent
proc closeScope*(c: PContext) =
ensureNoMissingOrUnusedSymbols(c.currentScope)
ensureNoMissingOrUnusedSymbols(c, c.currentScope)
rawCloseScope(c)
iterator walkScopes*(scope: PScope): PScope =
@@ -80,7 +80,7 @@ iterator walkScopes*(scope: PScope): PScope =
yield current
current = current.parent
proc skipAlias*(s: PSym; n: PNode): PSym =
proc skipAlias*(s: PSym; n: PNode; conf: ConfigRef): PSym =
if s == nil or s.kind != skAlias:
result = s
else:
@@ -88,7 +88,7 @@ proc skipAlias*(s: PSym; n: PNode): PSym =
if gCmd == cmdPretty:
prettybase.replaceDeprecated(n.info, s, result)
else:
message(n.info, warnDeprecated, "use " & result.name.s & " instead; " &
message(conf, n.info, warnDeprecated, "use " & result.name.s & " instead; " &
s.name.s)
proc localSearchInScope*(c: PContext, s: PIdent): PSym =
@@ -125,7 +125,7 @@ proc errorSym*(c: PContext, n: PNode): PSym =
# ensure that 'considerQuotedIdent' can't fail:
if m.kind == nkDotExpr: m = m.sons[1]
let ident = if m.kind in {nkIdent, nkSym, nkAccQuoted}:
considerQuotedIdent(m)
considerQuotedIdent(c.config, m)
else:
getIdent("err:" & renderTree(m))
result = newSym(skError, ident, getCurrOwner(c), n.info)
@@ -154,7 +154,7 @@ proc getSymRepr*(s: PSym): string =
else:
result = s.name.s
proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) =
# check if all symbols have been used and defined:
var it: TTabIter
var s = initTabIter(it, scope.symbols)
@@ -164,54 +164,53 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
# too many 'implementation of X' errors are annoying
# and slow 'suggest' down:
if missingImpls == 0:
localError(s.info, errImplOfXexpected, getSymRepr(s))
localError(c.config, s.info, "implementation of '$1' expected" % getSymRepr(s))
inc missingImpls
elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options:
# BUGFIX: check options in s!
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 and
s.typ.kind != tyGenericParam:
message(s.info, hintXDeclaredButNotUsed, getSymRepr(s))
message(c.config, s.info, hintXDeclaredButNotUsed, getSymRepr(s))
s = nextIter(it, scope.symbols)
proc wrongRedefinition*(info: TLineInfo, s: string) =
proc wrongRedefinition*(c: PContext; info: TLineInfo, s: string) =
if gCmd != cmdInteractive:
localError(info, errAttemptToRedefine, s)
localError(c.config, info, "redefinition of '$1'" % s)
proc addDecl*(c: PContext, sym: PSym, info: TLineInfo) =
if not c.currentScope.addUniqueSym(sym):
wrongRedefinition(info, sym.name.s)
wrongRedefinition(c, info, sym.name.s)
proc addDecl*(c: PContext, sym: PSym) =
if not c.currentScope.addUniqueSym(sym):
wrongRedefinition(sym.info, sym.name.s)
wrongRedefinition(c, sym.info, sym.name.s)
proc addPrelimDecl*(c: PContext, sym: PSym) =
discard c.currentScope.addUniqueSym(sym)
proc addDeclAt*(scope: PScope, sym: PSym) =
proc addDeclAt*(c: PContext; scope: PScope, sym: PSym) =
if not scope.addUniqueSym(sym):
wrongRedefinition(sym.info, sym.name.s)
wrongRedefinition(c, sym.info, sym.name.s)
proc addInterfaceDeclAux(c: PContext, sym: PSym) =
if sfExported in sym.flags:
# add to interface:
if c.module != nil: strTableAdd(c.module.tab, sym)
else: internalError(sym.info, "addInterfaceDeclAux")
else: internalError(c.config, sym.info, "addInterfaceDeclAux")
proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) =
addDeclAt(scope, sym)
addDeclAt(c, scope, sym)
addInterfaceDeclAux(c, sym)
proc addOverloadableSymAt*(scope: PScope, fn: PSym) =
proc addOverloadableSymAt*(c: PContext; scope: PScope, fn: PSym) =
if fn.kind notin OverloadableSyms:
internalError(fn.info, "addOverloadableSymAt")
internalError(c.config, fn.info, "addOverloadableSymAt")
return
let check = strTableGet(scope.symbols, fn.name)
if check != nil and check.kind notin OverloadableSyms:
wrongRedefinition(fn.info, fn.name.s)
wrongRedefinition(c, fn.info, fn.name.s)
else:
scope.addSym(fn)
@@ -222,12 +221,10 @@ proc addInterfaceDecl*(c: PContext, sym: PSym) =
proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) =
# it adds the symbol to the interface if appropriate
addOverloadableSymAt(scope, sym)
addOverloadableSymAt(c, scope, sym)
addInterfaceDeclAux(c, sym)
when defined(nimfix):
import strutils
# when we cannot find the identifier, retry with a changed identifer:
proc altSpelling(x: PIdent): PIdent =
case x.s[0]
@@ -255,7 +252,7 @@ proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) =
err.add candidate.owner.name.s & "." & candidate.name.s
candidate = nextIdentIter(ti, c.importTable.symbols)
inc i
localError(info, errGenerated, err)
localError(c.config, info, errGenerated, err)
proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) =
var err = "undeclared identifier: '" & name & "'"
@@ -264,13 +261,13 @@ proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) =
err.add c.recursiveDep
# prevent excessive errors for 'nim check'
c.recursiveDep = nil
localError(info, errGenerated, err)
localError(c.config, info, errGenerated, err)
proc lookUp*(c: PContext, n: PNode): PSym =
# Looks up a symbol. Generates an error in case of nil.
case n.kind
of nkIdent:
result = searchInScopes(c, n.ident).skipAlias(n)
result = searchInScopes(c, n.ident).skipAlias(n, c.config)
if result == nil:
fixSpelling(n, n.ident, searchInScopes)
errorUndeclaredIdentifier(c, n.info, n.ident.s)
@@ -278,14 +275,14 @@ proc lookUp*(c: PContext, n: PNode): PSym =
of nkSym:
result = n.sym
of nkAccQuoted:
var ident = considerQuotedIdent(n)
result = searchInScopes(c, ident).skipAlias(n)
var ident = considerQuotedIdent(c.config, n)
result = searchInScopes(c, ident).skipAlias(n, c.config)
if result == nil:
fixSpelling(n, ident, searchInScopes)
errorUndeclaredIdentifier(c, n.info, ident.s)
result = errorSym(c, n)
else:
internalError(n.info, "lookUp")
internalError(c.config, n.info, "lookUp")
return
if contains(c.ambiguousSymbols, result.id):
errorUseQualifier(c, n.info, result)
@@ -299,11 +296,11 @@ 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)
var ident = considerQuotedIdent(c.config, n)
if checkModule in flags:
result = searchInScopes(c, ident).skipAlias(n)
result = searchInScopes(c, ident).skipAlias(n, c.config)
else:
result = searchInScopes(c, ident, allExceptModule).skipAlias(n)
result = searchInScopes(c, ident, allExceptModule).skipAlias(n, c.config)
if result == nil and checkPureEnumFields in flags:
result = strTableGet(c.pureEnumFields, ident)
if result == nil and checkUndeclared in flags:
@@ -325,12 +322,12 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
if n.sons[1].kind == nkIdent:
ident = n.sons[1].ident
elif n.sons[1].kind == nkAccQuoted:
ident = considerQuotedIdent(n.sons[1])
ident = considerQuotedIdent(c.config, n.sons[1])
if ident != nil:
if m == c.module:
result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n)
result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n, c.config)
else:
result = strTableGet(m.tab, ident).skipAlias(n)
result = strTableGet(m.tab, ident).skipAlias(n, c.config)
if result == nil and checkUndeclared in flags:
fixSpelling(n.sons[1], ident, searchInScopes)
errorUndeclaredIdentifier(c, n.sons[1].info, ident.s)
@@ -339,7 +336,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
result = n.sons[1].sym
elif checkUndeclared in flags and
n.sons[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}:
localError(n.sons[1].info, errIdentifierExpected,
localError(c.config, n.sons[1].info, "identifier expected, but got: " &
renderTree(n.sons[1]))
result = errorSym(c, n.sons[1])
else:
@@ -349,11 +346,11 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
case n.kind
of nkIdent, nkAccQuoted:
var ident = considerQuotedIdent(n)
var ident = considerQuotedIdent(c.config, n)
o.scope = c.currentScope
o.mode = oimNoQualifier
while true:
result = initIdentIter(o.it, o.scope.symbols, ident).skipAlias(n)
result = initIdentIter(o.it, o.scope.symbols, ident).skipAlias(n, c.config)
if result != nil:
break
else:
@@ -370,17 +367,17 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
if n.sons[1].kind == nkIdent:
ident = n.sons[1].ident
elif n.sons[1].kind == nkAccQuoted:
ident = considerQuotedIdent(n.sons[1], n)
ident = considerQuotedIdent(c.config, n.sons[1], n)
if ident != nil:
if o.m == c.module:
# a module may access its private members:
result = initIdentIter(o.it, c.topLevelScope.symbols,
ident).skipAlias(n)
ident).skipAlias(n, c.config)
o.mode = oimSelfModule
else:
result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n)
result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n, c.config)
else:
noidentError(n.sons[1], n)
noidentError(c.config, n.sons[1], n)
result = errorSym(c, n.sons[1])
of nkClosedSymChoice, nkOpenSymChoice:
o.mode = oimSymChoice
@@ -408,18 +405,18 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
result = nil
of oimNoQualifier:
if o.scope != nil:
result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n)
result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n, c.config)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = initIdentIter(o.it, o.scope.symbols, o.it.name).skipAlias(n)
result = initIdentIter(o.it, o.scope.symbols, o.it.name).skipAlias(n, c.config)
# BUGFIX: o.it.name <-> n.ident
else:
result = nil
of oimSelfModule:
result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n)
result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n, c.config)
of oimOtherModule:
result = nextIdentIter(o.it, o.m.tab).skipAlias(n)
result = nextIdentIter(o.it, o.m.tab).skipAlias(n, c.config)
of oimSymChoice:
if o.symChoiceIndex < sonsLen(n):
result = n.sons[o.symChoiceIndex].sym
@@ -430,19 +427,19 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
o.mode = oimSymChoiceLocalLookup
o.scope = c.currentScope
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
of oimSymChoiceLocalLookup:
result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n)
result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n, c.config)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
if result != nil and result.kind == skStub: loadStub(result)

View File

@@ -14,7 +14,7 @@ import
wordrecg,
ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math,
magicsys, nversion, nimsets, parser, times, passes, rodread, vmdef,
modulegraphs
modulegraphs, configuration
type
TOptionEntry* = object # entries to put on a stack for pragma parsing
@@ -139,6 +139,8 @@ type
# would otherwise fail.
runnableExamples*: PNode
template config*(c: PContext): ConfigRef = c.graph.config
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
result.genericSym = s
result.inst = inst
@@ -164,7 +166,7 @@ proc pushOwner*(c: PContext; owner: PSym) =
proc popOwner*(c: PContext) =
var length = len(c.graph.owners)
if length > 0: setLen(c.graph.owners, length - 1)
else: internalError("popOwner")
else: internalError(c.config, "popOwner")
proc lastOptionEntry*(c: PContext): POptionEntry =
result = c.optionStack[^1]
@@ -200,19 +202,19 @@ proc considerGenSyms*(c: PContext; n: PNode) =
for i in 0..<n.safeLen:
considerGenSyms(c, n.sons[i])
proc newOptionEntry*(): POptionEntry =
proc newOptionEntry*(conf: ConfigRef): POptionEntry =
new(result)
result.options = gOptions
result.defaultCC = ccDefault
result.dynlib = nil
result.notes = gNotes
result.notes = conf.notes
proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext =
new(result)
result.ambiguousSymbols = initIntSet()
result.optionStack = @[]
result.libs = @[]
result.optionStack.add(newOptionEntry())
result.optionStack.add(newOptionEntry(graph.config))
result.module = module
result.friendModules = @[module]
result.converters = @[]
@@ -255,7 +257,7 @@ proc newTypeS*(kind: TTypeKind, c: PContext): PType =
proc makePtrType*(c: PContext, baseType: PType): PType =
result = newTypeS(tyPtr, c)
addSonSkipIntLit(result, baseType.assertNotNil)
addSonSkipIntLit(result, baseType)
proc makeTypeWithModifier*(c: PContext,
modifier: TTypeKind,
@@ -266,21 +268,21 @@ proc makeTypeWithModifier*(c: PContext,
result = baseType
else:
result = newTypeS(modifier, c)
addSonSkipIntLit(result, baseType.assertNotNil)
addSonSkipIntLit(result, baseType)
proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType =
if baseType.kind == kind:
result = baseType
else:
result = newTypeS(kind, c)
addSonSkipIntLit(result, baseType.assertNotNil)
addSonSkipIntLit(result, baseType)
proc makeTypeDesc*(c: PContext, typ: PType): PType =
if typ.kind == tyTypeDesc:
result = typ
else:
result = newTypeS(tyTypeDesc, c)
result.addSonSkipIntLit(typ.assertNotNil)
result.addSonSkipIntLit(typ)
proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
let typedesc = makeTypeDesc(c, typ)
@@ -339,21 +341,20 @@ proc makeNotType*(c: PContext, t1: PType): PType =
result.flags.incl(t1.flags * {tfHasStatic})
result.flags.incl tfHasMeta
proc nMinusOne*(n: PNode): PNode =
proc nMinusOne(c: PContext; n: PNode): PNode =
result = newNode(nkCall, n.info, @[
newSymNode(getSysMagic("pred", mPred)),
n])
newSymNode(getSysMagic(c.graph, n.info, "pred", mPred)), n])
# Remember to fix the procs below this one when you make changes!
proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType =
let intType = getSysType(tyInt)
let intType = getSysType(c.graph, n.info, tyInt)
result = newTypeS(tyRange, c)
result.sons = @[intType]
if n.typ != nil and n.typ.n == nil:
result.flags.incl tfUnresolved
result.n = newNode(nkRange, n.info, @[
newIntTypeNode(nkIntLit, 0, intType),
makeStaticExpr(c, n.nMinusOne)])
makeStaticExpr(c, nMinusOne(c, n))])
template rangeHasUnresolvedStatic*(t: PType): bool =
tfUnresolved in t.flags
@@ -372,7 +373,8 @@ proc fillTypeS*(dest: PType, kind: TTypeKind, c: PContext) =
dest.size = - 1
proc makeRangeType*(c: PContext; first, last: BiggestInt;
info: TLineInfo; intType = getSysType(tyInt)): PType =
info: TLineInfo; intType: PType = nil): PType =
let intType = if intType != nil: intType else: getSysType(c.graph, info, tyInt)
var n = newNodeI(nkRange, info)
addSon(n, newIntTypeNode(nkIntLit, first, intType))
addSon(n, newIntTypeNode(nkIntLit, last, intType))
@@ -385,17 +387,17 @@ proc markIndirect*(c: PContext, s: PSym) {.inline.} =
incl(s.flags, sfAddrTaken)
# XXX add to 'c' for global analysis
proc illFormedAst*(n: PNode) =
globalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
proc illFormedAst*(n: PNode; conf: ConfigRef) =
globalError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
proc illFormedAstLocal*(n: PNode) =
localError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
proc illFormedAstLocal*(n: PNode; conf: ConfigRef) =
localError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
proc checkSonsLen*(n: PNode, length: int) =
if sonsLen(n) != length: illFormedAst(n)
proc checkSonsLen*(n: PNode, length: int; conf: ConfigRef) =
if sonsLen(n) != length: illFormedAst(n, conf)
proc checkMinSonsLen*(n: PNode, length: int) =
if sonsLen(n) < length: illFormedAst(n)
proc checkMinSonsLen*(n: PNode, length: int; conf: ConfigRef) =
if sonsLen(n) < length: illFormedAst(n, conf)
proc isTopLevel*(c: PContext): bool {.inline.} =
result = c.currentScope.depthLevel <= 2