diff options
-rw-r--r-- | compiler/ccgexprs.nim | 4 | ||||
-rw-r--r-- | compiler/lowerings.nim | 2 | ||||
-rw-r--r-- | compiler/modules.nim | 2 | ||||
-rw-r--r-- | compiler/semmagic.nim | 8 | ||||
-rw-r--r-- | compiler/sempass2.nim | 2 | ||||
-rw-r--r-- | compiler/semstmts.nim | 3 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 12 | ||||
-rw-r--r-- | compiler/types.nim | 10 | ||||
-rw-r--r-- | lib/pure/os.nim | 4 | ||||
-rw-r--r-- | tests/ccgbugs/tcapture_static.nim | 13 | ||||
-rw-r--r-- | tests/generics/ttable_alias.nim | 7 |
11 files changed, 51 insertions, 16 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index f4068b2a2..f9fa1a0f6 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1980,6 +1980,10 @@ proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) = fillLoc(d, locData, t, tmp, OnStatic) else: putDataIntoDest(p, d, t, tmp) + # This fixes bug #4551, but we really need better dataflow + # analysis to make this 100% safe. + if t.kind notin {tySequence, tyString}: + d.s = OnStatic proc expr(p: BProc, n: PNode, d: var TLoc) = case n.kind diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index cdea2a4ff..36eb24653 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -578,6 +578,8 @@ proc wrapProcForSpawn*(owner: PSym; spawnExpr: PNode; retType: PType; var fn = n.sons[0] # templates and macros are in fact valid here due to the nature of # the transformation: + if fn.kind == nkClosure: + localError(n.info, "closure in spawn environment is not allowed") if not (fn.kind == nkSym and fn.sym.kind in {skProc, skTemplate, skMacro, skMethod, skConverter}): # for indirect calls we pass the function pointer in the scratchObj diff --git a/compiler/modules.nim b/compiler/modules.nim index 1b4746484..9120bd1b6 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -49,7 +49,7 @@ proc hashChanged(fileIdx: int32): bool = else: hashNotChanged # echo "TESTING Hash: ", fileIdx.toFilename, " ", result - case gMemCacheData[fileIdx].hashStatus: + case gMemCacheData[fileIdx].hashStatus of hashHasChanged: result = true of hashNotChanged: diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index d9fec6275..cbe9bc176 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -114,8 +114,12 @@ proc semTypeTraits(c: PContext, n: PNode): PNode = proc semOrd(c: PContext, n: PNode): PNode = result = n - result.typ = makeRangeType(c, firstOrd(n.sons[1].typ), - lastOrd(n.sons[1].typ), n.info) + let parType = n.sons[1].typ + if isOrdinalType(parType) or parType.kind == tySet: + result.typ = makeRangeType(c, firstOrd(parType), lastOrd(parType), n.info) + else: + localError(n.info, errOrdinalTypeExpected) + result.typ = errorType(c) proc semBindSym(c: PContext, n: PNode): PNode = result = copyNode(n) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 120c4c774..b12ab5e96 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -532,7 +532,7 @@ proc isOwnedProcVar(n: PNode; owner: PSym): bool = proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) = let a = skipConvAndClosure(n) let op = a.typ - if op != nil and op.kind == tyProc and n.kind != nkNilLit: + if op != nil and op.kind == tyProc and n.skipConv.kind != nkNilLit: internalAssert op.n.sons[0].kind == nkEffectList var effectList = op.n.sons[0] let s = n.skipConv diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index ab9ecd1a6..5d1770a32 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1309,6 +1309,7 @@ proc determineType(c: PContext, s: PSym) = proc semIterator(c: PContext, n: PNode): PNode = # gensym'ed iterator? + let isAnon = n[namePos].kind == nkEmpty if n[namePos].kind == nkSym: # gensym'ed iterators might need to become closure iterators: n[namePos].sym.owner = getCurrOwner() @@ -1318,6 +1319,8 @@ proc semIterator(c: PContext, n: PNode): PNode = var t = s.typ if t.sons[0] == nil and s.typ.callConv != ccClosure: localError(n.info, errXNeedsReturnType, "iterator") + if isAnon and s.typ.callConv == ccInline: + localError(n.info, "inline iterators are not first-class / cannot be assigned to variables") # iterators are either 'inline' or 'closure'; for backwards compatibility, # we require first class iterators to be marked with 'closure' explicitly # -- at least for 0.9.2. diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 3918bb74b..ce4f893ea 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -985,11 +985,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyGenericBody: considerPreviousT: - let ff = lastSon(f) - var depth = 0 - if a.kind == tyGenericInst and (a.sons[0] == f): #or (ff != nil and ff.kind == tyObject and isGenericSubtype(a.sons[0], ff, depth))): - c.inheritancePenalty += depth + if a.kind == tyGenericInst and a.sons[0] == f: bindingRet isGeneric + let ff = lastSon(f) if ff != nil: result = typeRel(c, ff, a) @@ -1006,7 +1004,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = for i in countup(1, sonsLen(f) - 1): if x.sons[i].kind == tyGenericParam: internalError("wrong instantiated type!") - elif typeRel(c, f.sons[i], x.sons[i]) <= isSubtype: return + elif typeRel(c, f.sons[i], x.sons[i]) <= isSubtype: + # Workaround for regression #4589 + if f.sons[i].kind != tyTypeDesc: return c.inheritancePenalty += depth result = isGeneric else: @@ -1024,7 +1024,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = # # we steal the generic parameters from the tyGenericBody: for i in countup(1, sonsLen(f) - 1): - var x = PType(idTableGet(c.bindings, genericBody.sons[i-1])) + let x = PType(idTableGet(c.bindings, genericBody.sons[i-1])) if x == nil: discard "maybe fine (for eg. a==tyNil)" elif x.kind in {tyGenericInvocation, tyGenericParam}: diff --git a/compiler/types.nim b/compiler/types.nim index c56382b89..ff60730f0 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -148,10 +148,12 @@ proc skipGeneric(t: PType): PType = proc isOrdinalType(t: PType): bool = assert(t != nil) - # caution: uint, uint64 are no ordinal types! - result = t.kind in {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum} or - (t.kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and - isOrdinalType(t.sons[0]) + const + # caution: uint, uint64 are no ordinal types! + baseKinds = {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum} + parentKinds = {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst, + tyDistinct} + t.kind in baseKinds or (t.kind in parentKinds and isOrdinalType(t.sons[0])) proc enumHasHoles(t: PType): bool = var b = t diff --git a/lib/pure/os.nim b/lib/pure/os.nim index e6ecb184e..1e474f4d4 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1507,8 +1507,8 @@ template rawToFormalFileInfo(rawInfo, formalInfo): untyped = ## 'rawInfo' is either a 'TBY_HANDLE_FILE_INFORMATION' structure on Windows, ## or a 'Stat' structure on posix when defined(Windows): - template toTime(e: FILETIME): expr {.gensym.} = winTimeToUnixTime(rdFileTime(e)) # local templates default to bind semantics - template merge(a, b): expr = a or (b shl 32) + template toTime(e: FILETIME): untyped {.gensym.} = winTimeToUnixTime(rdFileTime(e)) # local templates default to bind semantics + template merge(a, b): untyped = a or (b shl 32) formalInfo.id.device = rawInfo.dwVolumeSerialNumber formalInfo.id.file = merge(rawInfo.nFileIndexLow, rawInfo.nFileIndexHigh) formalInfo.size = merge(rawInfo.nFileSizeLow, rawInfo.nFileSizeHigh) diff --git a/tests/ccgbugs/tcapture_static.nim b/tests/ccgbugs/tcapture_static.nim new file mode 100644 index 000000000..2afb8de47 --- /dev/null +++ b/tests/ccgbugs/tcapture_static.nim @@ -0,0 +1,13 @@ +discard """ + output: '''hi''' +""" + +# bug #4551 + +proc foo() = + let arr = ["hi"] + for i, v in arr: + let bar = proc = + echo v + bar() +foo() diff --git a/tests/generics/ttable_alias.nim b/tests/generics/ttable_alias.nim new file mode 100644 index 000000000..992ca85e0 --- /dev/null +++ b/tests/generics/ttable_alias.nim @@ -0,0 +1,7 @@ +# bug #4589 + +import tables +type SimpleTable*[TKey, TVal] = TableRef[TKey, TVal] +template newSimpleTable*(TKey, TVal: typedesc): SimpleTable[TKey, TVal] = newTable[TKey, TVal]() +var fontCache : SimpleTable[string, SimpleTable[int32, int]] +fontCache = newSimpleTable(string, SimpleTable[int32, int]) |