Merge remote-tracking branch 'nim-lang/devel' into emscripten-support

This commit is contained in:
Andrey Sobolev
2015-09-16 22:01:18 +06:00
32 changed files with 484 additions and 100 deletions

View File

@@ -477,6 +477,8 @@ type
# wildcard type.
tfHasAsgn # type has overloaded assignment operator
tfBorrowDot # distinct type borrows '.'
tfTriggersCompileTime # uses the NimNode type which make the proc
# implicitly '.compiletime'
TTypeFlags* = set[TTypeFlag]
@@ -1380,6 +1382,9 @@ proc propagateToOwner*(owner, elem: PType) =
o2.flags.incl tfHasAsgn
owner.flags.incl tfHasAsgn
if tfTriggersCompileTime in elem.flags:
owner.flags.incl tfTriggersCompileTime
if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
tyGenericInvocation, tyPtr}:
let elemB = elem.skipTypes({tyGenericInst})

View File

@@ -1741,6 +1741,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mEcho: genEcho(p, e[1].skipConv)
of mArrToSeq: genArrToSeq(p, e, d)
of mNLen..mNError, mSlurp..mQuoteAst:
echo "from here ", p.prc.name.s, " ", p.prc.info
writestacktrace()
localError(e.info, errXMustBeCompileTime, e.sons[0].sym.name.s)
of mSpawn:
let n = lowerings.wrapProcForSpawn(p.module.module, e, e.typ, nil, nil)
@@ -1973,6 +1975,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
genProc(p.module, sym)
putLocIntoDest(p, d, sym.loc)
of skProc, skConverter, skIterators:
if sfCompileTime in sym.flags:
localError(n.info, "request to generate code for .compileTime proc: " &
sym.name.s)
genProc(p.module, sym)
if sym.loc.r == nil or sym.loc.t == nil:
internalError(n.info, "expr: proc not init " & sym.name.s)
@@ -2126,7 +2131,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
# due to a bug/limitation in the lambda lifting, unused inner procs
# are not transformed correctly. We work around this issue (#411) here
# by ensuring it's no inner proc (owner is a module):
if prc.skipGenericOwner.kind == skModule:
if prc.skipGenericOwner.kind == skModule and sfCompileTime notin prc.flags:
if (optDeadCodeElim notin gGlobalOptions and
sfDeadCodeElim notin getModule(prc).flags) or
({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or

View File

@@ -1110,7 +1110,7 @@ proc rawNewModule(module: PSym, filename: string): BModule =
proc nullify[T](arr: var T) =
for i in low(arr)..high(arr):
arr[i] = nil
arr[i] = Rope(nil)
proc resetModule*(m: BModule) =
# between two compilations in CAAS mode, we can throw

View File

@@ -92,3 +92,4 @@ proc initDefines*() =
defineSymbol("nimvarargstyped")
defineSymbol("nimtypedescfixed")
defineSymbol("nimKnowsNimvm")
defineSymbol("nimArrIdx")

View File

@@ -514,6 +514,7 @@ const
{low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit,
warnProveField, warnProveIndex,
warnGcUnsafe,
hintPath, hintConf,
hintDependency,
hintExecuting,
hintCodeBegin, hintCodeEnd,

View File

@@ -308,7 +308,10 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
let gp = finalCallee.ast.sons[genericParamsPos]
if gp.kind != nkEmpty:
if x.calleeSym.kind notin {skMacro, skTemplate}:
finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info)
if x.calleeSym.magic in {mArrGet, mArrPut}:
finalCallee = x.calleeSym
else:
finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info)
else:
# For macros and templates, the resolved generic params
# are added as normal params.

View File

@@ -45,7 +45,8 @@ type
TExprFlag* = enum
efLValue, efWantIterator, efInTypeof,
efWantStmt, efAllowStmt, efDetermineType,
efAllowDestructor, efWantValue, efOperand, efNoSemCheck
efAllowDestructor, efWantValue, efOperand, efNoSemCheck,
efNoProcvarCheck
TExprFlags* = set[TExprFlag]
TTypeAttachedOp* = enum

View File

@@ -52,7 +52,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result.typ = errorType(c)
else:
# XXX tyGenericInst here?
semProcvarCheck(c, result)
if efNoProcvarCheck notin flags: semProcvarCheck(c, result)
if result.typ.kind == tyVar: result = newDeref(result)
semDestructorCheck(c, result, flags)
@@ -452,18 +452,18 @@ proc changeType(n: PNode, newType: PType, check: bool) =
let tup = newType.skipTypes({tyGenericInst})
if tup.kind != tyTuple:
if tup.kind == tyObject: return
internalError(n.info, "changeType: no tuple type for constructor")
globalError(n.info, "no tuple type for constructor")
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:
internalError(m.info, "changeType(): invalid tuple constr")
globalError(m.info, "invalid tuple constructor")
return
if tup.n != nil:
var f = getSymFromList(tup.n, m.sym.name)
if f == nil:
internalError(m.info, "changeType(): invalid identifier")
globalError(m.info, "unknown identifier: " & m.sym.name.s)
return
changeType(n.sons[i].sons[1], f.typ, check)
else:
@@ -1156,7 +1156,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
result.add(x[0])
return
checkMinSonsLen(n, 2)
n.sons[0] = semExprWithType(c, n.sons[0])
n.sons[0] = semExprWithType(c, n.sons[0], {efNoProcvarCheck})
let arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef})
case arr.kind
of tyArray, tyOpenArray, tyVarargs, tyArrayConstr, tySequence, tyString,
@@ -1196,7 +1196,17 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
localError(n.info, errIndexTypesDoNotMatch)
result = n
else:
c.p.bracketExpr = n.sons[0]
let s = if n.sons[0].kind == nkSym: n.sons[0].sym
elif n[0].kind in nkSymChoices: n.sons[0][0].sym
else: nil
if s != nil and s.kind in {skProc, skMethod, skConverter}+skIterators:
# type parameters: partial generic specialization
n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s)
result = explicitGenericInstantiation(c, n, s)
elif s != nil and s.kind == skType:
result = symNodeFromType(c, semTypeNode(c, n, nil), n.info)
else:
c.p.bracketExpr = n.sons[0]
proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
let oldBracketExpr = c.p.bracketExpr
@@ -1250,7 +1260,7 @@ proc asgnToResultVar(c: PContext, n, le, ri: PNode) {.inline.} =
template resultTypeIsInferrable(typ: PType): expr =
typ.isMetaType and typ.kind != tyTypeDesc
proc semAsgn(c: PContext, n: PNode): PNode =
proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
checkSonsLen(n, 2)
var a = n.sons[0]
case a.kind
@@ -1273,12 +1283,15 @@ proc semAsgn(c: PContext, n: PNode): PNode =
# --> `[]=`(a, i, x)
let oldBracketExpr = c.p.bracketExpr
a = semSubscript(c, a, {efLValue})
if a == nil:
if a == nil and mode != noOverloadedSubscript:
result = buildOverloadedSubscripts(n.sons[0], getIdent"[]=")
add(result, n[1])
result = semExprNoType(c, result)
c.p.bracketExpr = oldBracketExpr
return result
elif a == nil:
localError(n.info, "could not resolve: " & $n[0])
return n
c.p.bracketExpr = oldBracketExpr
of nkCurlyExpr:
# a{i} = x --> `{}=`(a, i, x)
@@ -1323,7 +1336,8 @@ proc semAsgn(c: PContext, n: PNode): PNode =
typeMismatch(n, lhs.typ, rhs.typ)
n.sons[1] = fitNode(c, le, rhs)
if tfHasAsgn in lhs.typ.flags and not lhsIsResult:
if tfHasAsgn in lhs.typ.flags and not lhsIsResult and
mode != noOverloadedAsgn:
return overloadedAsgn(c, lhs, n.sons[1])
fixAbstractType(c, n)
@@ -1715,6 +1729,9 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
of mTypeOf:
checkSonsLen(n, 2)
result = semTypeOf(c, n.sons[1])
#of mArrGet: result = semArrGet(c, n, flags)
#of mArrPut: result = semArrPut(c, n, flags)
#of mAsgn: result = semAsgnOpr(c, n)
of mDefined: result = semDefined(c, setMs(n, s), false)
of mDefinedInScope: result = semDefined(c, setMs(n, s), true)
of mCompiles: result = semCompiles(c, setMs(n, s), flags)
@@ -2066,6 +2083,19 @@ proc semExport(c: PContext, n: PNode): PNode =
c.module.ast.add x
result = n
proc shouldBeBracketExpr(n: PNode): bool =
assert n.kind in nkCallKinds
let a = n.sons[0]
if a.kind in nkCallKinds:
let b = a[0]
if b.kind in nkSymChoices:
for i in 0..<b.len:
if b[i].sym.magic == mArrGet:
let be = newNodeI(nkBracketExpr, n.info)
for i in 1..<a.len: be.add(a[i])
n.sons[0] = be
return true
proc setGenericParams(c: PContext, n: PNode) =
for i in 1 .. <n.len:
n[i].typ = semTypeNode(c, n[i], nil)
@@ -2173,7 +2203,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
else:
#liMessage(n.info, warnUser, renderTree(n));
result = semIndirectOp(c, n, flags)
elif n[0].kind == nkBracketExpr and isSymChoice(n[0][0]):
elif (n[0].kind == nkBracketExpr or shouldBeBracketExpr(n)) and
isSymChoice(n[0][0]):
# indirectOp can deal with explicit instantiations; the fixes
# the 'newSeq[T](x)' bug
setGenericParams(c, n.sons[0])
@@ -2194,16 +2225,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result = semExpr(c, result, flags)
of nkBracketExpr:
checkMinSonsLen(n, 1)
var s = qualifiedLookUp(c, n.sons[0], {checkUndeclared})
if (s != nil and s.kind in {skProc, skMethod, skConverter}+skIterators) or
n[0].kind in nkSymChoices:
# type parameters: partial generic specialization
n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s)
result = explicitGenericInstantiation(c, n, s)
elif s != nil and s.kind in {skType}:
result = symNodeFromType(c, semTypeNode(c, n, nil), n.info)
else:
result = semArrayAccess(c, n, flags)
result = semArrayAccess(c, n, flags)
of nkCurlyExpr:
result = semExpr(c, buildOverloadedSubscripts(n, getIdent"{}"), flags)
of nkPragmaExpr:

View File

@@ -430,17 +430,10 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
of mCompileOptionArg:
result = newIntNodeT(ord(
testCompileOptionArg(getStr(a), getStr(b), n.info)), n)
of mNewString, mNewStringOfCap,
mExit, mInc, ast.mDec, mEcho, mSwap, mAppendStrCh,
mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq,
mParseExprToAst, mParseStmtToAst, mExpandToAst, mTypeTrait, mDotDot,
mNLen..mNError, mEqRef, mSlurp, mStaticExec, mNGenSym, mSpawn,
mParallel, mPlugin, mGetTypeInfo, mTypeOf:
discard
of mEqProc:
result = newIntNodeT(ord(
exprStructuralEquivalent(a, b, strictSymEquality=true)), n)
else: internalError(a.info, "evalOp(" & $m & ')')
else: discard
proc getConstIfExpr(c: PSym, n: PNode): PNode =
result = nil

View File

@@ -30,6 +30,13 @@ type
GenericCtx = object
toMixin: IntSet
cursorInBody: bool # only for nimsuggest
bracketExpr: PNode
template withBracketExpr(x, body: untyped) =
let old = ctx.bracketExpr
ctx.bracketExpr = x
body
ctx.bracketExpr = old
type
TSemGenericFlag = enum
@@ -227,6 +234,10 @@ proc semGenericStmt(c: PContext, n: PNode,
discard
of skProc, skMethod, skIterators, skConverter, skModule:
result.sons[0] = symChoice(c, fn, s, scOption)
# do check of 's.magic==mRoof' here because it might be some
# other '^' but after overload resolution the proper one:
if ctx.bracketExpr != nil and n.len == 2 and s.name.s == "^":
result.add ctx.bracketExpr
first = 1
of skGenericParam:
result.sons[0] = newSymNodeTypeDesc(s, fn.info)
@@ -251,6 +262,40 @@ proc semGenericStmt(c: PContext, n: PNode,
let flags = if mixinContext: flags+{withinMixin} else: flags
for i in countup(first, sonsLen(result) - 1):
result.sons[i] = semGenericStmt(c, result.sons[i], flags, ctx)
of nkCurlyExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent("{}"), n.info)
for i in 0 ..< n.len: result.add(n[i])
result = semGenericStmt(c, result, flags, ctx)
of nkBracketExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent("[]"), n.info)
for i in 0 ..< n.len: result.add(n[i])
withBracketExpr n.sons[0]:
result = semGenericStmt(c, result, flags, ctx)
of nkAsgn, nkFastAsgn:
checkSonsLen(n, 2)
let a = n.sons[0]
let b = n.sons[1]
let k = a.kind
case k
of nkCurlyExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent("{}="), n.info)
for i in 0 ..< a.len: result.add(a[i])
result.add(b)
result = semGenericStmt(c, result, flags, ctx)
of nkBracketExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent("[]="), n.info)
for i in 0 ..< a.len: result.add(a[i])
result.add(b)
withBracketExpr a.sons[0]:
result = semGenericStmt(c, result, flags, ctx)
else:
for i in countup(0, sonsLen(n) - 1):
result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
of nkIfStmt:
for i in countup(0, sonsLen(n)-1):
n.sons[i] = semGenericStmtScope(c, n.sons[i], flags, ctx)

View File

@@ -246,6 +246,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
inc i
pushProcCon(c, result)
instantiateProcType(c, pt, result, info)
if tfTriggersCompileTime in result.typ.flags:
incl(result.flags, sfCompileTime)
n.sons[genericParamsPos] = ast.emptyNode
var oldPrc = genericCacheGet(fn, entry[])
if oldPrc == nil:

View File

@@ -26,6 +26,41 @@ proc semTypeOf(c: PContext; n: PNode): PNode =
result.add typExpr
result.typ = makeTypeDesc(c, typExpr.typ.skipTypes({tyTypeDesc, tyIter}))
type
SemAsgnMode = enum asgnNormal, noOverloadedSubscript, noOverloadedAsgn
proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode
proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode
proc skipAddr(n: PNode): PNode {.inline.} =
(if n.kind == nkHiddenAddr: n.sons[0] else: n)
proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
result = newNodeI(nkBracketExpr, n.info)
for i in 1..<n.len: result.add(n[i])
let oldBracketExpr = c.p.bracketExpr
result = semSubscript(c, result, flags)
c.p.bracketExpr = oldBracketExpr
if result.isNil:
localError(n.info, "could not resolve: " & $n)
result = n
proc semArrPut(c: PContext; n: PNode; flags: TExprFlags): PNode =
# rewrite `[]=`(a, i, x) back to ``a[i] = x``.
let b = newNodeI(nkBracketExpr, n.info)
b.add(n[1].skipAddr)
for i in 2..n.len-2: b.add(n[i])
result = newNodeI(nkAsgn, n.info, 2)
result.sons[0] = b
result.sons[1] = n.lastSon
result = semAsgn(c, result, noOverloadedSubscript)
proc semAsgnOpr(c: PContext; n: PNode): PNode =
result = newNodeI(nkAsgn, n.info, 2)
result.sons[0] = n[1]
result.sons[1] = n[2]
result = semAsgn(c, result, noOverloadedAsgn)
proc semIsPartOf(c: PContext, n: PNode, flags: TExprFlags): PNode =
var r = isPartOf(n[1], n[2])
result = newIntNodeT(ord(r), n)
@@ -125,6 +160,9 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
of mTypeOf:
checkSonsLen(n, 2)
result = semTypeOf(c, n.sons[1])
of mArrGet: result = semArrGet(c, n, flags)
of mArrPut: result = semArrPut(c, n, flags)
of mAsgn: result = semAsgnOpr(c, n)
of mIsPartOf: result = semIsPartOf(c, n, flags)
of mTypeTrait: result = semTypeTraits(c, n)
of mAstToStr:
@@ -145,25 +183,28 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
if isNegative(n.sons[1]) or (n.len > 2 and isNegative(n.sons[2])):
localError(n.info, "use '^' instead of '-'; negative indexing is obsolete")
of mRoof:
# error correction:
result = n.sons[1]
if c.p.bracketExpr.isNil:
let bracketExpr = if n.len == 3: n.sons[2] else: c.p.bracketExpr
if bracketExpr.isNil:
localError(n.info, "no surrounding array access context for '^'")
elif c.p.bracketExpr.checkForSideEffects != seNoSideEffect:
result = n.sons[1]
elif bracketExpr.checkForSideEffects != seNoSideEffect:
localError(n.info, "invalid context for '^' as '$#' has side effects" %
renderTree(c.p.bracketExpr))
elif c.p.bracketExpr.typ.isStrangeArray:
renderTree(bracketExpr))
result = n.sons[1]
elif bracketExpr.typ.isStrangeArray:
localError(n.info, "invalid context for '^' as len!=high+1 for '$#'" %
renderTree(c.p.bracketExpr))
renderTree(bracketExpr))
result = n.sons[1]
else:
# ^x is rewritten to: len(a)-x
let lenExpr = newNodeI(nkCall, n.info)
lenExpr.add newIdentNode(getIdent"len", n.info)
lenExpr.add c.p.bracketExpr
lenExpr.add bracketExpr
let lenExprB = semExprWithType(c, lenExpr)
if lenExprB.typ.isNil or not isOrdinalType(lenExprB.typ):
localError(n.info, "'$#' has to be of an ordinal type for '^'" %
renderTree(lenExpr))
result = n.sons[1]
else:
result = newNodeIT(nkCall, n.info, getSysType(tyInt))
result.add newSymNode(createMagic("-", mSubI), n.info)

View File

@@ -1033,6 +1033,7 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
"signature for 'deepCopy' must be proc[T: ptr|ref](x: T): T")
incl(s.flags, sfUsed)
of "=":
if s.magic == mAsgn: return
incl(s.flags, sfUsed)
let t = s.typ
if t.len == 3 and t.sons[0] == nil and t.sons[1].kind == tyVar:
@@ -1131,6 +1132,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
# semParamList(c, n.sons[ParamsPos], nil, s)
else:
s.typ = newProcType(c, n.info)
if tfTriggersCompileTime in s.typ.flags: incl(s.flags, sfCompileTime)
if n.sons[patternPos].kind != nkEmpty:
n.sons[patternPos] = semPattern(c, n.sons[patternPos])
if s.kind in skIterators:

View File

@@ -281,6 +281,35 @@ proc semTemplBodySons(c: var TemplCtx, n: PNode): PNode =
for i in 0.. < n.len:
result.sons[i] = semTemplBody(c, n.sons[i])
proc wrapInBind(c: var TemplCtx; n: PNode; opr: string): PNode =
let ident = getIdent(opr)
if ident.id in c.toInject: return n
let s = searchInScopes(c.c, ident)
if s != nil:
var callee: PNode
if contains(c.toBind, s.id):
callee = symChoice(c.c, n, s, scClosed)
elif contains(c.toMixin, s.name.id):
callee = symChoice(c.c, n, s, scForceOpen)
elif s.owner == c.owner and sfGenSym in s.flags:
# template tmp[T](x: var seq[T]) =
# var yz: T
incl(s.flags, sfUsed)
callee = newSymNode(s, n.info)
styleCheckUse(n.info, s)
else:
callee = semTemplSymbol(c.c, n, s)
let call = newNodeI(nkCall, n.info)
call.add(callee)
for i in 0 .. n.len-1: call.add(n[i])
result = newNodeI(nkBind, n.info, 2)
result.sons[0] = n
result.sons[1] = call
else:
result = n
proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
result = n
semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
@@ -423,6 +452,28 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
result.sons[1] = semTemplBody(c, n.sons[1])
of nkPragma:
result = onlyReplaceParams(c, n)
of nkBracketExpr, nkCurlyExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(if n.kind == nkBracketExpr:"[]" else:"{}"),
n.info)
for i in 0 ..< n.len: result.add(n[i])
result = semTemplBodySons(c, result)
of nkAsgn, nkFastAsgn:
checkSonsLen(n, 2)
let a = n.sons[0]
let b = n.sons[1]
let k = a.kind
case k
of nkBracketExpr, nkCurlyExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(if k == nkBracketExpr:"[]=" else:"{}="),
n.info)
for i in 0 ..< a.len: result.add(a[i])
result.add(b)
else:
result = n
result = semTemplBodySons(c, result)
else:
# dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam',
# so we use the generic code for nkDotExpr too

View File

@@ -718,12 +718,12 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
if paramType == nil: return # (e.g. proc return type)
proc addImplicitGenericImpl(typeClass: PType, typId: PIdent): PType =
let finalTypId = if typId != nil: typId
else: getIdent(paramName & ":type")
if genericParams == nil:
# This happens with anonymous proc types appearing in signatures
# XXX: we need to lift these earlier
return
let finalTypId = if typId != nil: typId
else: getIdent(paramName & ":type")
# is this a bindOnce type class already present in the param list?
for i in countup(0, genericParams.len - 1):
if genericParams.sons[i].sym.name.id == finalTypId.id:
@@ -757,7 +757,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
case paramType.kind:
of tyAnything:
result = addImplicitGeneric(newTypeS(tyGenericParam, c))
result = addImplicitGenericImpl(newTypeS(tyGenericParam, c), nil)
of tyStatic:
# proc(a: expr{string}, b: expr{nkLambda})
@@ -868,6 +868,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
of tyExpr:
if procKind notin {skMacro, skTemplate}:
result = addImplicitGeneric(newTypeS(tyAnything, c))
#result = addImplicitGenericImpl(newTypeS(tyGenericParam, c), nil)
of tyGenericParam:
markUsed(info, paramType.sym)
@@ -977,7 +978,11 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
# compiler only checks for 'nil':
if skipTypes(r, {tyGenericInst}).kind != tyEmpty:
# 'auto' as a return type does not imply a generic:
if r.kind != tyExpr:
if r.kind == tyAnything:
# 'p(): auto' and 'p(): expr' are equivalent, but the rest of the
# compiler is hardly aware of 'auto':
r = newTypeS(tyExpr, c)
elif r.kind != tyExpr:
if r.sym == nil or sfAnon notin r.sym.flags:
let lifted = liftParamType(c, kind, genericParams, r, "result",
n.sons[0].info)
@@ -1149,7 +1154,17 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
else:
result = semAnonTuple(c, n, prev)
of nkCallKinds:
if isRange(n):
let x = n[0]
let ident = case x.kind
of nkIdent: x.ident
of nkSym: x.sym.name
of nkClosedSymChoice, nkOpenSymChoice: x[0].sym.name
else: nil
if ident != nil and ident.s == "[]":
let b = newNodeI(nkBracketExpr, n.info)
for i in 1..<n.len: b.add(n[i])
result = semTypeNode(c, b, prev)
elif ident != nil and ident.id == ord(wDotDot):
result = semRangeAux(c, n, prev)
elif n[0].kind notin nkIdentKinds:
result = semTypeExpr(c, n)
@@ -1336,8 +1351,11 @@ proc processMagicType(c: PContext, m: PSym) =
of mIntSetBaseType: setMagicType(m, tyRange, intSize)
of mNil: setMagicType(m, tyNil, ptrSize)
of mExpr:
setMagicType(m, tyExpr, 0)
if m.name.s == "expr": m.typ.flags.incl tfOldSchoolExprStmt
if m.name.s == "auto":
setMagicType(m, tyAnything, 0)
else:
setMagicType(m, tyExpr, 0)
if m.name.s == "expr": m.typ.flags.incl tfOldSchoolExprStmt
of mStmt:
setMagicType(m, tyStmt, 0)
if m.name.s == "stmt": m.typ.flags.incl tfOldSchoolExprStmt
@@ -1365,7 +1383,8 @@ proc processMagicType(c: PContext, m: PSym) =
of mOrdinal:
setMagicType(m, tyOrdinal, 0)
rawAddSon(m.typ, newTypeS(tyNone, c))
of mPNimrodNode: discard
of mPNimrodNode:
incl m.typ.flags, tfTriggersCompileTime
of mShared:
setMagicType(m, tyObject, 0)
m.typ.n = newNodeI(nkRecList, m.info)

View File

@@ -1691,6 +1691,10 @@ proc partialMatch*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
matchesAux(c, n, nOrig, m, marker)
proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
if m.calleeSym != nil and m.calleeSym.magic in {mArrGet, mArrPut}:
m.state = csMatch
m.call = n
return
var marker = initIntSet()
matchesAux(c, n, nOrig, m, marker)
if m.state == csNoMatch: return

View File

@@ -116,7 +116,7 @@ type class matches
``array`` any array type
``set`` any set type
``seq`` any seq type
``auto`` any type
``any`` any type
================== ===================================================
Furthermore, every generic type automatically creates a type class of the same
@@ -163,15 +163,6 @@ module to illustrate this:
Alternatively, the ``distinct`` type modifier can be applied to the type class
to allow each param matching the type class to bind to a different type.
If a proc param doesn't have a type specified, Nim will use the
``distinct auto`` type class (also known as ``any``). Note this behavior is
deprecated for procs; templates, however, support them:
.. code-block:: nim
# allow any combination of param types
proc concat(a, b): string = $a & $b # deprecated
proc concat(a, b: any): string = $a & $b # preferred
Procs written with the implicitly generic style will often need to refer to the
type parameters of the matched generic type. They can be easily accessed using
the dot syntax:

View File

@@ -72,7 +72,20 @@ compileTime pragma
------------------
The ``compileTime`` pragma is used to mark a proc or variable to be used at
compile time only. No code will be generated for it. Compile time procs are
useful as helpers for macros.
useful as helpers for macros. Since version 0.12.0 of the language, a proc
that uses ``system.NimNode`` within its parameter types is implictly declared
``compileTime``:
.. code-block:: nim
proc astHelper(n: NimNode): NimNode =
result = n
Is the same as:
.. code-block:: nim
proc astHelper(n: NimNode): NimNode {.compileTime.} =
result = n
noReturn pragma
---------------

View File

@@ -1228,3 +1228,27 @@ However, a ``void`` type cannot be inferred in generic code:
The ``void`` type is only valid for parameters and return types; other symbols
cannot have the type ``void``.
Auto type
---------
The ``auto`` type can only be used for return types and parameters. For return
types it causes the compiler to infer the type from the routine body:
.. code-block:: nim
proc returnsInt(): auto = 1984
For parameters it currently creates implicitly generic routines:
.. code-block:: nim
proc foo(a, b: auto) = discard
Is the same as:
.. code-block:: nim
proc foo[T1, T2](a: T1, b: T2) = discard
However later versions of the language might change this to mean "infer the
parameters' types from the body". Then the above ``foo`` would be rejected as
the parameters' types can not be infered from an empty ``discard`` statement.

View File

@@ -2316,7 +2316,7 @@ proc timer_settime*(a1: Timer, a2: cint, a3: var Itimerspec,
proc tzset*() {.importc, header: "<time.h>".}
proc wait*(a1: var cint): Pid {.importc, header: "<sys/wait.h>".}
proc wait*(a1: ptr cint): Pid {.importc, discardable, header: "<sys/wait.h>".}
proc waitid*(a1: cint, a2: Id, a3: var SigInfo, a4: cint): cint {.
importc, header: "<sys/wait.h>".}
proc waitpid*(a1: Pid, a2: var cint, a3: cint): Pid {.

View File

@@ -533,6 +533,18 @@ proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {.
var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
result = res != 0
proc getLocalAddr*(socket: Socket): (string, Port) =
## Get the socket's local address and port number.
##
## This is high-level interface for `getsockname`:idx:.
getLocalAddr(socket.fd, socket.domain)
proc getPeerAddr*(socket: Socket): (string, Port) =
## Get the socket's peer address and port number.
##
## This is high-level interface for `getpeername`:idx:.
getPeerAddr(socket.fd, socket.domain)
proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {.
tags: [WriteIOEffect].} =
## Sets option ``opt`` to a boolean value specified by ``value``.

View File

@@ -371,6 +371,76 @@ proc getSockName*(socket: SocketHandle): Port =
raiseOSError(osLastError())
result = Port(rawsockets.ntohs(name.sin_port))
proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
## returns the socket's local address and port number.
##
## Similar to POSIX's `getsockname`:idx:.
case domain
of AF_INET:
var name: Sockaddr_in
when useWinVersion:
name.sin_family = int16(ord(AF_INET))
else:
name.sin_family = posix.AF_INET
var namelen = sizeof(name).SockLen
if getsockname(socket, cast[ptr SockAddr](addr(name)),
addr(namelen)) == -1'i32:
raiseOSError(osLastError())
result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
of AF_INET6:
var name: Sockaddr_in6
when useWinVersion:
name.sin6_family = int16(ord(AF_INET6))
else:
name.sin6_family = posix.AF_INET6
var namelen = sizeof(name).SockLen
if getsockname(socket, cast[ptr SockAddr](addr(name)),
addr(namelen)) == -1'i32:
raiseOSError(osLastError())
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
var buf: array[64, char]
if inet_ntop(name.sin6_family.cint,
addr name, buf.cstring, sizeof(buf).int32).isNil:
raiseOSError(osLastError())
result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
else:
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
## returns the socket's peer address and port number.
##
## Similar to POSIX's `getpeername`:idx:
case domain
of AF_INET:
var name: Sockaddr_in
when useWinVersion:
name.sin_family = int16(ord(AF_INET))
else:
name.sin_family = posix.AF_INET
var namelen = sizeof(name).SockLen
if getpeername(socket, cast[ptr SockAddr](addr(name)),
addr(namelen)) == -1'i32:
raiseOSError(osLastError())
result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
of AF_INET6:
var name: Sockaddr_in6
when useWinVersion:
name.sin6_family = int16(ord(AF_INET6))
else:
name.sin6_family = posix.AF_INET6
var namelen = sizeof(name).SockLen
if getpeername(socket, cast[ptr SockAddr](addr(name)),
addr(namelen)) == -1'i32:
raiseOSError(osLastError())
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
var buf: array[64, char]
if inet_ntop(name.sin6_family.cint,
addr name, buf.cstring, sizeof(buf).int32).isNil:
raiseOSError(osLastError())
result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
else:
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {.
tags: [ReadIOEffect].} =
## getsockopt for integer options.

View File

@@ -78,7 +78,7 @@ type
stmt* {.magic: Stmt.} ## meta type to denote a statement (for templates)
typedesc* {.magic: TypeDesc.} ## meta type to denote a type description
void* {.magic: "VoidType".} ## meta type to denote the absence of any type
auto* = expr ## meta type for automatic type determination
auto* {.magic: Expr.} ## meta type for automatic type determination
any* = distinct auto ## meta type for any supported type
untyped* {.magic: Expr.} ## meta type to denote an expression that
## is not resolved (for templates)
@@ -104,7 +104,7 @@ type
SomeNumber* = SomeInteger|SomeReal
## type class matching all number types
proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.}
proc defined*(x: expr): bool {.magic: "Defined", noSideEffect, compileTime.}
## Special compile-time procedure that checks whether `x` is
## defined.
## `x` is an external symbol introduced through the compiler's
@@ -125,7 +125,7 @@ when defined(nimalias):
TNumber: SomeNumber,
TOrdinal: SomeOrdinal].}
proc declared*(x: expr): bool {.magic: "Defined", noSideEffect.}
proc declared*(x: expr): bool {.magic: "Defined", noSideEffect, compileTime.}
## Special compile-time procedure that checks whether `x` is
## declared. `x` has to be an identifier or a qualified identifier.
## This can be used to check whether a library provides a certain
@@ -140,11 +140,11 @@ when defined(useNimRtl):
{.deadCodeElim: on.}
proc definedInScope*(x: expr): bool {.
magic: "DefinedInScope", noSideEffect, deprecated.}
magic: "DefinedInScope", noSideEffect, deprecated, compileTime.}
## **Deprecated since version 0.9.6**: Use ``declaredInScope`` instead.
proc declaredInScope*(x: expr): bool {.
magic: "DefinedInScope", noSideEffect.}
magic: "DefinedInScope", noSideEffect, compileTime.}
## Special compile-time procedure that checks whether `x` is
## declared in the current scope. `x` has to be an identifier.
@@ -160,7 +160,7 @@ proc unsafeAddr*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} =
## Cannot be overloaded.
discard
proc `type`*(x: expr): typeDesc {.magic: "TypeOf", noSideEffect.} =
proc `type`*(x: expr): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
## Builtin 'type' operator for accessing the type of an expression.
## Cannot be overloaded.
discard
@@ -239,6 +239,14 @@ type
seq*{.magic: "Seq".}[T] ## Generic type to construct sequences.
set*{.magic: "Set".}[T] ## Generic type to construct bit sets.
when defined(nimArrIdx):
# :array|openarray|string|seq|cstring|tuple
proc `[]`*[I: Ordinal;T](a: T; i: I): T {.
noSideEffect, magic: "ArrGet".}
proc `[]=`*[I: Ordinal;T,S](a: var T; i: I;
x: S) {.noSideEffect, magic: "ArrPut".}
proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
type
Slice*[T] = object ## builtin slice type
a*, b*: T ## the bounds
@@ -3384,7 +3392,7 @@ when hasAlloc:
x[j+i] = item[j]
inc(j)
proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} =
proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect, compileTime.} =
## Special compile-time procedure that checks whether `x` can be compiled
## without any semantic error.
## This can be used to check whether a type supports some operation:
@@ -3448,7 +3456,7 @@ when hasAlloc and not defined(nimscript) and not defined(JS):
include "system/deepcopy"
proc procCall*(x: expr) {.magic: "ProcCall".} =
proc procCall*(x: expr) {.magic: "ProcCall", compileTime.} =
## special magic to prohibit dynamic binding for `method`:idx: calls.
## This is similar to `super`:idx: in ordinary OO languages.
##
@@ -3457,6 +3465,7 @@ proc procCall*(x: expr) {.magic: "ProcCall".} =
## procCall someMethod(a, b)
discard
proc `^`*[T](x: int; y: openArray[T]): int {.noSideEffect, magic: "Roof".}
proc `^`*(x: int): int {.noSideEffect, magic: "Roof".} =
## builtin `roof`:idx: operator that can be used for convenient array access.
## ``a[^x]`` is rewritten to ``a[a.len-x]``. However currently the ``a``

View File

@@ -409,7 +409,7 @@ type
bytes*: array[0..15, char]
Sockaddr_in6* {.importc: "SOCKADDR_IN6",
header: "winsock2.h".} = object
header: "ws2tcpip.h".} = object
sin6_family*: int16
sin6_port*: int16 # unsigned
sin6_flowinfo*: int32 # unsigned
@@ -511,6 +511,9 @@ proc connect*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {.
proc getsockname*(s: SocketHandle, name: ptr SockAddr,
namelen: ptr SockLen): cint {.
stdcall, importc: "getsockname", dynlib: ws2dll.}
proc getpeername*(s: SocketHandle, name: ptr SockAddr,
namelen: ptr SockLen): cint {.
stdcall, importc, dynlib: ws2dll.}
proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer,
optlen: ptr SockLen): cint {.
stdcall, importc: "getsockopt", dynlib: ws2dll.}
@@ -572,6 +575,9 @@ proc freeaddrinfo*(ai: ptr AddrInfo) {.
proc inet_ntoa*(i: InAddr): cstring {.
stdcall, importc, dynlib: ws2dll.}
proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
stringBufSize: int32): cstring {.stdcall, importc, dynlib: ws2dll.}
const
MAXIMUM_WAIT_OBJECTS* = 0x00000040

View File

@@ -0,0 +1,9 @@
# bug #1679
import macros, tables, hashes
proc hash(v: NimNode): Hash = 4 # performance is for suckers
macro test(body: stmt): stmt {.immediate.} =
var a = initCountTable[NimNode]()
a.inc(body)
test:
1 + 1

View File

@@ -0,0 +1,17 @@
import tables
type
UUIDObject* = ref object
uuid: string
Registry*[T] = ref object
objects: Table[string, T]
proc newRegistry*[T](): Registry[T] =
result = Registry[T]()
result.objects = initTable[string, T](128)
proc register*[T](self: Registry[T], obj: T) =
self.objects[obj.uuid] = obj

View File

@@ -0,0 +1,20 @@
discard """
output: "317"
"""
# bug #2599
import mbind_bracket
# also test that `[]` can be passed now as a first class construct:
template takeBracket(x, a, i: untyped) =
echo x(a, i)
var a: array[10, int]
a[8] = 317
takeBracket(`[]`, a, 8)
let reg = newRegistry[UUIDObject]()
reg.register(UUIDObject())

View File

@@ -3,7 +3,7 @@ discard """
"""
type
TThreadFuncArgs[T] = object of TObject
TThreadFuncArgs[T] = object of RootObj
a: proc(): T {.thread.}
b: proc(val: T) {.thread.}

View File

@@ -7,7 +7,7 @@ type
proc getTypeName(t: typedesc): string = t.name
proc foo(T: typedesc[float], a: expr): string =
proc foo(T: typedesc[float], a: auto): string =
result = "float " & $(a.len > 5)
proc foo(T: typedesc[TFoo], a: int): string =

View File

@@ -0,0 +1,20 @@
discard """
output: '''10
10.0
1.0hiho'''
"""
# bug #3224
proc f(x: auto): auto =
result = $(x+10)
proc f(x, y: auto): auto =
result = $(x+y)
echo f(0) # prints 10
echo f(0.0) # prints 10.0
proc `+`(a, b: string): string = a & b
echo f(0.7, 0.3), f("hi", "ho")

View File

@@ -24,7 +24,6 @@ version 1.0
- The bitwise 'not' operator will be renamed to 'bnot' to
prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
- split docgen into separate tool
- special rule for ``[]=``, items, pairs
- BUG: echo with template `$`*(info: TLineInfo): expr = toFileLineCol(info)
- make 'nil' work for 'add':
- resizeString

View File

@@ -3,7 +3,7 @@ News
====
..
2015-05-05 Version 0.11.4 released
2015-09-14 Version 0.11.4 released
==================================
Changes affecting backwards compatibility
@@ -58,7 +58,7 @@ News
of all the DLLs the standard library needs. This means that the following
DLLs are now split into 32 and 64 versions:
* ``prce.dll``: Split into ``prce32.dll`` and ``prce64.dll``.
* ``pcre.dll``: Split into ``pcre32.dll`` and ``pcre64.dll``.
* ``pdcurses.dll``: Split into ``pdcurses32.dll`` and ``pdcurses64.dll``.
* ``sqlite3.dll``: Split into ``sqlite3_32.dll`` and ``sqlite3_64.dll``.
* ``ssleay32.dll``: Split into ``ssleay32.dll`` and ``ssleay64.dll``.
@@ -75,6 +75,13 @@ News
with Unix's ``#!``.
- An implicit return type for an iterator is now deprecated. Use ``auto`` if
you want more type inference.
- The type ``auto`` is now a "multi-bind" metatype, so the following compiles:
.. code-block:: nim
proc f(x, y: auto): auto =
result = $x & y
echo f(0, "abc")
Library Additions
@@ -95,6 +102,9 @@ News
- The compiler now supports a new configuration system based on
`NimScript <docs/nims.html>`_.
- The compiler finally considers symbol binding rules in templates and
generics for overloaded ``[]``, ``[]=``, ``{}``, ``{}=`` operators
(issue `#2599 <https://github.com/nim-lang/Nim/issues/2599>`_).
Language Additions
@@ -112,22 +122,21 @@ News
this ``let (x, y) == f()`` still needs to be used.
- ``when nimvm`` can now be used for compiletime versions of some code
sections. Click `here <docs/manual.html#when-nimvm-statement>`_ for details.
- Usage of the type ``NimNode`` in a proc now implicitly annotates the proc
with ``.compileTime``. This means generics work much better for ``NimNode``.
Bugfixes
--------
- Fixed "Compiler internal error on iterator it(T: typedesc[Base]) called with
it(Child), where Child = object of Base"
- Fixed "Compiler internal error on iterator it(T: typedesc[Base]) called with it(Child), where Child = object of Base"
(`#2662 <https://github.com/Araq/Nim/issues/2662>`_)
- Fixed "repr() misses base object field in 2nd level derived object"
(`#2749 <https://github.com/Araq/Nim/issues/2749>`_)
- Fixed "nimsuggest doesn't work more than once on the non-main file"
(`#2694 <https://github.com/Araq/Nim/issues/2694>`_)
- Fixed "JS Codegen. Passing arguments by var in certain cases leads to invali
d JS."
- Fixed "JS Codegen. Passing arguments by var in certain cases leads to invalid JS."
(`#2798 <https://github.com/Araq/Nim/issues/2798>`_)
- Fixed ""check" proc in unittest.nim prevents the propagation of changes to v
ar parameters."
- Fixed ""check" proc in unittest.nim prevents the propagation of changes to var parameters."
(`#964 <https://github.com/Araq/Nim/issues/964>`_)
- Fixed "Excessive letters in integer literals are not an error"
(`#2523 <https://github.com/Araq/Nim/issues/2523>`_)
@@ -141,8 +150,7 @@ ar parameters."
(`#2687 <https://github.com/Araq/Nim/issues/2687>`_)
- Fixed "Compile error using object in const array"
(`#2774 <https://github.com/Araq/Nim/issues/2774>`_)
- Fixed "httpclient async requests with method httpPOST isn't sending Content-
Length header"
- Fixed "httpclient async requests with method httpPOST isn't sending Content-Length header"
(`#2884 <https://github.com/Araq/Nim/issues/2884>`_)
- Fixed "Streams module not working with JS backend"
(`#2148 <https://github.com/Araq/Nim/issues/2148>`_)
@@ -173,8 +181,7 @@ Length header"
(`#2974 <https://github.com/Araq/Nim/issues/2974>`_)
- Fixed "repr is broken"
(`#2992 <https://github.com/Araq/Nim/issues/2992>`_)
- Fixed "Ipv6 devel - add IPv6 support for asyncsockets, make AF_INET6 a defau
lt"
- Fixed "Ipv6 devel - add IPv6 support for asyncsockets, make AF_INET6 a default"
(`#2976 <https://github.com/Araq/Nim/issues/2976>`_)
- Fixed "Compilation broken on windows"
(`#2996 <https://github.com/Araq/Nim/issues/2996>`_)
@@ -184,8 +191,7 @@ lt"
(`#2672 <https://github.com/Araq/Nim/issues/2672>`_)
- Fixed "Uncatched exception in async procedure on raise statement"
(`#3014 <https://github.com/Araq/Nim/issues/3014>`_)
- Fixed "nim doc2 fails in Mac OS X due to system.nim (possibly related to #18
98)"
- Fixed "nim doc2 fails in Mac OS X due to system.nim (possibly related to #1898)"
(`#3005 <https://github.com/Araq/Nim/issues/3005>`_)
- Fixed "IndexError when rebuilding Nim on iteration 2"
(`#3018 <https://github.com/Araq/Nim/issues/3018>`_)
@@ -233,8 +239,7 @@ lt"
(`#3054 <https://github.com/Araq/Nim/issues/3054>`_)
- Fixed "Wrong sharing of static_t instantations"
(`#3112 <https://github.com/Araq/Nim/issues/3112>`_)
- Fixed "Automatically generated proc conflicts with user-defined proc when .e
xportc.'ed"
- Fixed "Automatically generated proc conflicts with user-defined proc when .exportc.'ed"
(`#3134 <https://github.com/Araq/Nim/issues/3134>`_)
- Fixed "getTypeInfo call crashes nim"
(`#3099 <https://github.com/Araq/Nim/issues/3099>`_)
@@ -254,15 +259,13 @@ xportc.'ed"
(`#3149 <https://github.com/Araq/Nim/issues/3149>`_)
- Fixed "Inference of `static[T]` in sequences"
(`#3144 <https://github.com/Araq/Nim/issues/3144>`_)
- Fixed "Argument named "closure" to proc inside template interfere with closu
re pragma"
- Fixed "Argument named "closure" to proc inside template interfere with closure pragma"
(`#3171 <https://github.com/Araq/Nim/issues/3171>`_)
- Fixed "Internal error with aliasing inside template"
(`#3158 <https://github.com/Araq/Nim/issues/3158>`_)
- Fixed "Cardinality of sets prints unexpected value"
(`#3135 <https://github.com/Araq/Nim/issues/3135>`_)
- Fixed "Nim crashes on const assignment from function returning var ref objec
t"
- Fixed "Nim crashes on const assignment from function returning var ref object"
(`#3103 <https://github.com/Araq/Nim/issues/3103>`_)
- Fixed "`repr` cstring"
(`#3080 <https://github.com/Araq/Nim/issues/3080>`_)
@@ -270,8 +273,7 @@ t"
(`#3052 <https://github.com/Araq/Nim/issues/3052>`_)
- Fixed "Compiler assertion when evaluating template with static[T]"
(`#1858 <https://github.com/Araq/Nim/issues/1858>`_)
- Fixed "Erroneous overflow in iterators when compiler built with overflowChec
ks enabled"
- Fixed "Erroneous overflow in iterators when compiler built with overflowChecks enabled"
(`#3140 <https://github.com/Araq/Nim/issues/3140>`_)
- Fixed "Unicode dashes as "lisp'ish" alternative to hump and snake notation"
(`#2811 <https://github.com/Araq/Nim/issues/2811>`_)
@@ -283,8 +285,7 @@ ks enabled"
(`#3193 <https://github.com/Araq/Nim/issues/3193>`_)
- Fixed "VM crash when accessing array's element"
(`#3192 <https://github.com/Araq/Nim/issues/3192>`_)
- Fixed "Unexpected proc invoked when different modules add procs to a type fr
om a 3rd module"
- Fixed "Unexpected proc invoked when different modules add procs to a type from a 3rd module"
(`#2664 <https://github.com/Araq/Nim/issues/2664>`_)
- Fixed "Nim crashes on conditional declaration inside a template"
(`#2670 <https://github.com/Araq/Nim/issues/2670>`_)
@@ -292,8 +293,7 @@ om a 3rd module"
(`#2752 <https://github.com/Araq/Nim/issues/2752>`_)
- Fixed "VM: Cannot assign int value to ref variable"
(`#1329 <https://github.com/Araq/Nim/issues/1329>`_)
- Fixed "Incorrect code generated for tagged unions with enums not starting at
zero"
- Fixed "Incorrect code generated for tagged unions with enums not starting at zero"
(`#3096 <https://github.com/Araq/Nim/issues/3096>`_)
- Fixed "Compile time procs using forward declarations are silently ignored"
(`#3066 <https://github.com/Araq/Nim/issues/3066>`_)
@@ -301,8 +301,7 @@ om a 3rd module"
(`#1965 <https://github.com/Araq/Nim/issues/1965>`_)
- Fixed "os.getCreationTime is incorrect/impossible on Posix systems"
(`#1058 <https://github.com/Araq/Nim/issues/1058>`_)
- Fixed "Improve error message for osproc.startProcess when command does not e
xist"
- Fixed "Improve error message for osproc.startProcess when command does not exist"
(`#2183 <https://github.com/Araq/Nim/issues/2183>`_)
- Fixed "gctest segfaults with --gc:markandsweep on x86_64"
(`#2305 <https://github.com/Araq/Nim/issues/2305>`_)