bugfixes for closures

This commit is contained in:
Araq 2012-06-21 08:46:56 +02:00
commit 7b4560337b
7 changed files with 58 additions and 13 deletions

View file

@ -124,8 +124,18 @@ proc GetUniqueType*(key: PType): PType =
result = key
of tyProc:
# tyVar is not 100% correct, but would speeds things up a little:
result = key
if key.callConv != ccClosure:
result = key
else:
# ugh, we need the canon here:
if IdTableHasObjectAsKey(gTypeTable[k], key): return key
for h in countup(0, high(gTypeTable[k].data)):
var t = PType(gTypeTable[k].data[h].key)
if t != nil and sameBackendType(t, key):
return t
IdTablePut(gTypeTable[k], key, key)
result = key
proc TableGetType*(tab: TIdTable, key: PType): PObject =
# returns nil if we need to declare this type
result = IdTableGet(tab, key)

View file

@ -366,14 +366,17 @@ proc searchForInnerProcs(o: POuterContext, n: PNode) =
var it = n.sons[i]
if it.kind == nkCommentStmt: nil
elif it.kind == nkIdentDefs:
var L = sonsLen(it)
if it.sons[0].kind != nkSym: InternalError(it.info, "transformOuter")
#echo "set: ", it.sons[0].sym.name.s, " ", o.currentBlock == nil
IdTablePut(o.localsToEnv, it.sons[0].sym, o.currentEnv)
searchForInnerProcs(o, it.sons[L-1])
elif it.kind == nkVarTuple:
var L = sonsLen(it)
for j in countup(0, L-3):
#echo "set: ", it.sons[j].sym.name.s, " ", o.currentBlock == nil
IdTablePut(o.localsToEnv, it.sons[j].sym, o.currentEnv)
searchForInnerProcs(o, it.sons[L-1])
else:
InternalError(it.info, "transformOuter")
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
@ -493,7 +496,6 @@ proc liftLambdas(fn: PSym, body: PNode): PNode =
searchForInnerProcs(o, body)
let a = transformOuterProc(o, body)
result = ex
#echo renderTree(result)
# XXX should 's' be replaced by a tuple ('s', env)?

View file

@ -596,14 +596,14 @@ proc rawMessage*(msg: TMsgKind, args: openarray[string]) =
writeContext(unknownLineInfo())
frmt = rawErrorFormat
of warnMin..warnMax:
if not (optWarns in gOptions): return
if not (msg in gNotes): return
if optWarns notin gOptions: return
if msg notin gNotes: return
writeContext(unknownLineInfo())
frmt = rawWarningFormat
inc(gWarnCounter)
of hintMin..hintMax:
if not (optHints in gOptions): return
if not (msg in gNotes): return
if optHints notin gOptions: return
if msg notin gNotes: return
frmt = rawHintFormat
inc(gHintCounter)
let s = `%`(frmt, `%`(msgKindToString(msg), args))

View file

@ -135,9 +135,9 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) =
IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64}
if sameType(castDest, src) and castDest.sym == src.sym:
# don't annoy conversions that may be needed on another processor:
if not (castDest.kind in {tyInt..tyUInt64, tyNil}):
if castDest.kind notin {tyInt..tyUInt64, tyNil}:
Message(info, hintConvFromXtoItselfNotNeeded, typeToString(castDest))
return
return
var d = skipTypes(castDest, abstractVar)
var s = skipTypes(src, abstractVar)
while (d != nil) and (d.Kind in {tyPtr, tyRef}) and (d.Kind == s.Kind):
@ -538,9 +538,11 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
result = semOverloadedCall(c, n, nOrig, {skIterator})
elif efInTypeOf in flags:
# for ``type(countup(1,3))``, see ``tests/ttoseq``.
result = semOverloadedCall(c, n, nOrig, {skIterator, skProc, skMethod, skConverter, skMacro, skTemplate})
result = semOverloadedCall(c, n, nOrig,
{skProc, skMethod, skConverter, skMacro, skTemplate, skIterator})
else:
result = semOverloadedCall(c, n, nOrig, {skProc, skMethod, skConverter, skMacro, skTemplate})
result = semOverloadedCall(c, n, nOrig,
{skProc, skMethod, skConverter, skMacro, skTemplate})
if result != nil:
if result.sons[0].kind != nkSym:
InternalError("semDirectCallAnalyseEffects")
@ -838,7 +840,7 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
# if f != nil and f.kind == skStub: loadStub(f)
# ``loadStub`` is not correct here as we don't care for ``f`` really
if f != nil:
# BUGFIX: do not check for (f.kind in [skProc, skMethod, skIterator]) here
# BUGFIX: do not check for (f.kind in {skProc, skMethod, skIterator}) here
# This special node kind is to merge with the call handler in `semExpr`.
result = newNodeI(nkDotCall, n.info)
addSon(result, newIdentNode(i, n.info))

View file

@ -767,7 +767,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
pushProcCon(c, s)
if s.typ.sons[0] != nil and kind != skIterator:
addResult(c, s.typ.sons[0], n.info, kind)
if sfImportc notin s.flags:
if sfImportc notin s.flags:
# no semantic checking for importc:
n.sons[bodyPos] = semStmtScope(c, n.sons[bodyPos])
if s.typ.sons[0] != nil and kind != skIterator: addResultNode(c, n)