mirror of
https://github.com/nim-lang/Nim.git
synced 2026-09-01 11:23:40 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82f3a57612 | ||
|
|
7e589bcbe4 | ||
|
|
dbed9310ba | ||
|
|
9524edec60 | ||
|
|
574db65396 | ||
|
|
e2bf3a6f70 | ||
|
|
6f2dbc105e | ||
|
|
63151568b4 | ||
|
|
4610c2b314 | ||
|
|
d01002d8f8 | ||
|
|
bc2fa6fe32 | ||
|
|
41637db18f | ||
|
|
b7eefc31d8 | ||
|
|
5df3bf467e | ||
|
|
ac44139084 | ||
|
|
ac882ea696 | ||
|
|
56f9559c69 | ||
|
|
c08c32a1ed | ||
|
|
03491904a0 | ||
|
|
57f84c5376 | ||
|
|
1df4debbf1 | ||
|
|
1ff69eae17 | ||
|
|
4fa122eb44 | ||
|
|
53782b1404 | ||
|
|
cafe1284ac | ||
|
|
e2ae7d5f43 | ||
|
|
772ebe6715 | ||
|
|
32c99651fc | ||
|
|
2eac7941ff | ||
|
|
cedcb7881d | ||
|
|
117b913458 |
2
.github/workflows/ci_bench.yml
vendored
2
.github/workflows/ci_bench.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04]
|
||||
os: [ubuntu-24.04]
|
||||
cpu: [amd64]
|
||||
name: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
2
.github/workflows/ci_docs.yml
vendored
2
.github/workflows/ci_docs.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
target: [linux, windows, osx]
|
||||
include:
|
||||
- target: linux
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-22.04
|
||||
- target: windows
|
||||
os: windows-2019
|
||||
- target: osx
|
||||
|
||||
76
.github/workflows/ci_gcc14.yml
vendored
Normal file
76
.github/workflows/ci_gcc14.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
name: GCC 14
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 'devel'
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-24.04]
|
||||
cpu: [amd64]
|
||||
name: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60 # refs bug #18178
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 'Install node.js 20.x'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
|
||||
- name: 'Install dependencies (Linux amd64)'
|
||||
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
|
||||
run: |
|
||||
sudo apt update -qq
|
||||
sudo apt remove needrestart
|
||||
DEBIAN_FRONTEND='noninteractive' \
|
||||
sudo apt install --no-install-recommends -yq \
|
||||
libcurl4-openssl-dev libgc-dev libsdl1.2-dev libsfml-dev \
|
||||
valgrind libc6-dbg libblas-dev xorg-dev
|
||||
- name: 'Install dependencies (Linux amd64 gcc 14)'
|
||||
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
|
||||
run: |
|
||||
sudo add-apt-repository universe
|
||||
sudo apt update -qq
|
||||
sudo apt install -y gcc-14 g++-14 libpcre3 liblapack-dev
|
||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 60 --slave /usr/bin/g++ g++ /usr/bin/g++-14
|
||||
- name: 'Install dependencies (macOS)'
|
||||
if: runner.os == 'macOS'
|
||||
run: brew install boehmgc make sfml gtk+3
|
||||
- name: 'Install dependencies (Windows)'
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
. ci/funs.sh
|
||||
nimInternalInstallDepsWindows
|
||||
echo_run echo "${{ github.workspace }}/dist/mingw64/bin" >> "${GITHUB_PATH}"
|
||||
|
||||
- name: 'Add build binaries to PATH'
|
||||
shell: bash
|
||||
run: echo "${{ github.workspace }}/bin" >> "${GITHUB_PATH}"
|
||||
|
||||
- name: 'NIM_TESTAMENT_DISABLE_SSL'
|
||||
shell: bash
|
||||
run: echo "NIM_TESTAMENT_DISABLE_SSL=1" >> $GITHUB_ENV
|
||||
|
||||
- name: 'System information'
|
||||
shell: bash
|
||||
run: . ci/funs.sh && nimCiSystemInfo
|
||||
|
||||
- name: 'Build csourcesAny'
|
||||
shell: bash
|
||||
run: . ci/funs.sh && nimBuildCsourcesIfNeeded CC=gcc ucpu='${{ matrix.cpu }}'
|
||||
|
||||
- name: 'koch, Run CI'
|
||||
shell: bash
|
||||
run: . ci/funs.sh && nimInternalBuildKochAndRunCI
|
||||
2
.github/workflows/ci_packages.yml
vendored
2
.github/workflows/ci_packages.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-13]
|
||||
os: [ubuntu-22.04, macos-13]
|
||||
cpu: [amd64]
|
||||
batch: ["allowed_failures", "0_3", "1_3", "2_3"] # list of `index_num`
|
||||
name: '${{ matrix.os }} (batch: ${{ matrix.batch }})'
|
||||
|
||||
17
.github/workflows/ci_publish.yml
vendored
17
.github/workflows/ci_publish.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04]
|
||||
os: [ubuntu-22.04]
|
||||
cpu: [amd64]
|
||||
name: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -21,10 +21,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 'Install node.js 20.x'
|
||||
- name: 'Install node.js'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version: ''
|
||||
|
||||
- name: 'Install dependencies (Linux amd64)'
|
||||
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
|
||||
@@ -34,17 +34,6 @@ jobs:
|
||||
sudo apt-fast install --no-install-recommends -yq \
|
||||
libcurl4-openssl-dev libgc-dev libsdl1.2-dev libsfml-dev \
|
||||
valgrind libc6-dbg libblas-dev xorg-dev
|
||||
- name: 'Install dependencies (macOS)'
|
||||
if: runner.os == 'macOS'
|
||||
run: brew install boehmgc make sfml gtk+3
|
||||
- name: 'Install dependencies (Windows)'
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
. ci/funs.sh
|
||||
nimInternalInstallDepsWindows
|
||||
echo_run echo "${{ github.workspace }}/dist/mingw64/bin" >> "${GITHUB_PATH}"
|
||||
|
||||
- name: 'Add build binaries to PATH'
|
||||
shell: bash
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
Linux_amd64:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
vmImage: 'ubuntu-24.04'
|
||||
CPU: amd64
|
||||
# regularly breaks, refs bug #17325
|
||||
# Linux_i386:
|
||||
@@ -36,16 +36,16 @@ jobs:
|
||||
CPU: amd64
|
||||
NIM_COMPILE_TO_CPP: true
|
||||
Windows_amd64_batch0_3:
|
||||
vmImage: 'windows-2019'
|
||||
vmImage: 'windows-2025'
|
||||
CPU: amd64
|
||||
# see also: `NIM_TEST_PACKAGES`
|
||||
NIM_TESTAMENT_BATCH: "0_3"
|
||||
Windows_amd64_batch1_3:
|
||||
vmImage: 'windows-2019'
|
||||
vmImage: 'windows-2025'
|
||||
CPU: amd64
|
||||
NIM_TESTAMENT_BATCH: "1_3"
|
||||
Windows_amd64_batch2_3:
|
||||
vmImage: 'windows-2019'
|
||||
vmImage: 'windows-2025'
|
||||
CPU: amd64
|
||||
NIM_TESTAMENT_BATCH: "2_3"
|
||||
|
||||
@@ -80,10 +80,12 @@ jobs:
|
||||
- bash: |
|
||||
set -e
|
||||
. ci/funs.sh
|
||||
echo_run sudo apt-fast update -qq
|
||||
echo_run sudo add-apt-repository universe
|
||||
echo_run sudo apt-get update -qq
|
||||
DEBIAN_FRONTEND='noninteractive' \
|
||||
echo_run sudo apt-fast install --no-install-recommends -yq \
|
||||
libcurl4-openssl-dev libgc-dev libsdl1.2-dev libsfml-dev valgrind libc6-dbg
|
||||
echo_run sudo apt-get install --no-install-recommends -yq \
|
||||
gcc-14 g++-14 libpcre3 liblapack-dev libpcre3 liblapack-dev libcurl4-openssl-dev libgc-dev libsdl1.2-dev libsfml-dev valgrind libc6-dbg
|
||||
echo_run sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 60 --slave /usr/bin/g++ g++ /usr/bin/g++-14
|
||||
displayName: 'Install dependencies (amd64 Linux)'
|
||||
condition: and(succeeded(), eq(variables['skipci'], 'false'), eq(variables['Agent.OS'], 'Linux'), eq(variables['CPU'], 'amd64'))
|
||||
|
||||
@@ -100,12 +102,12 @@ jobs:
|
||||
Pin-Priority: 1001
|
||||
EOF
|
||||
|
||||
# echo_run sudo apt-fast update -qq
|
||||
echo_run sudo apt-fast update -qq || echo "failed, see bug #17343"
|
||||
# echo_run sudo apt-get update -qq
|
||||
echo_run sudo apt-get update -qq || echo "failed, see bug #17343"
|
||||
# `:i386` (e.g. in `libffi-dev:i386`) is needed otherwise you may get:
|
||||
# `could not load: libffi.so` during dynamic loading.
|
||||
DEBIAN_FRONTEND='noninteractive' \
|
||||
echo_run sudo apt-fast install --no-install-recommends --allow-downgrades -yq \
|
||||
echo_run sudo apt-get install --no-install-recommends --allow-downgrades -yq \
|
||||
g++-multilib gcc-multilib libcurl4-openssl-dev:i386 libgc-dev:i386 \
|
||||
libsdl1.2-dev:i386 libsfml-dev:i386 libglib2.0-dev:i386 libffi-dev:i386
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ proc registerTraverseProc(p: BProc, v: PSym) =
|
||||
var traverseProc = ""
|
||||
if p.config.selectedGC in {gcMarkAndSweep, gcHooks, gcRefc} and
|
||||
optOwnedRefs notin p.config.globalOptions and
|
||||
containsGarbageCollectedRef(v.loc.t):
|
||||
containsManagedMemory(v.loc.t):
|
||||
# we register a specialized marked proc here; this has the advantage
|
||||
# that it works out of the box for thread local storage then :-)
|
||||
traverseProc = genTraverseProcForGlobal(p.module, v, v.info)
|
||||
|
||||
@@ -768,6 +768,8 @@ proc fillObjectFields*(m: BModule; typ: PType) =
|
||||
# this fact here.
|
||||
var check = initIntSet()
|
||||
discard getRecordFields(m, typ, check)
|
||||
if typ.baseClass != nil:
|
||||
fillObjectFields(m, typ.baseClass.skipTypes(skipPtrs))
|
||||
|
||||
proc mangleDynLibProc(sym: PSym): Rope
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ type
|
||||
|
||||
const
|
||||
nkSkip = {nkEmpty..nkNilLit, nkTemplateDef, nkTypeSection, nkStaticStmt,
|
||||
nkCommentStmt, nkMixinStmt, nkBindStmt} + procDefs
|
||||
nkCommentStmt, nkMixinStmt, nkBindStmt, nkTypeOfExpr} + procDefs
|
||||
|
||||
proc newStateAccess(ctx: var Ctx): PNode =
|
||||
if ctx.stateVarSym.isNil:
|
||||
|
||||
@@ -452,6 +452,11 @@ proc noAbsolutePaths(conf: ConfigRef): bool {.inline.} =
|
||||
proc cFileSpecificOptions(conf: ConfigRef; nimname, fullNimFile: string): string =
|
||||
result = conf.compileOptions
|
||||
|
||||
if (conf.cCompiler == ccGcc or conf.cCompiler == ccCLang) and
|
||||
conf.selectedGC == gcRefc:
|
||||
# bug #10625
|
||||
addOpt(result, "-fno-omit-frame-pointer")
|
||||
|
||||
for option in conf.compileOptionsCmd:
|
||||
if strutils.find(result, option, 0) < 0:
|
||||
addOpt(result, option)
|
||||
|
||||
@@ -39,7 +39,7 @@ template asink*(t: PType): PSym = getAttachedOp(c.g, t, attachedSink)
|
||||
|
||||
proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode)
|
||||
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
info: TLineInfo; idgen: IdGenerator; isDistinct = false): PSym
|
||||
info: TLineInfo; idgen: IdGenerator): PSym
|
||||
|
||||
proc createTypeBoundOps*(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo;
|
||||
idgen: IdGenerator)
|
||||
@@ -226,7 +226,14 @@ proc fillBodyObjTImpl(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||
let obj = newNodeIT(nkHiddenSubConv, c.info, t[0])
|
||||
obj.add newNodeI(nkEmpty, c.info)
|
||||
obj.add x
|
||||
fillBody(c, skipTypes(t[0], abstractPtrs), body, obj, y)
|
||||
var src = y
|
||||
|
||||
if c.kind in {attachedAsgn, attachedDeepCopy, attachedSink}:
|
||||
src = newNodeIT(nkHiddenSubConv, c.info, t[0])
|
||||
src.add newNodeI(nkEmpty, c.info)
|
||||
src.add y
|
||||
|
||||
fillBody(c, skipTypes(t[0], abstractPtrs), body, obj, src)
|
||||
fillBodyObj(c, t.n, body, x, y, enforceDefaultOp = false)
|
||||
|
||||
proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||
@@ -1036,9 +1043,7 @@ proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType;
|
||||
assert typ.kind == tyDistinct
|
||||
let baseType = typ[0]
|
||||
if getAttachedOp(g, baseType, kind) == nil:
|
||||
# TODO: fixme `isDistinct` is a fix for #23552; remove it after
|
||||
# `-d:nimPreviewNonVarDestructor` becomes the default
|
||||
discard produceSym(g, c, baseType, kind, info, idgen, isDistinct = true)
|
||||
discard produceSym(g, c, baseType, kind, info, idgen)
|
||||
result = getAttachedOp(g, baseType, kind)
|
||||
setAttachedOp(g, idgen.module, typ, kind, result)
|
||||
|
||||
@@ -1077,7 +1082,7 @@ proc symDupPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttache
|
||||
incl result.flags, sfGeneratedOp
|
||||
|
||||
proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp;
|
||||
info: TLineInfo; idgen: IdGenerator; isDiscriminant = false; isDistinct = false): PSym =
|
||||
info: TLineInfo; idgen: IdGenerator; isDiscriminant = false): PSym =
|
||||
if kind == attachedDup:
|
||||
return symDupPrototype(g, typ, owner, kind, info, idgen)
|
||||
|
||||
@@ -1087,7 +1092,7 @@ proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp
|
||||
let src = newSym(skParam, getIdent(g.cache, if kind == attachedTrace: "env" else: "src"),
|
||||
idgen, result, info)
|
||||
if kind == attachedDestructor and g.config.selectedGC in {gcArc, gcOrc, gcAtomicArc} and
|
||||
((g.config.isDefined("nimPreviewNonVarDestructor") and not isDiscriminant) or (typ.kind in {tyRef, tyString, tySequence} and not isDistinct)):
|
||||
((g.config.isDefined("nimPreviewNonVarDestructor") and not isDiscriminant) or (typ.kind in {tyRef, tyString, tySequence})):
|
||||
dest.typ = typ
|
||||
else:
|
||||
dest.typ = makeVarType(typ.owner, typ, idgen)
|
||||
@@ -1129,13 +1134,13 @@ proc genTypeFieldCopy(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
body.add newAsgnStmt(xx, yy)
|
||||
|
||||
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
info: TLineInfo; idgen: IdGenerator; isDistinct = false): PSym =
|
||||
info: TLineInfo; idgen: IdGenerator): PSym =
|
||||
if typ.kind == tyDistinct:
|
||||
return produceSymDistinctType(g, c, typ, kind, info, idgen)
|
||||
|
||||
result = getAttachedOp(g, typ, kind)
|
||||
if result == nil:
|
||||
result = symPrototype(g, typ, typ.owner, kind, info, idgen, isDistinct = isDistinct)
|
||||
result = symPrototype(g, typ, typ.owner, kind, info, idgen)
|
||||
|
||||
var a = TLiftCtx(info: info, g: g, kind: kind, c: c, asgnForType: typ, idgen: idgen,
|
||||
fn: result)
|
||||
@@ -1179,6 +1184,8 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
result.ast[pragmasPos].add newTree(nkExprColonExpr,
|
||||
newIdentNode(g.cache.getIdent("raises"), info), newNodeI(nkBracket, info))
|
||||
|
||||
if kind == attachedDestructor:
|
||||
incl result.options, optQuirky
|
||||
completePartialOp(g, idgen.module, typ, kind, result)
|
||||
|
||||
|
||||
|
||||
@@ -1295,8 +1295,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
pragmaProposition(c, it)
|
||||
of wEnsures:
|
||||
pragmaEnsures(c, it)
|
||||
of wEnforceNoRaises, wQuirky:
|
||||
of wEnforceNoRaises:
|
||||
sym.flags.incl sfNeverRaises
|
||||
of wQuirky:
|
||||
sym.flags.incl sfNeverRaises
|
||||
if sym.kind in {skProc, skMethod, skConverter, skFunc, skIterator}:
|
||||
sym.options.incl optQuirky
|
||||
of wSystemRaisesDefect:
|
||||
sym.flags.incl sfSystemRaisesDefect
|
||||
of wVirtual:
|
||||
|
||||
@@ -557,8 +557,16 @@ proc lsub(g: TSrcGen; n: PNode): int =
|
||||
of nkIfExpr:
|
||||
result = lsub(g, n[0][0]) + lsub(g, n[0][1]) + lsons(g, n, 1) +
|
||||
len("if_:_")
|
||||
of nkElifExpr: result = lsons(g, n) + len("_elif_:_")
|
||||
of nkElseExpr: result = lsub(g, n[0]) + len("_else:_") # type descriptions
|
||||
of nkElifExpr, nkElifBranch:
|
||||
if isEmptyType(n[1].typ):
|
||||
result = lsons(g, n) + len("elif_:_")
|
||||
else:
|
||||
result = lsons(g, n) + len("_elif_:_")
|
||||
of nkElseExpr, nkElse:
|
||||
if isEmptyType(n[0].typ):
|
||||
result = lsub(g, n[0]) + len("else:_")
|
||||
else:
|
||||
result = lsub(g, n[0]) + len("_else:_") # type descriptions
|
||||
of nkTypeOfExpr: result = (if n.len > 0: lsub(g, n[0]) else: 0)+len("typeof()")
|
||||
of nkRefTy: result = (if n.len > 0: lsub(g, n[0])+1 else: 0) + len("ref")
|
||||
of nkPtrTy: result = (if n.len > 0: lsub(g, n[0])+1 else: 0) + len("ptr")
|
||||
@@ -601,8 +609,6 @@ proc lsub(g: TSrcGen; n: PNode): int =
|
||||
of nkCommentStmt: result = n.comment.len
|
||||
of nkOfBranch: result = lcomma(g, n, 0, - 2) + lsub(g, lastSon(n)) + len("of_:_")
|
||||
of nkImportAs: result = lsub(g, n[0]) + len("_as_") + lsub(g, n[1])
|
||||
of nkElifBranch: result = lsons(g, n) + len("elif_:_")
|
||||
of nkElse: result = lsub(g, n[0]) + len("else:_")
|
||||
of nkFinally: result = lsub(g, n[0]) + len("finally:_")
|
||||
of nkGenericParams: result = lcomma(g, n) + 2
|
||||
of nkFormalParams:
|
||||
@@ -1459,15 +1465,30 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext, fromStmtList = false) =
|
||||
putWithSpace(g, tkColon, ":")
|
||||
if n.len > 0: gsub(g, n[0], 1)
|
||||
gsons(g, n, emptyContext, 1)
|
||||
of nkElifExpr:
|
||||
putWithSpace(g, tkElif, " elif")
|
||||
gcond(g, n[0])
|
||||
putWithSpace(g, tkColon, ":")
|
||||
gsub(g, n, 1)
|
||||
of nkElseExpr:
|
||||
put(g, tkElse, " else")
|
||||
putWithSpace(g, tkColon, ":")
|
||||
gsub(g, n, 0)
|
||||
of nkElifExpr, nkElifBranch:
|
||||
if isEmptyType(n[1].typ):
|
||||
optNL(g)
|
||||
putWithSpace(g, tkElif, "elif")
|
||||
gsub(g, n, 0)
|
||||
putWithSpace(g, tkColon, ":")
|
||||
gcoms(g)
|
||||
gstmts(g, n[1], c)
|
||||
else:
|
||||
putWithSpace(g, tkElif, " elif")
|
||||
gcond(g, n[0])
|
||||
putWithSpace(g, tkColon, ":")
|
||||
gsub(g, n, 1)
|
||||
of nkElseExpr, nkElse:
|
||||
if isEmptyType(n[0].typ):
|
||||
optNL(g)
|
||||
put(g, tkElse, "else")
|
||||
putWithSpace(g, tkColon, ":")
|
||||
gcoms(g)
|
||||
gstmts(g, n[0], c)
|
||||
else:
|
||||
put(g, tkElse, " else")
|
||||
putWithSpace(g, tkColon, ":")
|
||||
gsub(g, n, 0)
|
||||
of nkTypeOfExpr:
|
||||
put(g, tkType, "typeof")
|
||||
put(g, tkParLe, "(")
|
||||
@@ -1729,19 +1750,6 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext, fromStmtList = false) =
|
||||
of nkMixinStmt:
|
||||
putWithSpace(g, tkMixin, "mixin")
|
||||
gcomma(g, n, c)
|
||||
of nkElifBranch:
|
||||
optNL(g)
|
||||
putWithSpace(g, tkElif, "elif")
|
||||
gsub(g, n, 0)
|
||||
putWithSpace(g, tkColon, ":")
|
||||
gcoms(g)
|
||||
gstmts(g, n[1], c)
|
||||
of nkElse:
|
||||
optNL(g)
|
||||
put(g, tkElse, "else")
|
||||
putWithSpace(g, tkColon, ":")
|
||||
gcoms(g)
|
||||
gstmts(g, n[0], c)
|
||||
of nkFinally, nkDefer:
|
||||
optNL(g)
|
||||
if n.kind == nkFinally:
|
||||
|
||||
@@ -757,7 +757,8 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||
of nkCast:
|
||||
var a = getConstExpr(m, n[1], idgen, g)
|
||||
if a == nil: return
|
||||
if n.typ != nil and n.typ.kind in NilableTypes:
|
||||
if n.typ != nil and n.typ.kind in NilableTypes and
|
||||
not (n.typ.kind == tyProc and a.typ.kind == tyProc):
|
||||
# we allow compile-time 'cast' for pointer types:
|
||||
result = a
|
||||
result.typ = n.typ
|
||||
|
||||
@@ -11,7 +11,7 @@ import
|
||||
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
||||
wordrecg, strutils, options, guards, lineinfos, semfold, semdata,
|
||||
modulegraphs, varpartitions, typeallowed, nilcheck, errorhandling, tables,
|
||||
semstrictfuncs
|
||||
semstrictfuncs, lowerings
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
@@ -89,10 +89,11 @@ const
|
||||
errXCannotBeAssignedTo = "'$1' cannot be assigned to"
|
||||
errLetNeedsInit = "'let' symbol requires an initialization"
|
||||
|
||||
proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo) =
|
||||
if typ == nil or sfGeneratedOp in tracked.owner.flags:
|
||||
proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo; explicit = false) =
|
||||
if typ == nil or (sfGeneratedOp in tracked.owner.flags and not explicit):
|
||||
# don't create type bound ops for anything in a function with a `nodestroy` pragma
|
||||
# bug #21987
|
||||
# unless this is an explicit call, bug #24626
|
||||
return
|
||||
when false:
|
||||
let realType = typ.skipTypes(abstractInst)
|
||||
@@ -926,10 +927,17 @@ proc trackCall(tracked: PEffects; n: PNode) =
|
||||
# rebind type bounds operations after createTypeBoundOps call
|
||||
let t = n[1].typ.skipTypes({tyAlias, tyVar})
|
||||
if a.sym != getAttachedOp(tracked.graph, t, TTypeAttachedOp(opKind)):
|
||||
createTypeBoundOps(tracked, t, n.info)
|
||||
createTypeBoundOps(tracked, t, n.info, explicit = true)
|
||||
let op = getAttachedOp(tracked.graph, t, TTypeAttachedOp(opKind))
|
||||
if op != nil:
|
||||
n[0].sym = op
|
||||
if TTypeAttachedOp(opKind) == attachedDestructor and
|
||||
op.typ.len == 2 and op.typ.firstParamType.kind != tyVar:
|
||||
if n[1].kind == nkSym and n[1].sym.kind == skParam and
|
||||
n[1].typ.kind == tyVar:
|
||||
n[1] = genDeref(n[1])
|
||||
else:
|
||||
n[1] = skipAddr(n[1])
|
||||
|
||||
if op != nil and op.kind == tyProc:
|
||||
for i in 1..<min(n.safeLen, op.len):
|
||||
|
||||
@@ -1719,6 +1719,17 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
|
||||
# check the style here after the pragmas have been processed:
|
||||
styleCheckDef(c, s)
|
||||
# compute the type's size and check for illegal recursions:
|
||||
if a[0].kind == nkPragmaExpr:
|
||||
let pragmas = a[0][1]
|
||||
for i in 0 ..< pragmas.len:
|
||||
if pragmas[i].kind == nkExprColonExpr and
|
||||
pragmas[i][0].kind == nkIdent and
|
||||
whichKeyword(pragmas[i][0].ident) == wSize:
|
||||
if s.typ.kind != tyEnum and sfImportc notin s.flags:
|
||||
# EventType* {.size: sizeof(uint32).} = enum
|
||||
# AtomicFlag* {.importc: "atomic_flag", header: "<stdatomic.h>", size: 1.} = object
|
||||
localError(c.config, pragmas[i].info, "size pragma only allowed for enum types and imported types")
|
||||
|
||||
if a[1].kind == nkEmpty:
|
||||
var x = a[2]
|
||||
if x.kind in nkCallKinds and nfSem in x.flags:
|
||||
|
||||
@@ -66,7 +66,12 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule;
|
||||
# for instance 'nextTry' is both in tables.nim and astalgo.nim ...
|
||||
if not isField or sfGenSym notin s.flags:
|
||||
result = newSymNode(s, info)
|
||||
markUsed(c, info, s)
|
||||
if isField:
|
||||
# possibly not final field sym
|
||||
incl(s.flags, sfUsed)
|
||||
markOwnerModuleAsUsed(c, s)
|
||||
else:
|
||||
markUsed(c, info, s)
|
||||
onUse(info, s)
|
||||
else:
|
||||
result = n
|
||||
|
||||
@@ -107,6 +107,13 @@ proc transformSons(c: PTransf, n: PNode, noConstFold = false): PNode =
|
||||
for i in 0..<n.len:
|
||||
result[i] = transform(c, n[i], noConstFold)
|
||||
|
||||
proc transformSonsAfterType(c: PTransf, n: PNode, noConstFold = false): PNode =
|
||||
result = newTransNode(n)
|
||||
assert n.len != 0
|
||||
result[0] = copyTree(n[0])
|
||||
for i in 1..<n.len:
|
||||
result[i] = transform(c, n[i], noConstFold)
|
||||
|
||||
proc newAsgnStmt(c: PTransf, kind: TNodeKind, le: PNode, ri: PNode; isFirstWrite: bool): PNode =
|
||||
result = newTransNode(kind, ri.info, 2)
|
||||
result[0] = le
|
||||
@@ -835,9 +842,18 @@ proc transformArrayAccess(c: PTransf, n: PNode): PNode =
|
||||
if n[0].kind == nkSym and n[0].sym.kind == skType:
|
||||
result = n
|
||||
else:
|
||||
result = newTransNode(n)
|
||||
for i in 0..<n.len:
|
||||
result[i] = transform(c, skipConv(n[i]))
|
||||
result = transformSons(c, n)
|
||||
if n.len >= 2 and result[1].kind in {nkChckRange, nkChckRange64} and
|
||||
n[1].kind in {nkHiddenStdConv, nkHiddenSubConv}:
|
||||
# implicit conversion, was transformed into range check
|
||||
# remove in favor of index check if conversion to array index type
|
||||
# has to be done here because the array index type needs to be relaxed
|
||||
# i.e. a uint32 index can implicitly convert to range[0..3] but not int
|
||||
let arr = skipTypes(n[0].typ, abstractVarRange)
|
||||
if arr.kind == tyArray and
|
||||
firstOrd(c.graph.config, arr) == getOrdValue(result[1][1]) and
|
||||
lastOrd(c.graph.config, arr) == getOrdValue(result[1][2]):
|
||||
result[1] = result[1].skipConv
|
||||
|
||||
proc getMergeOp(n: PNode): PSym =
|
||||
case n.kind
|
||||
@@ -1058,6 +1074,9 @@ proc transform(c: PTransf, n: PNode, noConstFold = false): PNode =
|
||||
result = transformAddrDeref(c, n, {nkAddr, nkHiddenAddr})
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
result = transformConv(c, n)
|
||||
of nkObjConstr, nkCast:
|
||||
# don't try to transform type node
|
||||
result = transformSonsAfterType(c, n)
|
||||
of nkDiscardStmt:
|
||||
result = n
|
||||
if n[0].kind != nkEmpty:
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
import semmacrosanity
|
||||
import
|
||||
std/[strutils, tables, parseutils],
|
||||
std/[strutils, tables, intsets, parseutils],
|
||||
msgs, vmdef, vmgen, nimsets, types,
|
||||
parser, vmdeps, idents, trees, renderer, options, transf,
|
||||
gorgeimpl, lineinfos, btrees, macrocacheimpl,
|
||||
@@ -2375,8 +2375,11 @@ proc evalConstExprAux(module: PSym; idgen: IdGenerator;
|
||||
setupGlobalCtx(module, g, idgen)
|
||||
var c = PCtx g.vm
|
||||
let oldMode = c.mode
|
||||
let oldLocals = c.locals
|
||||
c.mode = mode
|
||||
c.locals = initIntSet()
|
||||
let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
|
||||
c.locals = oldLocals
|
||||
if c.code[start].opcode == opcEof: return newNodeI(nkEmpty, n.info)
|
||||
assert c.code[start].opcode != opcEof
|
||||
when debugEchoCode: c.echoCode start
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
## This module contains the type definitions for the new evaluation engine.
|
||||
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
||||
|
||||
import std/[tables, strutils]
|
||||
import std/[tables, strutils, intsets]
|
||||
|
||||
import ast, idents, options, modulegraphs, lineinfos
|
||||
|
||||
@@ -270,6 +270,7 @@ type
|
||||
templInstCounter*: ref int # gives every template instantiation a unique ID, needed here for getAst
|
||||
vmstateDiff*: seq[(PSym, PNode)] # we remember the "diff" to global state here (feature for IC)
|
||||
procToCodePos*: Table[int, int]
|
||||
locals*: IntSet
|
||||
|
||||
PStackFrame* = ref TStackFrame
|
||||
TStackFrame* {.acyclic.} = object
|
||||
|
||||
@@ -1559,6 +1559,7 @@ proc checkCanEval(c: PCtx; n: PNode) =
|
||||
# are in the right scope:
|
||||
if sfGenSym in s.flags and c.prc.sym == nil: discard
|
||||
elif s.kind == skParam and s.typ.kind == tyTypeDesc: discard
|
||||
elif s.kind in {skVar, skLet} and s.id in c.locals: discard
|
||||
else: cannotEval(c, n)
|
||||
elif s.kind in {skProc, skFunc, skConverter, skMethod,
|
||||
skIterator} and sfForward in s.flags:
|
||||
@@ -1948,7 +1949,7 @@ proc genVarSection(c: PCtx; n: PNode) =
|
||||
c.gen(lowerTupleUnpacking(c.graph, a, c.idgen, c.getOwner))
|
||||
elif a[0].kind == nkSym:
|
||||
let s = a[0].sym
|
||||
checkCanEval(c, a[0])
|
||||
c.locals.incl(s.id)
|
||||
if s.isGlobal:
|
||||
let runtimeAccessToCompileTime = c.mode == emRepl and
|
||||
sfCompileTime in s.flags and s.position > 0
|
||||
@@ -2013,7 +2014,7 @@ proc genArrayConstr(c: PCtx, n: PNode, dest: var TDest) =
|
||||
c.gABx(n, opcLdNull, dest, c.genType(n.typ))
|
||||
|
||||
let intType = getSysType(c.graph, n.info, tyInt)
|
||||
let seqType = n.typ.skipTypes(abstractVar-{tyTypeDesc})
|
||||
let seqType = n.typ.skipTypes(abstractVar+{tyStatic}-{tyTypeDesc})
|
||||
if seqType.kind == tySequence:
|
||||
var tmp = c.getTemp(intType)
|
||||
c.gABx(n, opcLdImmInt, tmp, n.len)
|
||||
|
||||
@@ -5096,22 +5096,22 @@ caught by reference. Example:
|
||||
proc fn() =
|
||||
let a = initRuntimeError("foo")
|
||||
doAssert $a.what == "foo"
|
||||
var b: cstring
|
||||
var b = ""
|
||||
try: raise initRuntimeError("foo2")
|
||||
except CStdException as e:
|
||||
doAssert e is CStdException
|
||||
b = e.what()
|
||||
doAssert $b == "foo2"
|
||||
b = $e.what()
|
||||
doAssert b == "foo2"
|
||||
|
||||
try: raise initStdException()
|
||||
except CStdException: discard
|
||||
|
||||
try: raise initRuntimeError("foo3")
|
||||
except CRuntimeError as e:
|
||||
b = e.what()
|
||||
b = $e.what()
|
||||
except CStdException:
|
||||
doAssert false
|
||||
doAssert $b == "foo3"
|
||||
doAssert b == "foo3"
|
||||
|
||||
fn()
|
||||
```
|
||||
|
||||
@@ -514,7 +514,6 @@ proc parseSaturatedNatural*(s: openArray[char], b: var int): int {.
|
||||
proc rawParseUInt(s: openArray[char], b: var BiggestUInt): int =
|
||||
var
|
||||
res = 0.BiggestUInt
|
||||
prev = 0.BiggestUInt
|
||||
i = 0
|
||||
if i < s.len - 1 and s[i] == '-' and s[i + 1] in {'0'..'9'}:
|
||||
integerOutOfRangeError()
|
||||
@@ -522,8 +521,11 @@ proc rawParseUInt(s: openArray[char], b: var BiggestUInt): int =
|
||||
if i < s.len and s[i] in {'0'..'9'}:
|
||||
b = 0
|
||||
while i < s.len and s[i] in {'0'..'9'}:
|
||||
prev = res
|
||||
res = res * 10 + (ord(s[i]) - ord('0')).BiggestUInt
|
||||
if res > BiggestUInt.high div 10: # Highest value that you can multiply 10 without overflow
|
||||
integerOutOfRangeError()
|
||||
res = res * 10
|
||||
let prev = res
|
||||
res += (ord(s[i]) - ord('0')).BiggestUInt
|
||||
if prev > res:
|
||||
integerOutOfRangeError()
|
||||
inc(i)
|
||||
|
||||
@@ -72,6 +72,9 @@ else:
|
||||
template count(x: Cell): untyped =
|
||||
x.rc shr rcShift
|
||||
|
||||
when not defined(nimHasQuirky):
|
||||
{.pragma: quirky.}
|
||||
|
||||
proc nimNewObj(size, alignment: int): pointer {.compilerRtl.} =
|
||||
let hdrSize = align(sizeof(RefHeader), alignment)
|
||||
let s = size + hdrSize
|
||||
@@ -173,7 +176,7 @@ proc nimRawDispose(p: pointer, alignment: int) {.compilerRtl.} =
|
||||
template `=dispose`*[T](x: owned(ref T)) = nimRawDispose(cast[pointer](x), T.alignOf)
|
||||
#proc dispose*(x: pointer) = nimRawDispose(x)
|
||||
|
||||
proc nimDestroyAndDispose(p: pointer) {.compilerRtl, raises: [].} =
|
||||
proc nimDestroyAndDispose(p: pointer) {.compilerRtl, quirky, raises: [].} =
|
||||
let rti = cast[ptr PNimTypeV2](p)
|
||||
if rti.destructor != nil:
|
||||
cast[DestructorProc](rti.destructor)(p)
|
||||
|
||||
@@ -10,7 +10,7 @@ const
|
||||
## is the minor number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
NimPatch* {.intdefine.}: int = 14
|
||||
NimPatch* {.intdefine.}: int = 16
|
||||
## is the patch number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
|
||||
@@ -13,17 +13,24 @@ when not defined(nimPreviewSlimSystem):
|
||||
## Outplace version of `addFloat`.
|
||||
result.addFloat(x)
|
||||
|
||||
proc `$`*(x: int): string {.raises: [].} =
|
||||
## Outplace version of `addInt`.
|
||||
result.addInt(x)
|
||||
template addIntAlias(T: typedesc) =
|
||||
proc `$`*(x: T): string {.raises: [].} =
|
||||
## Outplace version of `addInt`.
|
||||
result = ""
|
||||
result.addInt(x)
|
||||
|
||||
proc `$`*(x: int64): string {.raises: [].} =
|
||||
## Outplace version of `addInt`.
|
||||
result.addInt(x)
|
||||
# need to declare for bit types as well to not clash with converters:
|
||||
addIntAlias int
|
||||
addIntAlias int8
|
||||
addIntAlias int16
|
||||
addIntAlias int32
|
||||
addIntAlias int64
|
||||
|
||||
proc `$`*(x: uint64): string {.raises: [].} =
|
||||
## Outplace version of `addInt`.
|
||||
addInt(result, x)
|
||||
addIntAlias uint
|
||||
addIntAlias uint8
|
||||
addIntAlias uint16
|
||||
addIntAlias uint32
|
||||
addIntAlias uint64
|
||||
|
||||
# same as old `ctfeWhitelist` behavior, whether or not this is a good idea.
|
||||
template gen(T) =
|
||||
|
||||
@@ -14,21 +14,26 @@ proc rangeBase(T: typedesc): typedesc {.magic: "TypeTrait".}
|
||||
|
||||
proc repr*(x: NimNode): string {.magic: "Repr", noSideEffect.}
|
||||
|
||||
proc repr*(x: int): string =
|
||||
## Same as $x
|
||||
$x
|
||||
template dollarAlias(T: typedesc) =
|
||||
proc repr*(x: T): string {.noSideEffect.} =
|
||||
## Same as $x
|
||||
$x
|
||||
|
||||
proc repr*(x: int64): string =
|
||||
## Same as $x
|
||||
$x
|
||||
# need to declare for bit types as well to not clash with converters:
|
||||
dollarAlias int
|
||||
dollarAlias int8
|
||||
dollarAlias int16
|
||||
dollarAlias int32
|
||||
dollarAlias int64
|
||||
|
||||
proc repr*(x: uint64): string {.noSideEffect.} =
|
||||
## Same as $x
|
||||
$x
|
||||
dollarAlias uint
|
||||
dollarAlias uint8
|
||||
dollarAlias uint16
|
||||
dollarAlias uint32
|
||||
dollarAlias uint64
|
||||
|
||||
proc repr*(x: float): string =
|
||||
## Same as $x
|
||||
$x
|
||||
dollarAlias float
|
||||
dollarAlias float32
|
||||
|
||||
proc repr*(x: bool): string {.magic: "BoolToStr", noSideEffect.}
|
||||
## repr for a boolean argument. Returns `x`
|
||||
|
||||
@@ -446,7 +446,7 @@ proc testNimblePackages(r: var TResults; cat: Category; packageFilter: string) =
|
||||
if pkg.allowFailure:
|
||||
inc r.passed
|
||||
inc r.failedButAllowed
|
||||
addResult(r, test, targetC, "", "", cmd & "\n" & outp, reFailed, allowFailure = pkg.allowFailure)
|
||||
discard r.finishTest(test, targetC, "", "", cmd & "\n" & outp, reFailed, allowFailure = pkg.allowFailure)
|
||||
continue
|
||||
outp
|
||||
|
||||
@@ -462,21 +462,21 @@ proc testNimblePackages(r: var TResults; cat: Category; packageFilter: string) =
|
||||
discard tryCommand(cmds[i], maxRetries = 3)
|
||||
discard tryCommand(cmds[^1], reFailed = reBuildFailed)
|
||||
inc r.passed
|
||||
r.addResult(test, targetC, "", "", "", reSuccess, allowFailure = pkg.allowFailure)
|
||||
discard r.finishTest(test, targetC, "", "", "", reSuccess, allowFailure = pkg.allowFailure)
|
||||
|
||||
errors = r.total - r.passed
|
||||
if errors == 0:
|
||||
r.addResult(packageFileTest, targetC, "", "", "", reSuccess)
|
||||
discard r.finishTest(packageFileTest, targetC, "", "", "", reSuccess)
|
||||
else:
|
||||
r.addResult(packageFileTest, targetC, "", "", "", reBuildFailed)
|
||||
discard r.finishTest(packageFileTest, targetC, "", "", "", reBuildFailed)
|
||||
|
||||
except JsonParsingError:
|
||||
errors = 1
|
||||
r.addResult(packageFileTest, targetC, "", "", "Invalid package file", reBuildFailed)
|
||||
discard r.finishTest(packageFileTest, targetC, "", "", "Invalid package file", reBuildFailed)
|
||||
raise
|
||||
except ValueError:
|
||||
errors = 1
|
||||
r.addResult(packageFileTest, targetC, "", "", "Unknown package", reBuildFailed)
|
||||
discard r.finishTest(packageFileTest, targetC, "", "", "Unknown package", reBuildFailed)
|
||||
raise # bug #18805
|
||||
finally:
|
||||
if errors == 0: removeDir(packagesDir)
|
||||
@@ -565,6 +565,7 @@ proc isJoinableSpec(spec: TSpec): bool =
|
||||
spec.err != reDisabled and
|
||||
not spec.unjoinable and
|
||||
spec.exitCode == 0 and
|
||||
spec.retries == 0 and
|
||||
spec.input.len == 0 and
|
||||
spec.nimout.len == 0 and
|
||||
spec.nimoutFull == false and
|
||||
|
||||
@@ -152,7 +152,7 @@ pkg "sim"
|
||||
pkg "smtp", "nimble compileExample"
|
||||
pkg "snip", "nimble test", "https://github.com/genotrance/snip"
|
||||
pkg "stew"
|
||||
pkg "stint", "nim c stint.nim"
|
||||
pkg "stint", "nimble test_internal"
|
||||
pkg "strslice"
|
||||
pkg "strunicode", "nim c -r --mm:refc src/strunicode.nim"
|
||||
pkg "supersnappy"
|
||||
|
||||
@@ -66,6 +66,11 @@ template enableRemoteNetworking*: bool =
|
||||
## a `nim` invocation (possibly via additional intermediate processes).
|
||||
getEnv("NIM_TESTAMENT_REMOTE_NETWORKING") == "1"
|
||||
|
||||
template disableSSLTesting*: bool =
|
||||
## TODO: workaround for GitHub Action gcc 14 matrix; remove this
|
||||
## matrix and the flag after Azure agent supports ubuntu 24.04
|
||||
getEnv("NIM_TESTAMENT_DISABLE_SSL") == "1"
|
||||
|
||||
template whenRuntimeJs*(bodyIf, bodyElse) =
|
||||
##[
|
||||
Behaves as `when defined(js) and not nimvm` (which isn't legal yet).
|
||||
|
||||
@@ -56,6 +56,7 @@ type
|
||||
reJoined, # test is disabled because it was joined into the megatest
|
||||
reSuccess # test was successful
|
||||
reInvalidSpec # test had problems to parse the spec
|
||||
reRetry # test is being retried
|
||||
|
||||
TTarget* = enum
|
||||
targetC = "c"
|
||||
@@ -102,6 +103,7 @@ type
|
||||
# but don't rely on much precision
|
||||
inlineErrors*: seq[InlineError] # line information to error message
|
||||
debugInfo*: string # debug info to give more context
|
||||
retries*: int # number of retry attempts after the test fails
|
||||
|
||||
proc getCmd*(s: TSpec): string =
|
||||
if s.cmd.len == 0:
|
||||
@@ -478,6 +480,8 @@ proc parseSpec*(filename: string): TSpec =
|
||||
result.timeout = parseFloat(e.value)
|
||||
except ValueError:
|
||||
result.parseErrors.addLine "cannot interpret as a float: ", e.value
|
||||
of "retries":
|
||||
discard parseInt(e.value, result.retries)
|
||||
of "targets", "target":
|
||||
try:
|
||||
result.targets.incl parseTargets(e.value)
|
||||
|
||||
@@ -272,16 +272,13 @@ proc testName(test: TTest, target: TTarget, extraOptions: string, allowFailure:
|
||||
name.strip()
|
||||
|
||||
proc addResult(r: var TResults, test: TTest, target: TTarget,
|
||||
extraOptions, expected, given: string, successOrig: TResultEnum,
|
||||
extraOptions, expected, given: string, success: TResultEnum, duration: float,
|
||||
allowFailure = false, givenSpec: ptr TSpec = nil) =
|
||||
# instead of `ptr TSpec` we could also use `Option[TSpec]`; passing `givenSpec` makes it easier to get what we need
|
||||
# instead of having to pass individual fields, or abusing existing ones like expected vs given.
|
||||
# test.name is easier to find than test.name.extractFilename
|
||||
# A bit hacky but simple and works with tests/testament/tshould_not_work.nim
|
||||
let name = testName(test, target, extraOptions, allowFailure)
|
||||
let duration = epochTime() - test.startTime
|
||||
let success = if test.spec.timeout > 0.0 and duration > test.spec.timeout: reTimeout
|
||||
else: successOrig
|
||||
|
||||
let durationStr = duration.formatFloat(ffDecimal, precision = 2).align(5)
|
||||
if backendLogging:
|
||||
@@ -342,6 +339,18 @@ proc addResult(r: var TResults, test: TTest, target: TTarget,
|
||||
discard waitForExit(p)
|
||||
close(p)
|
||||
|
||||
proc finishTest(r: var TResults, test: TTest, target: TTarget,
|
||||
extraOptions, expected, given: string, successOrig: TResultEnum,
|
||||
allowFailure = false, givenSpec: ptr TSpec = nil): bool =
|
||||
result = false
|
||||
let duration = epochTime() - test.startTime
|
||||
let success = if test.spec.timeout > 0.0 and duration > test.spec.timeout: reTimeout
|
||||
else: successOrig
|
||||
if test.spec.retries > 0 and success notin {reSuccess, reDisabled, reJoined, reInvalidSpec}:
|
||||
return true
|
||||
else:
|
||||
addResult(r, test, target, extraOptions, expected, given, success, duration, allowFailure, givenSpec)
|
||||
|
||||
proc toString(inlineError: InlineError, filename: string): string =
|
||||
result.add "$file($line, $col) $kind: $msg" % [
|
||||
"file", filename,
|
||||
@@ -370,23 +379,23 @@ proc nimoutCheck(expected, given: TSpec): bool =
|
||||
result = false
|
||||
|
||||
proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest,
|
||||
target: TTarget, extraOptions: string) =
|
||||
target: TTarget, extraOptions: string): bool =
|
||||
if not checkForInlineErrors(expected, given) or
|
||||
(not expected.nimoutFull and not nimoutCheck(expected, given)):
|
||||
r.addResult(test, target, extraOptions, expected.nimout & inlineErrorsMsgs(expected), given.nimout, reMsgsDiffer)
|
||||
result = r.finishTest(test, target, extraOptions, expected.nimout & inlineErrorsMsgs(expected), given.nimout, reMsgsDiffer)
|
||||
elif strip(expected.msg) notin strip(given.msg):
|
||||
r.addResult(test, target, extraOptions, expected.msg, given.msg, reMsgsDiffer)
|
||||
result = r.finishTest(test, target, extraOptions, expected.msg, given.msg, reMsgsDiffer)
|
||||
elif not nimoutCheck(expected, given):
|
||||
r.addResult(test, target, extraOptions, expected.nimout, given.nimout, reMsgsDiffer)
|
||||
result = r.finishTest(test, target, extraOptions, expected.nimout, given.nimout, reMsgsDiffer)
|
||||
elif extractFilename(expected.file) != extractFilename(given.file) and
|
||||
"internal error:" notin expected.msg:
|
||||
r.addResult(test, target, extraOptions, expected.file, given.file, reFilesDiffer)
|
||||
result = r.finishTest(test, target, extraOptions, expected.file, given.file, reFilesDiffer)
|
||||
elif expected.line != given.line and expected.line != 0 or
|
||||
expected.column != given.column and expected.column != 0:
|
||||
r.addResult(test, target, extraOptions, $expected.line & ':' & $expected.column,
|
||||
result = r.finishTest(test, target, extraOptions, $expected.line & ':' & $expected.column,
|
||||
$given.line & ':' & $given.column, reLinesDiffer)
|
||||
else:
|
||||
r.addResult(test, target, extraOptions, expected.msg, given.msg, reSuccess)
|
||||
result = r.finishTest(test, target, extraOptions, expected.msg, given.msg, reSuccess)
|
||||
inc(r.passed)
|
||||
|
||||
proc generatedFile(test: TTest, target: TTarget): string =
|
||||
@@ -425,7 +434,7 @@ proc codegenCheck(test: TTest, target: TTarget, spec: TSpec, expectedMsg: var st
|
||||
echo getCurrentExceptionMsg()
|
||||
|
||||
proc compilerOutputTests(test: TTest, target: TTarget, extraOptions: string,
|
||||
given: var TSpec, expected: TSpec; r: var TResults) =
|
||||
given: var TSpec, expected: TSpec; r: var TResults): bool =
|
||||
var expectedmsg: string = ""
|
||||
var givenmsg: string = ""
|
||||
if given.err == reSuccess:
|
||||
@@ -440,7 +449,7 @@ proc compilerOutputTests(test: TTest, target: TTarget, extraOptions: string,
|
||||
else:
|
||||
givenmsg = "$ " & given.cmd & '\n' & given.nimout
|
||||
if given.err == reSuccess: inc(r.passed)
|
||||
r.addResult(test, target, extraOptions, expectedmsg, givenmsg, given.err)
|
||||
result = r.finishTest(test, target, extraOptions, expectedmsg, givenmsg, given.err)
|
||||
|
||||
proc getTestSpecTarget(): TTarget =
|
||||
if getEnv("NIM_COMPILE_TO_CPP", "false") == "true":
|
||||
@@ -456,31 +465,38 @@ proc equalModuloLastNewline(a, b: string): bool =
|
||||
|
||||
proc testSpecHelper(r: var TResults, test: var TTest, expected: TSpec,
|
||||
target: TTarget, extraOptions: string, nimcache: string) =
|
||||
test.startTime = epochTime()
|
||||
template maybeRetry(x: bool) =
|
||||
if x:
|
||||
test.spec.err = reRetry
|
||||
dec test.spec.retries
|
||||
testSpecHelper(r, test, expected, target, extraOptions, nimcache)
|
||||
return
|
||||
if test.spec.err != reRetry:
|
||||
test.startTime = epochTime()
|
||||
if testName(test, target, extraOptions, false) in skips:
|
||||
test.spec.err = reDisabled
|
||||
|
||||
if test.spec.err in {reDisabled, reJoined}:
|
||||
r.addResult(test, target, extraOptions, "", "", test.spec.err)
|
||||
discard r.finishTest(test, target, extraOptions, "", "", test.spec.err)
|
||||
inc(r.skipped)
|
||||
return
|
||||
var given = callNimCompiler(expected.getCmd, test.name, test.options, nimcache, target, extraOptions)
|
||||
case expected.action
|
||||
of actionCompile:
|
||||
compilerOutputTests(test, target, extraOptions, given, expected, r)
|
||||
maybeRetry compilerOutputTests(test, target, extraOptions, given, expected, r)
|
||||
of actionRun:
|
||||
if given.err != reSuccess:
|
||||
r.addResult(test, target, extraOptions, "", "$ " & given.cmd & '\n' & given.nimout, given.err, givenSpec = given.addr)
|
||||
maybeRetry r.finishTest(test, target, extraOptions, "", "$ " & given.cmd & '\n' & given.nimout, given.err, givenSpec = given.addr)
|
||||
else:
|
||||
let isJsTarget = target == targetJS
|
||||
var exeFile = changeFileExt(test.name, if isJsTarget: "js" else: ExeExt)
|
||||
if not fileExists(exeFile):
|
||||
r.addResult(test, target, extraOptions, expected.output,
|
||||
maybeRetry r.finishTest(test, target, extraOptions, expected.output,
|
||||
"executable not found: " & exeFile, reExeNotFound)
|
||||
else:
|
||||
let nodejs = if isJsTarget: findNodeJs() else: ""
|
||||
if isJsTarget and nodejs == "":
|
||||
r.addResult(test, target, extraOptions, expected.output, "nodejs binary not in PATH",
|
||||
maybeRetry r.finishTest(test, target, extraOptions, expected.output, "nodejs binary not in PATH",
|
||||
reExeNotFound)
|
||||
else:
|
||||
var exeCmd: string
|
||||
@@ -512,19 +528,19 @@ proc testSpecHelper(r: var TResults, test: var TTest, expected: TSpec,
|
||||
buf
|
||||
if exitCode != expected.exitCode:
|
||||
given.err = reExitcodesDiffer
|
||||
r.addResult(test, target, extraOptions, "exitcode: " & $expected.exitCode,
|
||||
maybeRetry r.finishTest(test, target, extraOptions, "exitcode: " & $expected.exitCode,
|
||||
"exitcode: " & $exitCode & "\n\nOutput:\n" &
|
||||
bufB, reExitcodesDiffer)
|
||||
elif (expected.outputCheck == ocEqual and not expected.output.equalModuloLastNewline(bufB)) or
|
||||
(expected.outputCheck == ocSubstr and expected.output notin bufB):
|
||||
given.err = reOutputsDiffer
|
||||
r.addResult(test, target, extraOptions, expected.output, bufB, reOutputsDiffer)
|
||||
compilerOutputTests(test, target, extraOptions, given, expected, r)
|
||||
maybeRetry r.finishTest(test, target, extraOptions, expected.output, bufB, reOutputsDiffer)
|
||||
maybeRetry compilerOutputTests(test, target, extraOptions, given, expected, r)
|
||||
of actionReject:
|
||||
# Make sure its the compiler rejecting and not the system (e.g. segfault)
|
||||
cmpMsgs(r, expected, given, test, target, extraOptions)
|
||||
maybeRetry cmpMsgs(r, expected, given, test, target, extraOptions)
|
||||
if given.exitCode != QuitFailure:
|
||||
r.addResult(test, target, extraOptions, "exitcode: " & $QuitFailure,
|
||||
maybeRetry r.finishTest(test, target, extraOptions, "exitcode: " & $QuitFailure,
|
||||
"exitcode: " & $given.exitCode & "\n\nOutput:\n" &
|
||||
given.nimout, reExitcodesDiffer)
|
||||
|
||||
@@ -532,7 +548,7 @@ proc targetHelper(r: var TResults, test: TTest, expected: TSpec, extraOptions: s
|
||||
for target in expected.targets:
|
||||
inc(r.total)
|
||||
if target notin gTargets:
|
||||
r.addResult(test, target, extraOptions, "", "", reDisabled)
|
||||
discard r.finishTest(test, target, extraOptions, "", "", reDisabled)
|
||||
inc(r.skipped)
|
||||
elif simulate:
|
||||
inc count
|
||||
@@ -546,7 +562,7 @@ proc testSpec(r: var TResults, test: TTest, targets: set[TTarget] = {}) =
|
||||
var expected = test.spec
|
||||
if expected.parseErrors.len > 0:
|
||||
# targetC is a lie, but a parameter is required
|
||||
r.addResult(test, targetC, "", "", expected.parseErrors, reInvalidSpec)
|
||||
discard r.finishTest(test, targetC, "", "", expected.parseErrors, reInvalidSpec)
|
||||
inc(r.total)
|
||||
return
|
||||
|
||||
|
||||
20
testament/tests/shouldfail/tnotenoughretries.nim
Normal file
20
testament/tests/shouldfail/tnotenoughretries.nim
Normal file
@@ -0,0 +1,20 @@
|
||||
discard """
|
||||
retries: 1
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
const tempFile = "tnotenoughretries_temp"
|
||||
|
||||
if not fileExists(tempFile):
|
||||
writeFile(tempFile, "abc")
|
||||
quit(1)
|
||||
else:
|
||||
let content = readFile(tempFile)
|
||||
if content == "abc":
|
||||
writeFile(tempFile, "def")
|
||||
quit(1)
|
||||
else:
|
||||
# success
|
||||
removeFile(tempFile)
|
||||
discard
|
||||
@@ -160,3 +160,16 @@ block:
|
||||
testCase()
|
||||
|
||||
main()
|
||||
|
||||
block: # bug #24147
|
||||
type
|
||||
O = object of RootObj
|
||||
val: string
|
||||
OO = object of O
|
||||
|
||||
proc `=copy`(dest: var O, src: O) =
|
||||
dest.val = src.val
|
||||
|
||||
let oo = OO(val: "hello world")
|
||||
var ooCopy : OO
|
||||
`=copy`(ooCopy, oo)
|
||||
|
||||
20
tests/arc/tnodestroyexplicithook.nim
Normal file
20
tests/arc/tnodestroyexplicithook.nim
Normal file
@@ -0,0 +1,20 @@
|
||||
# issue #24626
|
||||
|
||||
proc arrayWith2[T](y: T, size: static int): array[size, T] {.noinit, nodestroy, raises: [].} =
|
||||
## Creates a new array filled with `y`.
|
||||
for i in 0..size-1:
|
||||
when defined(nimHasDup):
|
||||
result[i] = `=dup`(y)
|
||||
else:
|
||||
wasMoved(result[i])
|
||||
`=copy`(result[i], y)
|
||||
|
||||
proc useArray(x: seq[int]) =
|
||||
var a = arrayWith2(x, 2)
|
||||
|
||||
proc main =
|
||||
let x = newSeq[int](100)
|
||||
for i in 0..5:
|
||||
useArray(x)
|
||||
|
||||
main()
|
||||
@@ -9,7 +9,8 @@ var
|
||||
try:
|
||||
x_cursor = ("hi", 5)
|
||||
if cond:
|
||||
x_cursor = ("different", 54) else:
|
||||
x_cursor = ("different", 54)
|
||||
else:
|
||||
x_cursor = ("string here", 80)
|
||||
echo [
|
||||
:tmpD = `$$`(x_cursor)
|
||||
|
||||
@@ -128,7 +128,8 @@ if dirExists(this.value):
|
||||
var :tmpD
|
||||
par = (dir:
|
||||
:tmpD = `=dup`(this.value)
|
||||
:tmpD, front: "") else:
|
||||
:tmpD, front: "")
|
||||
else:
|
||||
var
|
||||
:tmpD_1
|
||||
:tmpD_2
|
||||
|
||||
16
tests/arc/tvalgrind.nim
Normal file
16
tests/arc/tvalgrind.nim
Normal file
@@ -0,0 +1,16 @@
|
||||
discard """
|
||||
cmd: "nim c --mm:orc -d:useMalloc $file"
|
||||
valgrind: "true"
|
||||
"""
|
||||
|
||||
import std/streams
|
||||
|
||||
|
||||
proc foo() =
|
||||
var name = newStringStream("2r2")
|
||||
raise newException(ValueError, "sh")
|
||||
|
||||
try:
|
||||
foo()
|
||||
except:
|
||||
discard
|
||||
4
tests/array/tindexconv.nim
Normal file
4
tests/array/tindexconv.nim
Normal file
@@ -0,0 +1,4 @@
|
||||
block: # issue #17958
|
||||
var mem: array[uint8, uint8]
|
||||
let val = 0xffff'u16
|
||||
discard mem[uint8 val] # Error: unhandled exception: index 65535 not in 0 .. 255 [IndexDefect]
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
errormsg: "index 2 not in 0 .. 1"
|
||||
errormsg: "conversion from int literal(2) to range 0..1(int) is invalid"
|
||||
line: 18
|
||||
"""
|
||||
block:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
errormsg: "index 3 not in 0 .. 1"
|
||||
errormsg: "conversion from int literal(3) to range 0..1(int) is invalid"
|
||||
line: 9
|
||||
"""
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
discard """
|
||||
# doesn't work on macos 13 seemingly due to libc++ linking issue https://stackoverflow.com/a/77375947
|
||||
disabled: osx
|
||||
targets: cpp
|
||||
"""
|
||||
|
||||
@@ -18,21 +16,21 @@ proc initStdException(): CStdException {.importcpp: "std::exception()", construc
|
||||
proc fn() =
|
||||
let a = initRuntimeError("foo")
|
||||
doAssert $a.what == "foo"
|
||||
var b: cstring
|
||||
var b = ""
|
||||
try: raise initRuntimeError("foo2")
|
||||
except CStdException as e:
|
||||
doAssert e is CStdException
|
||||
b = e.what()
|
||||
doAssert $b == "foo2"
|
||||
b = $e.what()
|
||||
doAssert b == "foo2"
|
||||
|
||||
try: raise initStdException()
|
||||
except CStdException: discard
|
||||
|
||||
try: raise initRuntimeError("foo3")
|
||||
except CRuntimeError as e:
|
||||
b = e.what()
|
||||
b = $e.what()
|
||||
except CStdException:
|
||||
doAssert false
|
||||
doAssert $b == "foo3"
|
||||
doAssert b == "foo3"
|
||||
|
||||
fn()
|
||||
|
||||
@@ -6,3 +6,26 @@ type DistinctSeq* = distinct seq[int]
|
||||
# `=destroy`(cast[ptr DistinctSeq](0)[])
|
||||
var x = @[].DistinctSeq
|
||||
`=destroy`(x)
|
||||
|
||||
|
||||
import std/options
|
||||
|
||||
# bug #24801
|
||||
type
|
||||
B[T] = object
|
||||
case r: bool
|
||||
of false:
|
||||
v: ref int
|
||||
of true:
|
||||
x: T
|
||||
E = distinct seq[int]
|
||||
U = ref object of RootObj
|
||||
G = ref object of U
|
||||
|
||||
proc a(): E = default(E)
|
||||
method c(_: U): seq[E] {.base.} = discard
|
||||
proc p(): seq[E] = c(default(U))
|
||||
method c(_: G): seq[E] = discard E(newSeq[seq[int]](1)[0])
|
||||
method y(_: U) {.base.} =
|
||||
let s = default(B[tuple[f: B[int], w: B[int]]])
|
||||
discard some(s.x)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
discard """
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
# -*- nim -*-
|
||||
|
||||
import os, strutils
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
discard """
|
||||
outputsub: "true"
|
||||
disabled: "32bit"
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
type
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
discard """
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
# Program to detect bug #1796 reliably
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "no leak: "
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
type
|
||||
|
||||
@@ -6,6 +6,7 @@ Hello from thread
|
||||
Hello from thread
|
||||
'''
|
||||
cmd: "nim $target --hints:on --threads:on --tlsEmulation:off $options $file"
|
||||
retries: 2
|
||||
"""
|
||||
# Copied from stdlib
|
||||
import strutils
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "Success!"
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
# This is adapted from a benchmark written by John Ellis and Pete Kovac
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "77\n77"
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
## Check how GC/Alloc works in Emscripten
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "no leak: "
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
when defined(GC_setMaxPause):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "no leak: "
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
when defined(GC_setMaxPause):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "no leak: "
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
when defined(GC_setMaxPause):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "no leak: "
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
type
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
output: "success"
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
import os, times
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "finished"
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
# Test the garbage collector.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
discard """
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
import std/[cgi, strtabs]
|
||||
|
||||
proc handleRequest(query: string): StringTableRef =
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "no leak: "
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
type
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
outputsub: "no leak: "
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
type
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
joinable: false
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
import std/asyncdispatch
|
||||
|
||||
@@ -8,6 +8,7 @@ Performing Loop Recognition
|
||||
Another 3 iterations...
|
||||
...
|
||||
Found 1 loops (including artificial root node) (3)'''
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
# bug #3184
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
output: '''Success'''
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
# bug #3793
|
||||
|
||||
@@ -3,6 +3,7 @@ discard """
|
||||
10000000
|
||||
10000000
|
||||
10000000'''
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
# bug #17085
|
||||
|
||||
@@ -4,6 +4,7 @@ discard """
|
||||
finalized
|
||||
finalized
|
||||
'''
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
proc finish(o: RootRef) =
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
output: "true"
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
import intsets
|
||||
|
||||
7
tests/iter/ttypeofclosureiter.nim
Normal file
7
tests/iter/ttypeofclosureiter.nim
Normal file
@@ -0,0 +1,7 @@
|
||||
# issue #24859
|
||||
|
||||
template u(): int =
|
||||
yield 0
|
||||
0
|
||||
iterator s(): int {.closure.} = discard default(typeof(u()))
|
||||
let _ = s
|
||||
@@ -5,5 +5,6 @@ discard """
|
||||
"""
|
||||
|
||||
var s = ['a']
|
||||
let z = s[10000] == 'a'
|
||||
echo z
|
||||
let i = 10000
|
||||
let z = s[i] == 'a'
|
||||
echo z
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
discard """
|
||||
output: '''
|
||||
Hello World
|
||||
Hello World
|
||||
Hello World'''
|
||||
joinable: false
|
||||
"""
|
||||
@@ -8,7 +9,7 @@ type MyProc = proc() {.cdecl.}
|
||||
type MyProc2 = proc() {.nimcall.}
|
||||
type MyProc3 = proc() #{.closure.} is implicit
|
||||
|
||||
proc testProc() = echo "Hello World"
|
||||
proc testProc() {.exportc:"foo".} = echo "Hello World"
|
||||
|
||||
template reject(x) = doAssert(not compiles(x))
|
||||
|
||||
@@ -23,6 +24,10 @@ proc callPointer(p: pointer) =
|
||||
ffunc0()
|
||||
ffunc1()
|
||||
|
||||
# bug #5901
|
||||
proc foo() {.importc.}
|
||||
(cast[proc(a: int) {.cdecl.}](foo))(5)
|
||||
|
||||
callPointer(cast[pointer](testProc))
|
||||
|
||||
reject: discard cast[enum](0)
|
||||
|
||||
@@ -14,6 +14,10 @@ xxx test all tests/untestable/* here, possibly with adjustments to make running
|
||||
import std/[strformat,os,unittest,compilesettings]
|
||||
import stdtest/specialpaths
|
||||
|
||||
|
||||
from stdtest/testutils import disableSSLTesting
|
||||
|
||||
|
||||
const
|
||||
nim = getCurrentCompilerExe()
|
||||
mode = querySetting(backend)
|
||||
@@ -29,4 +33,5 @@ proc main =
|
||||
block: # SSL certificate check integration tests
|
||||
runCmd fmt"{nim} r {options} -d:ssl --threads:on --mm:refc {testsDir}/untestable/thttpclient_ssl_remotenetwork.nim"
|
||||
|
||||
main()
|
||||
when not disableSSLTesting():
|
||||
main()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
discard """
|
||||
action: compile
|
||||
disabled: "windows"
|
||||
disabled: osx
|
||||
"""
|
||||
|
||||
import sfml, os
|
||||
|
||||
30
tests/objects/t24847.nim
Normal file
30
tests/objects/t24847.nim
Normal file
@@ -0,0 +1,30 @@
|
||||
# issue #24847
|
||||
|
||||
block: # original issue test
|
||||
type
|
||||
R[C] = ref object of RootObj
|
||||
b: C
|
||||
K[S] = ref object of R[S]
|
||||
W[J] = object
|
||||
case y: bool
|
||||
of false, true: discard
|
||||
|
||||
proc e[T]() = discard K[T]()
|
||||
iterator h(): int {.closure.} = e[W[int]]()
|
||||
let _ = h
|
||||
type U = distinct int
|
||||
e[W[U]]()
|
||||
|
||||
block: # simplified
|
||||
type
|
||||
R[C] = ref object of RootObj
|
||||
b: C
|
||||
K[S] = ref object of R[S]
|
||||
W[J] = object
|
||||
case y: bool
|
||||
of false, true: discard
|
||||
|
||||
type U = distinct int
|
||||
|
||||
discard K[W[int]]()
|
||||
discard K[W[U]]()
|
||||
@@ -1,6 +1,7 @@
|
||||
discard """
|
||||
cmd: "nim $target --mm:refc -d:ssl $options $file"
|
||||
disabled: "openbsd"
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
# Nim - Basic SSL integration tests
|
||||
@@ -13,7 +14,10 @@ discard """
|
||||
## Test with:
|
||||
## ./bin/nim c -d:ssl -p:. --threads:on -r tests/stdlib/thttpclient_ssl.nim
|
||||
|
||||
when not defined(windows):
|
||||
|
||||
from stdtest/testutils import disableSSLTesting
|
||||
|
||||
when not defined(windows) and not disableSSLTesting():
|
||||
# Disabled on Windows due to old OpenSSL version
|
||||
import std/[formatfloat, syncio]
|
||||
import
|
||||
|
||||
@@ -6,6 +6,54 @@ import unittest, strutils
|
||||
|
||||
block: # parseutils
|
||||
check: parseBiggestUInt("0") == 0'u64
|
||||
check: parseBiggestUInt("1") == 1'u64
|
||||
check: parseBiggestUInt("2") == 2'u64
|
||||
check: parseBiggestUInt("10") == 10'u64
|
||||
check: parseBiggestUInt("11") == 11'u64
|
||||
check: parseBiggestUInt("99") == 99'u64
|
||||
check: parseBiggestUInt("123") == 123'u64
|
||||
check: parseBiggestUInt("9876") == 9876'u64
|
||||
check: parseBiggestUInt("1_234") == 1234'u64
|
||||
check: parseBiggestUInt("123__4") == 1234'u64
|
||||
for i in 1.BiggestUInt .. 9.BiggestUInt:
|
||||
var x = i
|
||||
for j in 1 .. 19:
|
||||
check parseBiggestUInt((i + '0'.uint).char.repeat j) == x
|
||||
x *= 10
|
||||
x += i
|
||||
check: parseBiggestUInt("18446744073709551609") == 0xFFFF_FFFF_FFFF_FFF9'u64
|
||||
check: parseBiggestUInt("18446744073709551610") == 0xFFFF_FFFF_FFFF_FFFA'u64
|
||||
check: parseBiggestUInt("18446744073709551611") == 0xFFFF_FFFF_FFFF_FFFB'u64
|
||||
check: parseBiggestUInt("18446744073709551612") == 0xFFFF_FFFF_FFFF_FFFC'u64
|
||||
check: parseBiggestUInt("18446744073709551613") == 0xFFFF_FFFF_FFFF_FFFD'u64
|
||||
check: parseBiggestUInt("18446744073709551614") == 0xFFFF_FFFF_FFFF_FFFE'u64
|
||||
check: parseBiggestUInt("18446744073709551615") == 0xFFFF_FFFF_FFFF_FFFF'u64
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551616")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551617")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551618")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551619")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551620")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551621")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551622")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551623")
|
||||
expect(ValueError):
|
||||
for i in 0 .. 999:
|
||||
discard parseBiggestUInt("18446744073709552" & intToStr(i, 3))
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("22751622367522324480000000")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("41404969074137497600000000")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("20701551093035827200000000000000000")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("225462255024603136000000000000000000")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("204963831854661632000000000000000000")
|
||||
|
||||
@@ -326,3 +326,27 @@ do:
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
import std/macros
|
||||
|
||||
# bug #24850
|
||||
macro a() =
|
||||
let
|
||||
y = quote do: discard
|
||||
b = nnkIfStmt.newTree(
|
||||
nnkElifExpr.newTree(ident "true", y), nnkElseExpr.newTree(y))
|
||||
d = nnkWhenStmt.newTree(
|
||||
nnkElifExpr.newTree(ident "true", y), nnkElseExpr.newTree(y))
|
||||
doAssert repr(b) == """
|
||||
if true:
|
||||
discard
|
||||
else:
|
||||
discard"""
|
||||
|
||||
doAssert repr(d) == """
|
||||
when true:
|
||||
discard
|
||||
else:
|
||||
discard"""
|
||||
|
||||
a()
|
||||
|
||||
5
tests/system/treprconverter.nim
Normal file
5
tests/system/treprconverter.nim
Normal file
@@ -0,0 +1,5 @@
|
||||
# issue #24864
|
||||
|
||||
type S = distinct uint16
|
||||
converter d(field: uint8 | uint16): S = discard
|
||||
discard (repr(0'u16), repr(0'u8))
|
||||
9
tests/template/tfielduse.nim
Normal file
9
tests/template/tfielduse.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
# issue #24657
|
||||
|
||||
proc g() {.error.} = discard
|
||||
|
||||
type T = object
|
||||
g: int
|
||||
|
||||
template B(): untyped = typeof(T.g)
|
||||
type _ = B()
|
||||
15
tests/template/tgenericobjconstr.nim
Normal file
15
tests/template/tgenericobjconstr.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
discard """
|
||||
matrix: "--skipParentCfg"
|
||||
"""
|
||||
|
||||
# issue #24631
|
||||
|
||||
type
|
||||
V[d: static bool] = object
|
||||
l: int
|
||||
|
||||
template y(): V[false] = V[false](l: 0)
|
||||
discard y()
|
||||
|
||||
template z(): V[false] = cast[V[false]](V[false](l: 0))
|
||||
discard z()
|
||||
20
tests/testament/tretries.nim
Normal file
20
tests/testament/tretries.nim
Normal file
@@ -0,0 +1,20 @@
|
||||
discard """
|
||||
retries: 2
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
const tempFile = "tretries_temp"
|
||||
|
||||
if not fileExists(tempFile):
|
||||
writeFile(tempFile, "abc")
|
||||
quit(1)
|
||||
else:
|
||||
let content = readFile(tempFile)
|
||||
if content == "abc":
|
||||
writeFile(tempFile, "def")
|
||||
quit(1)
|
||||
else:
|
||||
# success
|
||||
removeFile(tempFile)
|
||||
discard
|
||||
@@ -24,6 +24,8 @@ FAIL: tests/shouldfail/tnimout.nim
|
||||
Failure: reMsgsDiffer
|
||||
FAIL: tests/shouldfail/tnimoutfull.nim
|
||||
Failure: reMsgsDiffer
|
||||
FAIL: tests/shouldfail/tnotenoughretries.nim
|
||||
Failure: reExitcodesDiffer
|
||||
FAIL: tests/shouldfail/toutput.nim
|
||||
Failure: reOutputsDiffer
|
||||
FAIL: tests/shouldfail/toutputsub.nim
|
||||
@@ -43,7 +45,7 @@ import stdtest/testutils
|
||||
|
||||
proc main =
|
||||
const nim = getCurrentCompilerExe()
|
||||
let testamentExe = "bin/testament"
|
||||
let testamentExe = "testament/testament"
|
||||
let cmd = fmt"{testamentExe} --directory:testament --colors:off --backendLogging:off --nim:{nim} category shouldfail"
|
||||
let (outp, status) = execCmdEx(cmd)
|
||||
doAssert status == 1, $status
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
## nim r --putenv:NIM_TESTAMENT_REMOTE_NETWORKING:1 -d:nimDisableCertificateValidation -d:ssl -p:. tests/untestable/thttpclient_ssl_disabled.nim
|
||||
|
||||
from stdtest/testutils import enableRemoteNetworking
|
||||
when enableRemoteNetworking and (defined(nimTestsEnableFlaky) or not defined(openbsd)):
|
||||
# badssl tests disabled indefinitely
|
||||
when false and enableRemoteNetworking and (defined(nimTestsEnableFlaky) or not defined(openbsd)):
|
||||
import httpclient, net, unittest
|
||||
|
||||
const expired = "https://expired.badssl.com/"
|
||||
|
||||
@@ -19,7 +19,6 @@ from net import newSocket, newContext, wrapSocket, connect, close, Port,
|
||||
from strutils import contains
|
||||
|
||||
const
|
||||
expired = "https://expired.badssl.com/"
|
||||
good = "https://google.com/"
|
||||
|
||||
|
||||
@@ -56,12 +55,13 @@ suite "SSL certificate check":
|
||||
var ctx = newContext(verifyMode=CVerifyPeerUseEnvVars)
|
||||
ctx.wrapSocket(sock)
|
||||
checkpoint("Socket created")
|
||||
try:
|
||||
sock.connect("expired.badssl.com", 443.Port)
|
||||
fail()
|
||||
except:
|
||||
sock.close
|
||||
check getCurrentExceptionMsg().contains("certificate verify failed")
|
||||
when false: # badssl tests disabled indefinitely
|
||||
try:
|
||||
sock.connect("expired.badssl.com", 443.Port)
|
||||
fail()
|
||||
except:
|
||||
sock.close
|
||||
check getCurrentExceptionMsg().contains("certificate verify failed")
|
||||
|
||||
elif existsEnv("SSL_CERT_DIR"):
|
||||
var sock = newSocket()
|
||||
|
||||
@@ -33,7 +33,8 @@ when enableRemoteNetworking and (defined(nimTestsEnableFlaky) or not defined(win
|
||||
CertTest = tuple[url:string, category:Category, desc: string]
|
||||
|
||||
# badssl certs sometimes expire, set to false when that happens
|
||||
when true:
|
||||
# badssl now disabled indefinitely
|
||||
when false:
|
||||
const certificate_tests: array[0..54, CertTest] = [
|
||||
("https://wrong.host.badssl.com/", bad, "wrong.host"),
|
||||
("https://captive-portal.badssl.com/", bad, "captive-portal"),
|
||||
@@ -197,7 +198,7 @@ when enableRemoteNetworking and (defined(nimTestsEnableFlaky) or not defined(win
|
||||
|
||||
type NetSocketTest = tuple[hostname: string, port: Port, category:Category, desc: string]
|
||||
# badssl certs sometimes expire, set to false when that happens
|
||||
when true:
|
||||
when false:
|
||||
const net_tests:array[0..3, NetSocketTest] = [
|
||||
("imap.gmail.com", 993.Port, good, "IMAP"),
|
||||
("wrong.host.badssl.com", 443.Port, bad, "wrong.host"),
|
||||
|
||||
79
tests/vm/tconststaticvar.nim
Normal file
79
tests/vm/tconststaticvar.nim
Normal file
@@ -0,0 +1,79 @@
|
||||
block: # issue #8758
|
||||
template baz() =
|
||||
var i = 0
|
||||
|
||||
proc foo() =
|
||||
static:
|
||||
var i = 0
|
||||
baz()
|
||||
|
||||
block: # issue #10828
|
||||
proc test(i: byte): bool =
|
||||
const SET = block: # No issues when defined outside proc
|
||||
var s: set[byte]
|
||||
for i in 0u8 .. 255u8: incl(s, i)
|
||||
s
|
||||
return i in SET
|
||||
doAssert test(0)
|
||||
doAssert test(127)
|
||||
doAssert test(255)
|
||||
|
||||
block: # issue #12172
|
||||
const TEST = block:
|
||||
var test: array[5, string]
|
||||
for i in low(test)..high(test):
|
||||
test[i] = $i
|
||||
test
|
||||
proc test =
|
||||
const TEST2 = block:
|
||||
var test: array[5, string] # Error here
|
||||
for i in low(test)..high(test):
|
||||
test[i] = $i
|
||||
test
|
||||
doAssert TEST == TEST2
|
||||
doAssert TEST == @["0", "1", "2", "3", "4"]
|
||||
doAssert TEST2 == @["0", "1", "2", "3", "4"]
|
||||
test()
|
||||
|
||||
block: # issue #21610
|
||||
func stuff(): int =
|
||||
const r = block:
|
||||
var r = 1 # Error: cannot evaluate at compile time: r
|
||||
for i in 2..10:
|
||||
r *= i
|
||||
r
|
||||
r
|
||||
doAssert stuff() == 3628800
|
||||
|
||||
block: # issue #23803
|
||||
func foo1(c: int): int {.inline.} =
|
||||
const arr = block:
|
||||
var res: array[0..99, int]
|
||||
res[42] = 43
|
||||
res
|
||||
arr[c]
|
||||
doAssert foo1(41) == 0
|
||||
doAssert foo1(42) == 43
|
||||
doAssert foo1(43) == 0
|
||||
|
||||
# works
|
||||
func foo2(c: int): int {.inline.} =
|
||||
func initArr(): auto =
|
||||
var res: array[0..99, int]
|
||||
res[42] = 43
|
||||
res
|
||||
const arr = initArr()
|
||||
arr[c]
|
||||
doAssert foo2(41) == 0
|
||||
doAssert foo2(42) == 43
|
||||
doAssert foo2(43) == 0
|
||||
|
||||
# also works
|
||||
const globalArr = block:
|
||||
var res: array[0..99, int]
|
||||
res[42] = 43
|
||||
res
|
||||
func foo3(c: int): int {.inline.} = globalArr[c]
|
||||
doAssert foo3(41) == 0
|
||||
doAssert foo3(42) == 43
|
||||
doAssert foo3(43) == 0
|
||||
13
tests/vm/tconststaticvar2.nim
Normal file
13
tests/vm/tconststaticvar2.nim
Normal file
@@ -0,0 +1,13 @@
|
||||
# issue #24634
|
||||
|
||||
type J = object
|
||||
|
||||
template m(u: J): int =
|
||||
let v = u
|
||||
0
|
||||
|
||||
proc g() =
|
||||
const x = J()
|
||||
const _ = m(x)
|
||||
|
||||
g()
|
||||
9
tests/vm/tconststaticvar3.nim
Normal file
9
tests/vm/tconststaticvar3.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
# issue #24633
|
||||
|
||||
import std/sequtils
|
||||
|
||||
proc f(a: static openArray[int]) =
|
||||
const s1 = a.mapIt(it)
|
||||
const s2 = a.toSeq()
|
||||
|
||||
f([1,2,3])
|
||||
6
tests/vm/tconststaticvar_wrong.nim
Normal file
6
tests/vm/tconststaticvar_wrong.nim
Normal file
@@ -0,0 +1,6 @@
|
||||
proc test =
|
||||
const TEST = block:
|
||||
let i = 1
|
||||
const j = i + 1 #[tt.Error
|
||||
^ cannot evaluate at compile time: i]#
|
||||
j
|
||||
@@ -67,3 +67,12 @@ template fn=
|
||||
doAssert test([0,1,2,3,4,5]).id == 0
|
||||
fn() # ok
|
||||
static: fn()
|
||||
|
||||
block: # bug #24630
|
||||
func f(a: static openArray[int]): int =
|
||||
12
|
||||
|
||||
func g(a: static openArray[int]) =
|
||||
const b = f(a)
|
||||
|
||||
g(@[1,2,3])
|
||||
|
||||
@@ -353,7 +353,7 @@ block: # bug #8007
|
||||
block: # bug #14340
|
||||
block:
|
||||
proc opl3EnvelopeCalcSin0() = discard
|
||||
type EnvelopeSinfunc = proc()
|
||||
type EnvelopeSinfunc = proc() {.nimcall.} # todo: fixme
|
||||
# const EnvelopeCalcSin0 = opl3EnvelopeCalcSin0 # ok
|
||||
const EnvelopeCalcSin0: EnvelopeSinfunc = opl3EnvelopeCalcSin0 # was bug
|
||||
const envelopeSin = [EnvelopeCalcSin0]
|
||||
|
||||
Reference in New Issue
Block a user