Compare commits

...

33 Commits

Author SHA1 Message Date
flywind
7994556f38 don't use a temp for addr [backport: 1.6] (#19503)
* don't use a temp for addr

fix #19497

* Update compiler/ccgcalls.nim

Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>

* add a test

Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>
(cherry picked from commit 27e548140b)
2022-02-08 08:35:28 +01:00
flywind
8c9e88f520 disable nimlsp (#19499)
(cherry picked from commit 28180e47a9)
2022-02-07 19:50:59 +01:00
narimiran
7e52a57121 bump NimVersion to 1.6.4 2022-02-07 16:20:22 +01:00
flywind
35c812fda1 nvro don't touch cdecl types [backport: 1.6] (#19461)
* nvro don't touch cdecl types; fix #19342 again

(cherry picked from commit 0c3892c3c7)
2022-01-28 10:05:51 +01:00
rockcavera
47888c18f7 Update manual.rst (#19301)
(cherry picked from commit ef634cc251)
2022-01-26 18:30:56 +01:00
Andreas Rumpf
a8e040ec30 bugfix: varargs count as open arrays (#19447)
(cherry picked from commit 6ea6225523)
2022-01-26 07:57:21 +01:00
Hugo Granström
2fb1c80f42 change run command for numericalnim (#19448)
Now it makes runs the custom `nimCI` task that installs the external dependencies

(cherry picked from commit 4b723c0f53)
2022-01-25 13:12:41 +01:00
Andreas Rumpf
e1f3c74bdc RST: allow empty number-lines directives just like it was done for a decade; all my documents rely on this feature [backport (#19431)
(cherry picked from commit 15f54de5c4)
2022-01-23 08:14:23 +01:00
flywind
52d2ff601b enable weave (#19363) [backport:1.6]
* enable weave
* workaround CI

(cherry picked from commit 927fa890ec)
2022-01-20 18:06:44 +01:00
James
41b71487af Resolve cross file resolution errors in atomics (#19422) [backport:1.6]
* Resolve call undeclared routine testAndSet

* Fix undeclared field atomicType

(cherry picked from commit 851e515bba)
2022-01-20 18:06:35 +01:00
Tom
3d3b34473b Add noQuit option (#19419) [backport:1.6]
* Add noQuit option

* Add nim prefix in case of conflicts

Co-authored-by: flywind <xzsflywind@gmail.com>

Co-authored-by: flywind <xzsflywind@gmail.com>
(cherry picked from commit ce44cf03cc)
2022-01-20 18:06:26 +01:00
hlaaftana
fc0aec6f1b Optimize lent in JS [backport:1.6] (#19393)
* Optimize lent in JS [backport:1.6]

* addr on lent doesn't work anymore, don't use it

* use unsafeAddr  in test again for older versions

(cherry picked from commit 07c7a8a526)
2022-01-20 18:06:11 +01:00
flywind
7cafd22377 synchronize important_packages with devel 2022-01-17 11:23:51 +01:00
flywind
9aff19f51a mangle names in nimbase.h using cppDefine (#19395) [backport]
mangle names in nimbase.h
fix comments

(cherry picked from commit 4f6b59de96)
2022-01-17 11:16:29 +01:00
flywind
bc823b6487 nrvo shouldn't touch bycopy object[backport:1.2] (#19385)
fix nim-lang#19342

(cherry picked from commit 9b9ae8a487)
2022-01-17 07:38:58 +01:00
Leon
3d3d790c63 docs: Fix broken cross references to rfind in strutils (#19382) [backport]
Fixes three broken cross references to `rfind` in strutils.
Breakage due to signature changes of the `rfind` methods.

Co-authored-by: adigitoleo <adigitoleo@dissimulo.com>
(cherry picked from commit 5853303be0)
2022-01-17 07:38:51 +01:00
gecko
a90cabbe40 Fix remove on last node of singly-linked list [backport:1.6] (#19353)
(cherry picked from commit 955040f0f1)
2022-01-11 08:25:58 +01:00
Zachary Marquez
2539d7a862 fix nim-lang#19343 (#19344) [backport]
Ensure HttpClient onProgress is called once per second
Ensure that reported speed is accurate

(cherry picked from commit 58656aa5bb)
2022-01-11 08:25:42 +01:00
rockcavera
30737b3e7f Update net.nim (#19327) [backport]
(cherry picked from commit 5ec8b60942)
2022-01-11 08:25:20 +01:00
rockcavera
984691bb67 Fix #19314 - fixing broken DoublyLinkedList after adding empty DoublyLinkedList (#19315) [backport]
* Update lists.nim

* Update tlists.nim

(cherry picked from commit 526a32e169)
2022-01-11 08:21:16 +01:00
Andreas Rumpf
5f70b1ab53 fixes #16617 [backport] (#19300)
(cherry picked from commit ac37eed5a2)
2022-01-11 08:20:29 +01:00
rockcavera
afa4bc34b4 Fix #19297 - fixing broken list after adding empty list (#19299)
* Update lists.nim

* Update tlists.nim

* removed check `if b.tail != nil`

The tail of the list being null it is still possible to retrieve its end by going through all nodes from the head. So checking for null from `b.tail` is unnecessary. However, setting `a.tail = b.tail` only if `a.head != nil`, so you don't break a good list with an already broken one.

(cherry picked from commit dc5c88ca79)
2021-12-31 05:14:05 +01:00
Andreas Rumpf
0648cde117 fixes grammar typos [backport] (#19289)
(cherry picked from commit a61bbf7d8d)
2021-12-31 05:13:52 +01:00
Tomohiro
980ec713da Fix #19107 (#19286) [backport]
(cherry picked from commit fdbec969d8)
2021-12-31 05:13:46 +01:00
Jason Beetham
26ed4e5413 Fixed object field access of static objects in generics (#19283) [backport]
(cherry picked from commit fa96e56ad0)
2021-12-31 05:13:27 +01:00
Andreas Rumpf
161736ceb3 Revert "Update uri.nim (#19148) [backport:1.0]" (#19280)
This reverts commit a3ef5df680.

(cherry picked from commit 81d32cf7e5)
2021-12-31 05:13:22 +01:00
Jake Leahy
ce6fa79858 Extract runnables that specify doccmd (#19275) [backport:1.6]
(cherry picked from commit 4da7dbffc5)
2021-12-31 05:13:09 +01:00
Carlo Capocasa
f2e7e5d899 fix bug #14468 zero-width split (#19248) (#19269) 2021-12-20 13:10:51 +01:00
flywind
d4de5d32bc build testament in package CI (#19092)
* build testament in package CI

* Update testament/important_packages.nim

(cherry picked from commit b155864967)
2021-12-20 12:04:46 +01:00
xioren
efdb180f62 use uppercase "type" for Proxy-Authorization header (#19273)
Some servers will reject authorization requests with a lowercase "basic" type. Changing to "Basic" seems to solve these issues.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Proxy-Authorization
(cherry picked from commit b812431f83)
2021-12-20 09:42:03 +01:00
Constantine Molchanov
095202e218 Use testament to check Norm test pass (#19018)
* Use testament to check Norm test pass

This is what I actually use to test Norm, so it's better to use it.

This should not currently pass. This is expected because this is exactly the problem I want to highlight with this PR. My tests do indeed not pass at the moment.

* Remove clearNimblePath from testament command.

Co-authored-by: flywind <xzsflywind@gmail.com>
(cherry picked from commit b2edc3468c)
2021-12-19 09:19:57 +01:00
Don-Duong Quach
f4e41e6c4f Fixed typo in manual.rst unsafeAssign->uncheckedAssign. Fixes part 1 of #19266 (#19267)
(cherry picked from commit 610516e027)
2021-12-18 17:47:40 +01:00
narimiran
8aec198abc bump NimVersion to 1.6.3 2021-12-18 17:47:12 +01:00
41 changed files with 386 additions and 107 deletions

View File

@@ -11,6 +11,10 @@
## Standard library additions and changes
- `macros.parseExpr` and `macros.parseStmt` now accept an optional
filename argument for more informative errors.
- Module `colors` expanded with missing colors from the CSS color standard.
- Fixed `lists.SinglyLinkedList` being broken after removing the last node ([#19353](https://github.com/nim-lang/Nim/pull/19353)).
## Language changes

View File

@@ -501,7 +501,7 @@ type
nfHasComment # node has a comment
TNodeFlags* = set[TNodeFlag]
TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 43)
TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 45)
tfVarargs, # procedure has C styled varargs
# tyArray type represeting a varargs list
tfNoSideEffect, # procedure type does not allow side effects

View File

@@ -76,7 +76,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
# getUniqueType() is too expensive here:
var typ = skipTypes(ri[0].typ, abstractInst)
if typ[0] != nil:
if isInvalidReturnType(p.config, typ[0]):
if isInvalidReturnType(p.config, typ):
if params != nil: pl.add(~", ")
# beware of 'result = p(result)'. We may need to allocate a temporary:
if d.k in {locTemp, locNone} or not preventNrvo(p, le, ri):
@@ -376,8 +376,8 @@ proc genParams(p: BProc, ri: PNode, typ: PType): Rope =
if not needTmp[i - 1]:
needTmp[i - 1] = potentialAlias(n, potentialWrites)
getPotentialWrites(ri[i], false, potentialWrites)
if ri[i].kind == nkHiddenAddr:
# Optimization: don't use a temp, if we would only take the adress anyway
if ri[i].kind in {nkHiddenAddr, nkAddr}:
# Optimization: don't use a temp, if we would only take the address anyway
needTmp[i - 1] = false
for i in 1..<ri.len:
@@ -439,7 +439,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
let rawProc = getClosureType(p.module, typ, clHalf)
let canRaise = p.config.exc == excGoto and canRaiseDisp(p, ri[0])
if typ[0] != nil:
if isInvalidReturnType(p.config, typ[0]):
if isInvalidReturnType(p.config, typ):
if ri.len > 1: pl.add(~", ")
# beware of 'result = p(result)'. We may need to allocate a temporary:
if d.k in {locTemp, locNone} or not preventNrvo(p, le, ri):
@@ -737,7 +737,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
pl.add(~": ")
pl.add(genArg(p, ri[i], param, ri))
if typ[0] != nil:
if isInvalidReturnType(p.config, typ[0]):
if isInvalidReturnType(p.config, typ):
if ri.len > 1: pl.add(~" ")
# beware of 'result = p(result)'. We always allocate a temporary:
if d.k in {locTemp, locNone}:

View File

@@ -32,13 +32,20 @@ proc registerTraverseProc(p: BProc, v: PSym, traverseProc: Rope) =
"$n\t#nimRegisterGlobalMarker($1);$n$n", [traverseProc])
proc isAssignedImmediately(conf: ConfigRef; n: PNode): bool {.inline.} =
if n.kind == nkEmpty: return false
if isInvalidReturnType(conf, n.typ):
# var v = f()
# is transformed into: var v; f(addr v)
# where 'f' **does not** initialize the result!
return false
result = true
if n.kind == nkEmpty:
result = false
elif n.kind in nkCallKinds and n[0] != nil and n[0].typ != nil and n[0].typ.skipTypes(abstractInst).kind == tyProc:
if isInvalidReturnType(conf, n[0].typ, true):
# var v = f()
# is transformed into: var v; f(addr v)
# where 'f' **does not** initialize the result!
result = false
else:
result = true
elif isInvalidReturnType(conf, n.typ, false):
result = false
else:
result = true
proc inExceptBlockLen(p: BProc): int =
for x in p.nestedTryStmts:

View File

@@ -215,12 +215,18 @@ proc isObjLackingTypeField(typ: PType): bool {.inline.} =
result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and
(typ[0] == nil) or isPureObject(typ))
proc isInvalidReturnType(conf: ConfigRef; rettype: PType): bool =
proc isInvalidReturnType(conf: ConfigRef; typ: PType, isProc = true): bool =
# Arrays and sets cannot be returned by a C procedure, because C is
# such a poor programming language.
# We exclude records with refs too. This enhances efficiency and
# is necessary for proper code generation of assignments.
if rettype == nil or getSize(conf, rettype) > conf.target.floatSize*3:
var rettype = typ
var isAllowedCall = true
if isProc:
rettype = rettype[0]
isAllowedCall = typ.callConv in {ccClosure, ccInline, ccNimCall}
if rettype == nil or (isAllowedCall and
getSize(conf, rettype) > conf.target.floatSize*3):
result = true
else:
case mapType(conf, rettype, skResult)
@@ -257,11 +263,11 @@ proc addAbiCheck(m: BModule, t: PType, name: Rope) =
# see `testCodegenABICheck` for example error message it generates
proc fillResult(conf: ConfigRef; param: PNode) =
proc fillResult(conf: ConfigRef; param: PNode, proctype: PType) =
fillLoc(param.sym.loc, locParam, param, ~"Result",
OnStack)
let t = param.sym.typ
if mapReturnType(conf, t) != ctArray and isInvalidReturnType(conf, t):
if mapReturnType(conf, t) != ctArray and isInvalidReturnType(conf, proctype):
incl(param.sym.loc.flags, lfIndirect)
param.sym.loc.storage = OnUnknown
@@ -426,7 +432,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
check: var IntSet, declareEnvironment=true;
weakDep=false) =
params = nil
if t[0] == nil or isInvalidReturnType(m.config, t[0]):
if t[0] == nil or isInvalidReturnType(m.config, t):
rettype = ~"void"
else:
rettype = getTypeDescAux(m, t[0], check, skResult)
@@ -461,7 +467,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
params.addf(", NI $1Len_$2", [param.loc.r, j.rope])
inc(j)
arr = arr[0].skipTypes({tySink})
if t[0] != nil and isInvalidReturnType(m.config, t[0]):
if t[0] != nil and isInvalidReturnType(m.config, t):
var arr = t[0]
if params != nil: params.add(", ")
if mapReturnType(m.config, t[0]) != ctArray:

View File

@@ -48,8 +48,13 @@ proc addForwardedProc(m: BModule, prc: PSym) =
m.g.forwardedProcs.add(prc)
proc findPendingModule(m: BModule, s: PSym): BModule =
let ms = s.itemId.module #getModule(s)
result = m.g.modules[ms]
# TODO fixme
if m.config.symbolFiles == v2Sf:
let ms = s.itemId.module #getModule(s)
result = m.g.modules[ms]
else:
var ms = getModule(s)
result = m.g.modules[ms.position]
proc initLoc(result: var TLoc, k: TLocKind, lode: PNode, s: TStorageLoc) =
result.k = k
@@ -1034,7 +1039,7 @@ proc genProcAux(m: BModule, prc: PSym) =
internalError(m.config, prc.info, "proc has no result symbol")
let resNode = prc.ast[resultPos]
let res = resNode.sym # get result symbol
if not isInvalidReturnType(m.config, prc.typ[0]):
if not isInvalidReturnType(m.config, prc.typ):
if sfNoInit in prc.flags: incl(res.flags, sfNoInit)
if sfNoInit in prc.flags and p.module.compileToCpp and (let val = easyResultAsgn(procBody); val != nil):
var decl = localVarDecl(p, resNode)
@@ -1048,7 +1053,7 @@ proc genProcAux(m: BModule, prc: PSym) =
initLocalVar(p, res, immediateAsgn=false)
returnStmt = ropecg(p.module, "\treturn $1;$n", [rdLoc(res.loc)])
else:
fillResult(p.config, resNode)
fillResult(p.config, resNode, prc.typ)
assignParam(p, res, prc.typ[0])
# We simplify 'unsureAsgn(result, nil); unsureAsgn(result, x)'
# to 'unsureAsgn(result, x)'

View File

@@ -178,7 +178,7 @@ const
proc mapType(typ: PType): TJSTypeKind =
let t = skipTypes(typ, abstractInst)
case t.kind
of tyVar, tyRef, tyPtr, tyLent:
of tyVar, tyRef, tyPtr:
if skipTypes(t.lastSon, abstractInst).kind in MappedToObject:
result = etyObject
else:
@@ -186,7 +186,8 @@ proc mapType(typ: PType): TJSTypeKind =
of tyPointer:
# treat a tyPointer like a typed pointer to an array of bytes
result = etyBaseIndex
of tyRange, tyDistinct, tyOrdinal, tyProxy:
of tyRange, tyDistinct, tyOrdinal, tyProxy, tyLent:
# tyLent is no-op as JS has pass-by-reference semantics
result = mapType(t[0])
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
of tyBool: result = etyBool
@@ -1060,14 +1061,14 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
xtyp = etySeq
case xtyp
of etySeq:
if (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
if x.typ.kind in {tyVar, tyLent} or (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
else:
useMagic(p, "nimCopy")
lineF(p, "$1 = nimCopy(null, $2, $3);$n",
[a.rdLoc, b.res, genTypeInfo(p, y.typ)])
of etyObject:
if x.typ.kind in {tyVar} or (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
if x.typ.kind in {tyVar, tyLent} or (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
else:
useMagic(p, "nimCopy")
@@ -1092,10 +1093,18 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
lineF(p, "$# = [$#, $#];$n", [a.res, b.address, b.res])
lineF(p, "$1 = $2;$n", [a.address, b.res])
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
elif a.typ == etyBaseIndex:
# array indexing may not map to var type
if b.address != nil:
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
else:
lineF(p, "$1 = $2;$n", [a.address, b.res])
else:
internalError(p.config, x.info, $("genAsgn", b.typ, a.typ))
else:
elif b.address != nil:
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
else:
lineF(p, "$1 = $2;$n", [a.address, b.res])
else:
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
@@ -1442,13 +1451,17 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) =
else:
if s.loc.r == nil:
internalError(p.config, n.info, "symbol has no generated name: " & s.name.s)
r.res = s.loc.r
if mapType(p, s.typ) == etyBaseIndex:
r.address = s.loc.r
r.res = s.loc.r & "_Idx"
else:
r.res = s.loc.r
r.kind = resVal
proc genDeref(p: PProc, n: PNode, r: var TCompRes) =
let it = n[0]
let t = mapType(p, it.typ)
if t == etyObject:
if t == etyObject or it.typ.kind == tyLent:
gen(p, it, r)
else:
var a: TCompRes
@@ -1689,7 +1702,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
result = putToSeq("0", indirect)
of tyFloat..tyFloat128:
result = putToSeq("0.0", indirect)
of tyRange, tyGenericInst, tyAlias, tySink, tyOwned:
of tyRange, tyGenericInst, tyAlias, tySink, tyOwned, tyLent:
result = createVar(p, lastSon(typ), indirect)
of tySet:
result = putToSeq("{}", indirect)
@@ -1731,7 +1744,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
createObjInitList(p, t, initIntSet(), initList)
result = ("({$1})") % [initList]
if indirect: result = "[$1]" % [result]
of tyVar, tyPtr, tyLent, tyRef, tyPointer:
of tyVar, tyPtr, tyRef, tyPointer:
if mapType(p, t) == etyBaseIndex:
result = putToSeq("[null, 0]", indirect)
else:
@@ -2380,16 +2393,17 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
if prc.typ[0] != nil and sfPure notin prc.flags:
resultSym = prc.ast[resultPos].sym
let mname = mangleName(p.module, resultSym)
if not isIndirect(resultSym) and
let returnAddress = not isIndirect(resultSym) and
resultSym.typ.kind in {tyVar, tyPtr, tyLent, tyRef, tyOwned} and
mapType(p, resultSym.typ) == etyBaseIndex:
mapType(p, resultSym.typ) == etyBaseIndex
if returnAddress:
resultAsgn = p.indentLine(("var $# = null;$n") % [mname])
resultAsgn.add p.indentLine("var $#_Idx = 0;$n" % [mname])
else:
let resVar = createVar(p, resultSym.typ, isIndirect(resultSym))
resultAsgn = p.indentLine(("var $# = $#;$n") % [mname, resVar])
gen(p, prc.ast[resultPos], a)
if mapType(p, resultSym.typ) == etyBaseIndex:
if returnAddress:
returnStmt = "return [$#, $#];$n" % [a.address, a.res]
else:
returnStmt = "return $#;$n" % [a.res]
@@ -2565,8 +2579,15 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
of nkObjConstr: genObjConstr(p, n, r)
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, r)
of nkAddr, nkHiddenAddr:
genAddr(p, n, r)
of nkDerefExpr, nkHiddenDeref: genDeref(p, n, r)
if n.typ.kind in {tyLent}:
gen(p, n[0], r)
else:
genAddr(p, n, r)
of nkDerefExpr, nkHiddenDeref:
if n.typ.kind in {tyLent}:
gen(p, n[0], r)
else:
genDeref(p, n, r)
of nkBracketExpr: genArrayAccess(p, n, r)
of nkDotExpr: genFieldAccess(p, n, r)
of nkCheckedFieldExpr: genCheckedFieldOp(p, n, nil, r)

View File

@@ -582,10 +582,10 @@ proc parsePar(p: var Parser): PNode =
#| | 'finally' | 'except' | 'for' | 'block' | 'const' | 'let'
#| | 'when' | 'var' | 'mixin'
#| par = '(' optInd
#| ( &parKeyw (ifExpr \ complexOrSimpleStmt) ^+ ';'
#| | ';' (ifExpr \ complexOrSimpleStmt) ^+ ';'
#| ( &parKeyw (ifExpr / complexOrSimpleStmt) ^+ ';'
#| | ';' (ifExpr / complexOrSimpleStmt) ^+ ';'
#| | pragmaStmt
#| | simpleExpr ( ('=' expr (';' (ifExpr \ complexOrSimpleStmt) ^+ ';' )? )
#| | simpleExpr ( ('=' expr (';' (ifExpr / complexOrSimpleStmt) ^+ ';' )? )
#| | (':' expr (',' exprColonEqExpr ^+ ',' )? ) ) )
#| optPar ')'
#

View File

@@ -1414,7 +1414,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass:
ty = ty.lastSon
ty = skipTypes(ty, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyOwned, tyAlias, tySink})
ty = skipTypes(ty, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyOwned, tyAlias, tySink, tyStatic})
while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct, tyGenericInst, tyAlias})
var check: PNode = nil
if ty.kind == tyObject:

View File

@@ -2075,6 +2075,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
incl(s.flags, sfWasForwarded)
elif sfBorrow in s.flags: semBorrow(c, n, s)
sideEffectsCheck(c, s)
closeScope(c) # close scope for parameters
# c.currentScope = oldScope
popOwner(c)

View File

@@ -57,6 +57,8 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
of tyVar, tyLent:
if kind in {skProc, skFunc, skConst} and (views notin c.features):
result = t
elif taIsOpenArray in flags:
result = t
elif t.kind == tyLent and ((kind != skResult and views notin c.features) or
kind == skParam): # lent can't be used as parameters.
result = t
@@ -231,7 +233,7 @@ proc classifyViewTypeAux(marker: var IntSet, t: PType): ViewTypeKind =
case t.kind
of tyVar:
result = mutableView
of tyLent, tyOpenArray:
of tyLent, tyOpenArray, tyVarargs:
result = immutableView
of tyGenericInst, tyDistinct, tyAlias, tyInferred, tySink, tyOwned,
tyUncheckedArray, tySequence, tyArray, tyRef, tyStatic:

View File

@@ -3,6 +3,11 @@
cppDefine "errno"
cppDefine "unix"
# mangle the macro names in nimbase.h
cppDefine "NAN_INFINITY"
cppDefine "INF"
cppDefine "NAN"
when defined(nimStrictMode):
# xxx add more flags here, and use `-d:nimStrictMode` in more contexts in CI.

View File

@@ -37,10 +37,10 @@ parKeyw = 'discard' | 'include' | 'if' | 'while' | 'case' | 'try'
| 'finally' | 'except' | 'for' | 'block' | 'const' | 'let'
| 'when' | 'var' | 'mixin'
par = '(' optInd
( &parKeyw (ifExpr \ complexOrSimpleStmt) ^+ ';'
| ';' (ifExpr \ complexOrSimpleStmt) ^+ ';'
( &parKeyw (ifExpr / complexOrSimpleStmt) ^+ ';'
| ';' (ifExpr / complexOrSimpleStmt) ^+ ';'
| pragmaStmt
| simpleExpr ( ('=' expr (';' (ifExpr \ complexOrSimpleStmt) ^+ ';' )? )
| simpleExpr ( ('=' expr (';' (ifExpr / complexOrSimpleStmt) ^+ ';' )? )
| (':' expr (',' exprColonEqExpr ^+ ',' )? ) ) )
optPar ')'
literal = | INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT

View File

@@ -1899,7 +1899,7 @@ A small example:
cast uncheckedAssign
--------------------
Some restrictions for case objects can be disabled via a `{.cast(unsafeAssign).}` section:
Some restrictions for case objects can be disabled via a `{.cast(uncheckedAssign).}` section:
.. code-block:: nim
:test: "nim c $1"
@@ -5002,7 +5002,7 @@ be used:
See also:
- `Shared heap memory management <gc.html>`_.
- `Shared heap memory management <mm.html>`_.

View File

@@ -559,7 +559,8 @@ proc runCI(cmd: string) =
let batchParam = "--batch:$1" % "NIM_TESTAMENT_BATCH".getEnv("_")
if getEnv("NIM_TEST_PACKAGES", "0") == "1":
execFold("Test selected Nimble packages", "nim r testament/testament $# pcat nimble-packages" % batchParam)
nimCompileFold("Compile testament", "testament/testament.nim", options = "-d:release")
execFold("Test selected Nimble packages", "testament $# pcat nimble-packages" % batchParam)
else:
buildTools()

View File

@@ -1718,8 +1718,8 @@ proc extractDocCommentsAndRunnables*(n: NimNode): NimNode =
case ni.kind
of nnkCommentStmt:
result.add ni
of nnkCall:
if ni[0].kind == nnkIdent and ni[0].strVal == "runnableExamples":
of nnkCall, nnkCommand:
if ni[0].kind == nnkIdent and ni[0].eqIdent "runnableExamples":
result.add ni
else: break
else: break

View File

@@ -522,19 +522,22 @@ iterator split*(s: string, sep: Regex; maxsplit = -1): string =
@["", "this", "is", "an", "example", ""]
var last = 0
var splits = maxsplit
var x: int
var x = -1
if len(s) == 0:
last = 1
if matchLen(s, sep, 0) == 0:
x = 0
while last <= len(s):
var first = last
var sepLen = 1
if x == 0:
inc(last)
while last < len(s):
x = matchLen(s, sep, last)
if x >= 0:
sepLen = x
break
inc(last)
if x == 0:
if last >= len(s): break
inc last
if splits == 0: last = len(s)
yield substr(s, first, last-1)
if splits == 0: break

View File

@@ -927,7 +927,8 @@ proc getField1Int(d: PDoc, n: PRstNode, fieldName: string): int =
let nChars = parseInt(value, number)
if nChars == 0:
if value.len == 0:
err("field $1 requires an argument" % [fieldName])
# use a good default value:
result = 1
else:
err("field $1 requires an integer, but '$2' was given" %
[fieldName, value])

View File

@@ -531,11 +531,12 @@ proc addMoved*[T](a, b: var SinglyLinkedList[T]) {.since: (1, 5, 1).} =
ci
assert s == [0, 1, 0, 1, 0, 1]
if a.tail != nil:
a.tail.next = b.head
a.tail = b.tail
if a.head == nil:
a.head = b.head
if b.head != nil:
if a.head == nil:
a.head = b.head
else:
a.tail.next = b.head
a.tail = b.tail
if a.addr != b.addr:
b.head = nil
b.tail = nil
@@ -675,12 +676,12 @@ proc addMoved*[T](a, b: var DoublyLinkedList[T]) {.since: (1, 5, 1).} =
assert s == [0, 1, 0, 1, 0, 1]
if b.head != nil:
b.head.prev = a.tail
if a.tail != nil:
a.tail.next = b.head
a.tail = b.tail
if a.head == nil:
a.head = b.head
if a.head == nil:
a.head = b.head
else:
b.head.prev = a.tail
a.tail.next = b.head
a.tail = b.tail
if a.addr != b.addr:
b.head = nil
b.tail = nil
@@ -739,6 +740,8 @@ proc remove*[T](L: var SinglyLinkedList[T], n: SinglyLinkedNode[T]): bool {.disc
if prev.next == nil:
return false
prev.next = n.next
if L.tail == n:
L.tail = prev # update tail if we removed the last node
true
proc remove*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) =

View File

@@ -293,19 +293,16 @@ else:
AtomicInt32 {.importc: "_Atomic NI32".} = int32
AtomicInt64 {.importc: "_Atomic NI64".} = int64
template atomicType*(T: typedesc[Trivial]): untyped =
# Maps the size of a trivial type to it's internal atomic type
when sizeof(T) == 1: AtomicInt8
elif sizeof(T) == 2: AtomicInt16
elif sizeof(T) == 4: AtomicInt32
elif sizeof(T) == 8: AtomicInt64
type
AtomicFlag* {.importc: "atomic_flag", size: 1.} = object
Atomic*[T] = object
when T is Trivial:
value: T.atomicType
# Maps the size of a trivial type to it's internal atomic type
when sizeof(T) == 1: value: AtomicInt8
elif sizeof(T) == 2: value: AtomicInt16
elif sizeof(T) == 4: value: AtomicInt32
elif sizeof(T) == 8: value: AtomicInt64
else:
nonAtomicValue: T
guard: AtomicFlag
@@ -364,11 +361,11 @@ else:
cast[T](atomic_fetch_xor_explicit(addr(location.value), cast[nonAtomicType(T)](value), order))
template withLock[T: not Trivial](location: var Atomic[T]; order: MemoryOrder; body: untyped): untyped =
while location.guard.testAndSet(moAcquire): discard
while testAndSet(location.guard, moAcquire): discard
try:
body
finally:
location.guard.clear(moRelease)
clear(location.guard, moRelease)
proc load*[T: not Trivial](location: var Atomic[T]; order: MemoryOrder = moSequentiallyConsistent): T {.inline.} =
withLock(location, order):

View File

@@ -523,7 +523,7 @@ proc generateHeaders(requestUrl: Uri, httpMethod: HttpMethod, headers: HttpHeade
# Proxy auth header.
if not proxy.isNil and proxy.auth != "":
let auth = base64.encode(proxy.auth)
add(result, "Proxy-Authorization: basic " & auth & httpNewLine)
add(result, "Proxy-Authorization: Basic " & auth & httpNewLine)
for key, val in headers:
add(result, key & ": " & val & httpNewLine)
@@ -673,7 +673,7 @@ proc reportProgress(client: HttpClient | AsyncHttpClient,
progress: BiggestInt) {.multisync.} =
client.contentProgress += progress
client.oneSecondProgress += progress
if (getMonoTime() - client.lastProgressReport).inSeconds > 1:
if (getMonoTime() - client.lastProgressReport).inSeconds >= 1:
if not client.onProgressChanged.isNil:
await client.onProgressChanged(client.contentTotal,
client.contentProgress,

View File

@@ -1618,7 +1618,7 @@ proc recvFrom*(socket: Socket, data: var string, length: int,
## used. Therefore if `socket` contains something in its buffer this
## function will make no effort to return it.
template adaptRecvFromToDomain(domain: Domain) =
var addrLen = sizeof(sockAddress).SockLen
var addrLen = SockLen(sizeof(sockAddress))
result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint,
cast[ptr SockAddr](addr(sockAddress)), addr(addrLen))

View File

@@ -574,6 +574,9 @@ template formatValue(result: var string; value: cstring; specifier: string) =
result.add value
proc strformatImpl(f: string; openChar, closeChar: char): NimNode =
template missingCloseChar =
error("invalid format string: missing closing character '" & closeChar & "'")
if openChar == ':' or closeChar == ':':
error "openChar and closeChar must not be ':'"
var i = 0
@@ -618,6 +621,8 @@ proc strformatImpl(f: string; openChar, closeChar: char): NimNode =
let start = i
inc i
i += f.skipWhitespace(i)
if i == f.len:
missingCloseChar
if f[i] == closeChar or f[i] == ':':
result.add newCall(bindSym"add", res, newLit(subexpr & f[start ..< i]))
else:
@@ -627,6 +632,9 @@ proc strformatImpl(f: string; openChar, closeChar: char): NimNode =
subexpr.add f[i]
inc i
if i == f.len:
missingCloseChar
var x: NimNode
try:
x = parseExpr(subexpr)
@@ -639,10 +647,10 @@ proc strformatImpl(f: string; openChar, closeChar: char): NimNode =
while i < f.len and f[i] != closeChar:
options.add f[i]
inc i
if i == f.len:
missingCloseChar
if f[i] == closeChar:
inc i
else:
doAssert false, "invalid format string: missing '}'"
result.add newCall(formatSym, res, x, newLit(options))
elif f[i] == closeChar:
if i<f.len-1 and f[i+1] == closeChar:

View File

@@ -1859,7 +1859,7 @@ func find*(s: string, sub: char, start: Natural = 0, last = 0): int {.rtl,
## Use `s[start..last].rfind` for a `start`-origin index.
##
## See also:
## * `rfind func<#rfind,string,char,Natural>`_
## * `rfind func<#rfind,string,char,Natural,int>`_
## * `replace func<#replace,string,char,char>`_
let last = if last == 0: s.high else: last
when nimvm:
@@ -1887,7 +1887,7 @@ func find*(s: string, chars: set[char], start: Natural = 0, last = 0): int {.
## Use `s[start..last].find` for a `start`-origin index.
##
## See also:
## * `rfind func<#rfind,string,set[char],Natural>`_
## * `rfind func<#rfind,string,set[char],Natural,int>`_
## * `multiReplace func<#multiReplace,string,varargs[]>`_
let last = if last == 0: s.high else: last
for i in int(start)..last:
@@ -1904,7 +1904,7 @@ func find*(s, sub: string, start: Natural = 0, last = 0): int {.rtl,
## Use `s[start..last].find` for a `start`-origin index.
##
## See also:
## * `rfind func<#rfind,string,string,Natural>`_
## * `rfind func<#rfind,string,string,Natural,int>`_
## * `replace func<#replace,string,string,string>`_
if sub.len > s.len - start: return -1
if sub.len == 1: return find(s, sub[0], start, last)

View File

@@ -216,8 +216,6 @@ func parseAuthority(authority: string, result: var Uri) =
result.isIpv6 = true
of ']':
inIPv6 = false
of '\0':
break
else:
if inPort:
result.port.add(authority[i])

View File

@@ -1189,8 +1189,8 @@ proc align(address, alignment: int): int =
else:
result = (address + (alignment - 1)) and not (alignment - 1)
when defined(nimdoc):
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn.}
when defined(nimNoQuit):
proc quit*(errorcode: int = QuitSuccess) = discard "ignoring quit"
## Stops the program immediately with an exit code.
##
## Before stopping the program the "exit procedures" are called in the
@@ -1214,6 +1214,9 @@ when defined(nimdoc):
## It does *not* call the garbage collector to free all the memory,
## unless an `addExitProc` proc calls `GC_fullCollect <#GC_fullCollect>`_.
elif defined(nimdoc):
proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn.}
elif defined(genode):
include genode/env
@@ -2125,7 +2128,7 @@ const
## is the minor number of Nim's version.
## Odd for devel, even for releases.
NimPatch* {.intdefine.}: int = 2
NimPatch* {.intdefine.}: int = 4
## is the patch number of Nim's version.
## Odd for devel, even for releases.

View File

@@ -35,7 +35,7 @@ proc pkg(name: string; cmd = "nimble test"; url = "", useHead = true, allowFailu
pkg "alea", allowFailure = true
pkg "argparse"
pkg "arraymancer", "nim c tests/tests_cpu.nim", allowFailure = true
pkg "arraymancer", "nim c tests/tests_cpu.nim"
pkg "ast_pattern_matching", "nim c -r --oldgensym:on tests/test1.nim", allowFailure = true
pkg "asyncthreadpool"
pkg "awk"
@@ -55,7 +55,7 @@ pkg "chronos", "nim c -r -d:release tests/testall"
pkg "cligen", "nim c --path:. -r cligen.nim"
pkg "combparser", "nimble test --gc:orc"
pkg "compactdict"
pkg "comprehension", "nimble test", "https://github.com/alehander42/comprehension"
pkg "comprehension", "nimble test", "https://github.com/alehander92/comprehension"
pkg "criterion", allowFailure = true # pending https://github.com/disruptek/criterion/issues/3 (wrongly closed)
pkg "datamancer"
pkg "dashing", "nim c tests/functional.nim"
@@ -63,8 +63,8 @@ pkg "delaunay"
pkg "docopt"
pkg "easygl", "nim c -o:egl -r src/easygl.nim", "https://github.com/jackmott/easygl"
pkg "elvis"
pkg "fidget", allowFailure = true
pkg "fragments", "nim c -r fragments/dsl.nim"
pkg "fidget"
pkg "fragments", "nim c -r fragments/dsl.nim", allowFailure = true # pending https://github.com/nim-lang/packages/issues/2115
pkg "fusion"
pkg "gara"
pkg "glob"
@@ -91,7 +91,7 @@ pkg "memo"
pkg "msgpack4nim", "nim c -r tests/test_spec.nim"
pkg "nake", "nim c nakefile.nim"
pkg "neo", "nim c -d:blas=openblas tests/all.nim"
pkg "nesm", "nimble tests", allowFailure = true # notice plural 'tests'
pkg "nesm", "nimble tests" # notice plural 'tests'
pkg "netty"
pkg "nico", allowFailure = true
pkg "nicy", "nim c -r src/nicy.nim"
@@ -103,7 +103,7 @@ pkg "nimfp", "nim c -o:nfp -r src/fp.nim"
pkg "nimgame2", "nim c -d:nimLegacyConvEnumEnum nimgame2/nimgame.nim"
# XXX Doesn't work with deprecated 'randomize', will create a PR.
pkg "nimgen", "nim c -o:nimgenn -r src/nimgen/runcfg.nim"
pkg "nimlsp"
pkg "nimlsp", allowFailure = true
pkg "nimly", "nim c -r tests/test_readme_example.nim"
pkg "nimongo", "nimble test_ci", allowFailure = true
pkg "nimph", "nimble test", "https://github.com/disruptek/nimph", allowFailure = true
@@ -115,9 +115,9 @@ pkg "nimterop", "nimble minitest"
pkg "nimwc", "nim c nimwc.nim"
pkg "nimx", "nim c --threads:on test/main.nim", allowFailure = true
pkg "nitter", "nim c src/nitter.nim", "https://github.com/zedeus/nitter"
pkg "norm", "nim c -r tests/sqlite/trows.nim"
pkg "norm", "testament r tests/sqlite/trows.nim"
pkg "npeg", "nimble testarc"
pkg "numericalnim", "nim c -r tests/test_integrate.nim"
pkg "numericalnim", "nimble nimCI"
pkg "optionsutils"
pkg "ormin", "nim c -o:orminn ormin.nim"
pkg "parsetoml"
@@ -157,7 +157,7 @@ pkg "tiny_sqlite"
pkg "unicodedb", "nim c -d:release -r tests/tests.nim"
pkg "unicodeplus", "nim c -d:release -r tests/tests.nim"
pkg "unpack"
pkg "weave", "nimble test_gc_arc", allowFailure = true
pkg "weave", "nimble test_gc_arc"
pkg "websocket", "nim c websocket.nim"
pkg "winim", "nim c winim.nim"
pkg "with"

View File

@@ -103,7 +103,7 @@ type
proc getCmd*(s: TSpec): string =
if s.cmd.len == 0:
result = compilerPrefix & " $target --hints:on -d:testing --clearNimblePath --nimblePath:build/deps/pkgs $options $file"
result = compilerPrefix & " $target --hints:on -d:testing --nimblePath:build/deps/pkgs $options $file"
else:
result = s.cmd

22
tests/arc/tarc_orc.nim Normal file
View File

@@ -0,0 +1,22 @@
discard """
matrix: "--mm:arc; --mm:orc"
"""
block:
type
PublicKey = array[32, uint8]
PrivateKey = array[64, uint8]
proc ed25519_create_keypair(publicKey: ptr PublicKey; privateKey: ptr PrivateKey) =
publicKey[][0] = uint8(88)
type
KeyPair = object
public: PublicKey
private: PrivateKey
proc initKeyPair(): KeyPair =
ed25519_create_keypair(result.public.addr, result.private.addr)
let keys = initKeyPair()
doAssert keys.public[0] == 88

16
tests/ccgbugs/tmangle.nim Normal file
View File

@@ -0,0 +1,16 @@
block:
proc hello() =
let NAN_INFINITY = 12
doAssert NAN_INFINITY == 12
let INF = "2.0"
doAssert INF == "2.0"
let NAN = 2.3
doAssert NAN == 2.3
hello()
block:
proc hello(NAN: float) =
doAssert NAN == 2.0
hello(2.0)

33
tests/js/tlent.nim Normal file
View File

@@ -0,0 +1,33 @@
discard """
output: '''
hmm
100
hmm
100
'''
"""
# #16800
type A = object
b: int
var t = A(b: 100)
block:
proc getValues: lent int =
echo "hmm"
result = t.b
echo getValues()
block:
proc getValues: lent int =
echo "hmm"
t.b
echo getValues()
when false: # still an issue, #16908
template main =
iterator fn[T](a:T): lent T = yield a
let a = @[10]
for b in fn(a): echo b
static: main()
main()

View File

@@ -17,22 +17,26 @@ proc main =
main()
template main2 = # bug #15958
when defined(js):
proc sameAddress[T](a, b: T): bool {.importjs: "(# === #)".}
else:
template sameAddress(a, b): bool = a.unsafeAddr == b.unsafeAddr
proc byLent[T](a: T): lent T = a
let a = [11,12]
let b = @[21,23]
let ss = {1, 2, 3, 5}
doAssert byLent(a) == [11,12]
doAssert byLent(a).unsafeAddr == a.unsafeAddr
doAssert sameAddress(byLent(a), a)
doAssert byLent(b) == @[21,23]
when not defined(js): # pending bug #16073
doAssert byLent(b).unsafeAddr == b.unsafeAddr
# bug #16073
doAssert sameAddress(byLent(b), b)
doAssert byLent(ss) == {1, 2, 3, 5}
doAssert byLent(ss).unsafeAddr == ss.unsafeAddr
doAssert sameAddress(byLent(ss), ss)
let r = new(float)
r[] = 10.0
when not defined(js): # pending bug #16073
doAssert byLent(r)[] == 10.0
# bug #16073
doAssert byLent(r)[] == 10.0
when not defined(js): # pending bug https://github.com/timotheecour/Nim/issues/372
let p = create(float)
@@ -41,9 +45,9 @@ template main2 = # bug #15958
proc byLent2[T](a: openarray[T]): lent T = a[0]
doAssert byLent2(a) == 11
doAssert byLent2(a).unsafeAddr == a[0].unsafeAddr
doAssert sameAddress(byLent2(a), a[0])
doAssert byLent2(b) == 21
doAssert byLent2(b).unsafeAddr == b[0].unsafeAddr
doAssert sameAddress(byLent2(b), b[0])
proc byLent3[T](a: varargs[T]): lent T = a[1]
let

12
tests/objects/m19342.c Normal file
View File

@@ -0,0 +1,12 @@
struct Node
{
int data[25];
};
struct Node hello(int name) {
struct Node x = {999, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 1, 2, 3, 4, 5, 6, 7 ,8, 9,
1, 2, 3, 4, 5};
return x;
}

18
tests/objects/t19342.nim Normal file
View File

@@ -0,0 +1,18 @@
discard """
targets: "c cpp"
"""
{.compile: "m19342.c".}
# bug #19342
type
Node* {.bycopy.} = object
data: array[25, cint]
proc myproc(name: cint): Node {.importc: "hello", cdecl.}
proc parse =
let node = myproc(10)
doAssert node.data[0] == 999
parse()

View File

@@ -0,0 +1,18 @@
discard """
targets: "c cpp"
"""
{.compile: "m19342.c".}
# bug #19342
type
Node* {.byRef.} = object
data: array[25, cint]
proc myproc(name: cint): Node {.importc: "hello", cdecl.}
proc parse =
let node = myproc(10)
doAssert node.data[0] == 999
parse()

View File

@@ -0,0 +1,9 @@
import atomics
type
AtomicWithGeneric*[T] = object
value: Atomic[T]
proc initAtomicWithGeneric*[T](value: T): AtomicWithGeneric[T] =
result.value.store(value)

View File

@@ -0,0 +1,11 @@
import atomicSample
block crossFileObjectContainingAGenericWithAComplexObject:
discard initAtomicWithGeneric[string]("foo")
block crossFileObjectContainingAGenericWithAnInteger:
discard initAtomicWithGeneric[int](1)
discard initAtomicWithGeneric[int8](1)
discard initAtomicWithGeneric[int16](1)
discard initAtomicWithGeneric[int32](1)
discard initAtomicWithGeneric[int64](1)

View File

@@ -233,6 +233,43 @@ template main =
doAssert l.toSeq == [1]
doAssert l.remove(l.head) == true
doAssert l.toSeq == []
block issue19297: # add (appends a shallow copy)
var a: SinglyLinkedList[int]
var b: SinglyLinkedList[int]
doAssert a.toSeq == @[]
a.add(1)
doAssert a.toSeq == @[1]
a.add(b)
doAssert a.toSeq == @[1]
a.add(2)
doAssert a.toSeq == @[1, 2]
block issue19314: # add (appends a shallow copy)
var a: DoublyLinkedList[int]
var b: DoublyLinkedList[int]
doAssert a.toSeq == @[]
a.add(1)
doAssert a.toSeq == @[1]
a.add(b)
doAssert a.toSeq == @[1]
a.add(2)
doAssert a.toSeq == @[1, 2]
block RemoveLastNodeFromSinglyLinkedList:
var list = initSinglyLinkedList[string]()
let n1 = newSinglyLinkedNode("sonic")
let n2 = newSinglyLinkedNode("the")
let n3 = newSinglyLinkedNode("tiger")
let n4 = newSinglyLinkedNode("hedgehog")
list.add(n1)
list.add(n2)
list.add(n3)
list.remove(n3)
list.add(n4)
doAssert list.toSeq == @["sonic", "the", "hedgehog"]
static: main()
main()

View File

@@ -66,3 +66,23 @@ block: # unpackVarargs
doAssert call1(toString) == ""
doAssert call1(toString, 10) == "10"
doAssert call1(toString, 10, 11) == "1011"
block: # extractDocCommentsAndRunnables
macro checkRunnables(prc: untyped) =
let runnables = prc.body.extractDocCommentsAndRunnables()
doAssert runnables[0][0].eqIdent("runnableExamples")
macro checkComments(comment: static[string], prc: untyped) =
let comments = prc.body.extractDocCommentsAndRunnables()
doAssert comments[0].strVal == comment
proc a() {.checkRunnables.} =
runnableExamples: discard
discard
proc b() {.checkRunnables.} =
runnableExamples "-d:ssl": discard
discard
proc c() {.checkComments("Hello world").} =
## Hello world

View File

@@ -108,4 +108,10 @@ proc testAll() =
doAssert replace("foo", re"", "-") == "-f-o-o-"
doAssert replace("ooo", re"o", "-") == "---"
block: # bug #14468
accum = @[]
for word in split("this is an example", re"\b"):
accum.add(word)
doAssert(accum == @["this", " ", "is", " ", "an", " ", "example"])
testAll()

View File

@@ -44,6 +44,14 @@ template main() =
proc parseInt(f: static[bool]): int {.used.} = discard
doAssert "123".parseInt == 123
block:
type
MyType = object
field: float32
AType[T: static MyType] = distinct range[0f32 .. T.field]
var a: AType[MyType(field: 5f32)]
proc n(S: static Slice[int]): range[S.a..S.b] = discard
assert typeof(n 1..2) is range[1..2]
static: main()