diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/astalgo.nim | 14 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 30 | ||||
-rw-r--r-- | compiler/extccomp.nim | 4 | ||||
-rw-r--r-- | compiler/installer.ini (renamed from compiler/nim.ini) | 0 | ||||
-rw-r--r-- | compiler/msgs.nim | 5 | ||||
-rw-r--r-- | compiler/pragmas.nim | 9 | ||||
-rw-r--r-- | compiler/sem.nim | 6 | ||||
-rw-r--r-- | compiler/semdata.nim | 1 | ||||
-rw-r--r-- | compiler/semexprs.nim | 33 | ||||
-rw-r--r-- | compiler/sempass2.nim | 42 | ||||
-rw-r--r-- | compiler/semstmts.nim | 4 | ||||
-rw-r--r-- | compiler/semtypes.nim | 7 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 27 |
13 files changed, 111 insertions, 71 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index f23e9a983..e9b82d74b 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -130,8 +130,8 @@ proc skipConvAndClosure*(n: PNode): PNode = proc sameValue*(a, b: PNode): bool = result = false case a.kind - of nkCharLit..nkInt64Lit: - if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal == b.intVal + of nkCharLit..nkUInt64Lit: + if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal of nkFloatLit..nkFloat64Lit: if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal of nkStrLit..nkTripleStrLit: @@ -145,13 +145,13 @@ proc leValue*(a, b: PNode): bool = # a <= b? result = false case a.kind - of nkCharLit..nkInt64Lit: - if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal <= b.intVal - of nkFloatLit..nkFloat64Lit: + of nkCharLit..nkUInt32Lit: + if b.kind in {nkCharLit..nkUInt32Lit}: result = a.intVal <= b.intVal + of nkFloatLit..nkFloat64Lit: if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal - of nkStrLit..nkTripleStrLit: + of nkStrLit..nkTripleStrLit: if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal <= b.strVal - else: + else: # don't raise an internal error for 'nimrod check': #InternalError(a.info, "leValue") discard diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index b9fc694cb..fb878a83e 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -430,15 +430,27 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = assert(typ.kind == tyProc) var length = sonsLen(ri) assert(sonsLen(typ) == sonsLen(typ.n)) - - if length > 1: - app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) - app(pl, ~" ") - app(pl, op.r) - if length > 2: - app(pl, ~": ") - app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri)) - for i in countup(3, length-1): + + # don't call 'ropeToStr' here for efficiency: + let pat = ri.sons[0].sym.loc.r.data + internalAssert pat != nil + var start = 3 + if ' ' in pat: + start = 1 + app(pl, op.r) + if length > 1: + app(pl, ~": ") + app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) + start = 2 + else: + if length > 1: + app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) + app(pl, ~" ") + app(pl, op.r) + if length > 2: + app(pl, ~": ") + app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri)) + for i in countup(start, length-1): assert(sonsLen(typ) == sonsLen(typ.n)) if i >= sonsLen(typ): internalError(ri.info, "varargs for objective C method?") diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 8e40cca39..1083b7590 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -626,7 +626,9 @@ proc callCCompiler*(projectfile: string) = if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors() var res = 0 if gNumberOfProcessors <= 1: - for i in countup(0, high(cmds)): res = max(execWithEcho(cmds[i]), res) + for i in countup(0, high(cmds)): + res = execWithEcho(cmds[i]) + if res != 0: rawMessage(errExecutionOfProgramFailed, []) elif optListCmd in gGlobalOptions or gVerbosity > 1: res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams}, gNumberOfProcessors) diff --git a/compiler/nim.ini b/compiler/installer.ini index dcf9aa52f..dcf9aa52f 100644 --- a/compiler/nim.ini +++ b/compiler/installer.ini diff --git a/compiler/msgs.nim b/compiler/msgs.nim index be69f1ea5..45fc2b1e2 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -720,7 +720,10 @@ type proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) = template quit = if defined(debug) or gVerbosity >= 3 or msg == errInternal: - writeStackTrace() + if stackTraceAvailable(): + writeStackTrace() + else: + msgWriteln("No stack traceback available\nTo create a stacktrace, rerun compilation with ./koch temp c <file>") quit 1 if msg >= fatalMin and msg <= fatalMax: diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 90f87696b..78ee490e2 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -735,11 +735,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, incl(sym.flags, sfProcvar) if sym.typ != nil: incl(sym.typ.flags, tfThread) of wGcSafe: - if optThreadAnalysis in gGlobalOptions: - noVal(it) - if sym.kind != skType: incl(sym.flags, sfThread) - if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) - else: invalidPragma(it) + noVal(it) + if sym.kind != skType: incl(sym.flags, sfThread) + if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) + else: invalidPragma(it) of wPacked: noVal(it) if sym.typ == nil: invalidPragma(it) diff --git a/compiler/sem.nim b/compiler/sem.nim index 214f471d6..2d69d4213 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -130,9 +130,11 @@ proc commonType*(x, y: PType): PType = elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len: var nt: PType for i in 0.. <a.len: - if isEmptyContainer(a.sons[i]) and not isEmptyContainer(b.sons[i]): + let aEmpty = isEmptyContainer(a.sons[i]) + let bEmpty = isEmptyContainer(b.sons[i]) + if aEmpty != bEmpty: if nt.isNil: nt = copyType(a, a.owner, false) - nt.sons[i] = b.sons[i] + nt.sons[i] = if aEmpty: b.sons[i] else: a.sons[i] if not nt.isNil: result = nt #elif b.sons[idx].kind == tyEmpty: return x elif a.kind == tyRange and b.kind == tyRange: diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 157761591..27d441000 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -221,6 +221,7 @@ proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode = proc makeTypeFromExpr*(c: PContext, n: PNode): PType = result = newTypeS(tyFromExpr, c) + assert n != nil result.n = n proc newTypeWithSons*(c: PContext, kind: TTypeKind, diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 40413e3eb..55d2656e0 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -448,25 +448,30 @@ proc changeType(n: PNode, newType: PType, check: bool) = let tup = newType.skipTypes({tyGenericInst}) if tup.kind != tyTuple: internalError(n.info, "changeType: no tuple type for constructor") - elif newType.n == nil: discard - elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr: - for i in countup(0, sonsLen(n) - 1): + elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr: + # named tuple? + for i in countup(0, sonsLen(n) - 1): var m = n.sons[i].sons[0] - if m.kind != nkSym: + if m.kind != nkSym: internalError(m.info, "changeType(): invalid tuple constr") return - var f = getSymFromList(newType.n, m.sym.name) - if f == nil: - internalError(m.info, "changeType(): invalid identifier") - return - changeType(n.sons[i].sons[1], f.typ, check) + if tup.n != nil: + var f = getSymFromList(newType.n, m.sym.name) + if f == nil: + internalError(m.info, "changeType(): invalid identifier") + return + changeType(n.sons[i].sons[1], f.typ, check) + else: + changeType(n.sons[i].sons[1], tup.sons[i], check) else: for i in countup(0, sonsLen(n) - 1): - var m = n.sons[i] - var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i]) - addSon(a, newSymNode(newType.n.sons[i].sym)) - addSon(a, m) - changeType(m, tup.sons[i], check) + changeType(n.sons[i], tup.sons[i], check) + when false: + var m = n.sons[i] + var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i]) + addSon(a, newSymNode(newType.n.sons[i].sym)) + addSon(a, m) + changeType(m, tup.sons[i], check) of nkCharLit..nkUInt64Lit: if check: let value = n.intVal diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index ede556a70..3f78629c8 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -194,6 +194,9 @@ proc warnAboutGcUnsafe(n: PNode) = #assert false message(n.info, warnGcUnsafe, renderTree(n)) +template markGcUnsafe(a: PEffects) = + a.gcUnsafe = true + proc useVar(a: PEffects, n: PNode) = let s = n.sym if isLocalVar(a, s): @@ -209,7 +212,7 @@ proc useVar(a: PEffects, n: PNode) = if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and tfGcSafe notin s.typ.flags: if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - a.gcUnsafe = true + markGcUnsafe(a) type TIntersection = seq[tuple[id, count: int]] # a simple count table @@ -448,7 +451,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = if notGcSafe(s.typ) and sfImportc notin s.flags: if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) mergeLockLevels(tracked, n, s.getLockLevel) proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) = @@ -502,13 +505,13 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) = # assume GcUnsafe unless in its type; 'forward' does not matter: if notGcSafe(op) and not isOwnedProcVar(a, tracked.owner): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) else: mergeEffects(tracked, effectList.sons[exceptionEffects], n) mergeTags(tracked, effectList.sons[tagEffects], n) if notGcSafe(op): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) notNilCheck(tracked, n, paramType) proc breaksBlock(n: PNode): bool = @@ -656,7 +659,7 @@ proc track(tracked: PEffects, n: PNode) = # and it's not a recursive call: if not (a.kind == nkSym and a.sym == tracked.owner): warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) for i in 1 .. <len(n): trackOperand(tracked, n.sons[i], paramType(op, i)) if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}: # may not look like an assignment, but it is: @@ -825,7 +828,7 @@ proc trackProc*(s: PSym, body: PNode) = # effects already computed? if sfForward in s.flags: return if effects.len == effectListLen: return - + var t: TEffects initEffects(effects, s, t) track(t, body) @@ -849,19 +852,20 @@ proc trackProc*(s: PSym, body: PNode) = # after the check, use the formal spec: effects.sons[tagEffects] = tagsSpec - if optThreadAnalysis in gGlobalOptions: - if sfThread in s.flags and t.gcUnsafe: - if optThreads in gGlobalOptions: - localError(s.info, "'$1' is not GC-safe" % s.name.s) - else: - localError(s.info, warnGcUnsafe2, s.name.s) - if not t.gcUnsafe: s.typ.flags.incl tfGcSafe - if s.typ.lockLevel == UnspecifiedLockLevel: - s.typ.lockLevel = t.maxLockLevel - elif t.maxLockLevel > s.typ.lockLevel: - localError(s.info, - "declared lock level is $1, but real lock level is $2" % - [$s.typ.lockLevel, $t.maxLockLevel]) + if sfThread in s.flags and t.gcUnsafe: + if optThreads in gGlobalOptions and optThreadAnalysis in gGlobalOptions: + localError(s.info, "'$1' is not GC-safe" % s.name.s) + else: + localError(s.info, warnGcUnsafe2, s.name.s) + if not t.gcUnsafe: + s.typ.flags.incl tfGcSafe + if s.typ.lockLevel == UnspecifiedLockLevel: + s.typ.lockLevel = t.maxLockLevel + elif t.maxLockLevel > s.typ.lockLevel: + #localError(s.info, + message(s.info, warnLockLevel, + "declared lock level is $1, but real lock level is $2" % + [$s.typ.lockLevel, $t.maxLockLevel]) proc trackTopLevelStmt*(module: PSym; n: PNode) = if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef, diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 6e5b272de..07cae5d04 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -359,6 +359,10 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var def: PNode if a.sons[length-1].kind != nkEmpty: def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) + if def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro: + # prevent the all too common 'var x = int' bug: + localError(def.info, "'typedesc' metatype is not valid here; typed '=' instead of ':'?") + def.typ = errorType(c) if typ != nil: if typ.isMetaType: def = inferWithMetatype(c, typ, def) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index d052700b2..048154f12 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -781,9 +781,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result.rawAddSon(paramType) for i in 0 .. paramType.sonsLen - 2: - let dummyType = if paramType.sons[i].kind == tyStatic: tyUnknown - else: tyAnything - result.rawAddSon newTypeS(dummyType, c) + if paramType.sons[i].kind == tyStatic: + result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnkown' + else: + result.rawAddSon newTypeS(tyAnything, c) if paramType.lastSon.kind == tyUserTypeClass: result.kind = tyUserTypeClassInst diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 2e37f3bf1..00802e69b 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -418,7 +418,8 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags: return isNone - elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}: + elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {} and + optThreadAnalysis in gGlobalOptions: # noSideEffect implies ``tfThread``! return isNone elif f.flags * {tfIterator} != a.flags * {tfIterator}: @@ -1056,7 +1057,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyFromExpr: # fix the expression, so it contains the already instantiated types - if f.n == nil: return isGeneric + if f.n == nil or f.n.kind == nkEmpty: return isGeneric let reevaluated = tryResolvingStaticExpr(c, f.n) case reevaluated.typ.kind of tyTypeDesc: @@ -1441,13 +1442,14 @@ proc matchesAux(c: PContext, n, nOrig: PNode, return checkConstraint(n.sons[a].sons[1]) if m.baseTypeMatch: - assert(container == nil) + #assert(container == nil) container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) addSon(container, arg) setSon(m.call, formal.position + 1, container) if f != formalLen - 1: container = nil - else: + else: setSon(m.call, formal.position + 1, arg) + inc f else: # unnamed param if f >= formalLen: @@ -1466,7 +1468,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, n.sons[a] = prepareOperand(c, formal.typ, n.sons[a]) var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, n.sons[a], nOrig.sons[a]) - if (arg != nil) and m.baseTypeMatch and (container != nil): + if arg != nil and m.baseTypeMatch and container != nil: addSon(container, arg) incrIndexType(container.typ) else: @@ -1480,7 +1482,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, internalError(n.sons[a].info, "matches") return formal = m.callee.n.sons[f].sym - if containsOrIncl(marker, formal.position): + if containsOrIncl(marker, formal.position) and container.isNil: # already in namedParams: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s) m.state = csNoMatch @@ -1493,17 +1495,22 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m.state = csNoMatch return if m.baseTypeMatch: - assert(container == nil) - container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) + #assert(container == nil) + if container.isNil: + container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) addSon(container, arg) setSon(m.call, formal.position + 1, implicitConv(nkHiddenStdConv, formal.typ, container, m, c)) - if f != formalLen - 1: container = nil + #if f != formalLen - 1: container = nil + + # pick the formal from the end, so that 'x, y, varargs, z' works: + f = max(f, formalLen - n.len + a + 1) else: setSon(m.call, formal.position + 1, arg) + inc(f) + container = nil checkConstraint(n.sons[a]) inc(a) - inc(f) proc semFinishOperands*(c: PContext, n: PNode) = # this needs to be called to ensure that after overloading resolution every |