mirror of
https://github.com/nim-lang/Nim.git
synced 2026-09-01 11:23:40 +00:00
Compare commits
54 Commits
v2.0.14
...
version-2-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
336dc9d827 | ||
|
|
3fe329dbd1 | ||
|
|
9ef34c3589 | ||
|
|
fda07a76fd | ||
|
|
19dc02e1bb | ||
|
|
0a6f1b44dc | ||
|
|
a837ee7800 | ||
|
|
2fbb793f4e | ||
|
|
edeac84e47 | ||
|
|
d2b8c3c0d5 | ||
|
|
10564f25b3 | ||
|
|
fbc7e54e95 | ||
|
|
7f3dbd5656 | ||
|
|
71f3e100b6 | ||
|
|
d2cb099e44 | ||
|
|
7e51e48cac | ||
|
|
19c89622ca | ||
|
|
b1d9af4d5f | ||
|
|
c467532484 | ||
|
|
114d0b8bdc | ||
|
|
f8ce7ddd6d | ||
|
|
cd6dbbd7f3 | ||
|
|
acac0bc1f2 | ||
|
|
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 |
16
.github/workflows/bisects.yml
vendored
16
.github/workflows/bisects.yml
vendored
@@ -8,12 +8,18 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
# nimrun-action requires Nim installed.
|
||||
- uses: jiro4989/setup-nim-action@v1
|
||||
with:
|
||||
nim-version: 'devel'
|
||||
- name: Install OpenSSL (Windows)
|
||||
if: |
|
||||
runner.os == 'Windows'
|
||||
run: choco install openssl.light --version=1.1.1.0 # OpenSSL 3.x removed SSL_library_init
|
||||
shell: 'powershell'
|
||||
|
||||
# v2 wont work here, because uses "hardcoded" nim versions, action "dynamically" finds version with bug.
|
||||
- uses: jiro4989/setup-nim-action@v1
|
||||
with:
|
||||
nim-version: 'devel'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt-get install --no-install-recommends -yq valgrind
|
||||
|
||||
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 }}
|
||||
|
||||
8
.github/workflows/ci_docs.yml
vendored
8
.github/workflows/ci_docs.yml
vendored
@@ -43,11 +43,11 @@ jobs:
|
||||
target: [linux, windows, osx]
|
||||
include:
|
||||
- target: linux
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-22.04
|
||||
- target: windows
|
||||
os: windows-2019
|
||||
- target: osx
|
||||
os: macos-13
|
||||
os: macos-15
|
||||
|
||||
name: ${{ matrix.target }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
if: |
|
||||
github.event_name == 'push' && github.ref == 'refs/heads/devel' &&
|
||||
matrix.target == 'linux'
|
||||
uses: crazy-max/ghaction-github-pages@v3
|
||||
uses: crazy-max/ghaction-github-pages@v5
|
||||
with:
|
||||
build_dir: doc/html
|
||||
env:
|
||||
|
||||
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
|
||||
22
.github/workflows/ci_packages.yml
vendored
22
.github/workflows/ci_packages.yml
vendored
@@ -17,9 +17,13 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-13]
|
||||
cpu: [amd64]
|
||||
os: [ubuntu-latest, macos-14]
|
||||
batch: ["allowed_failures", "0_3", "1_3", "2_3"] # list of `index_num`
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
cpu: amd64
|
||||
- os: macos-14
|
||||
cpu: arm64
|
||||
name: '${{ matrix.os }} (batch: ${{ matrix.batch }})'
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60 # refs bug #18178
|
||||
@@ -28,23 +32,23 @@ jobs:
|
||||
NIM_TESTAMENT_BATCH: ${{ matrix.batch }}
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 'Install node.js 20.x'
|
||||
uses: actions/setup-node@v4
|
||||
- name: 'Install node.js'
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version: 24
|
||||
|
||||
- name: 'Install dependencies (Linux amd64)'
|
||||
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
|
||||
run: |
|
||||
sudo apt-fast update -qq
|
||||
sudo apt-get update -qq
|
||||
DEBIAN_FRONTEND='noninteractive' \
|
||||
sudo apt-fast install --no-install-recommends -yq \
|
||||
sudo apt-get install --no-install-recommends -yq \
|
||||
libcurl4-openssl-dev libgc-dev libsdl1.2-dev libsfml-dev \
|
||||
valgrind libc6-dbg libblas-dev xorg-dev
|
||||
valgrind libc6-dbg libblas-dev liblapack-dev libpcre3 xorg-dev
|
||||
- name: 'Install dependencies (macOS)'
|
||||
if: runner.os == 'macOS'
|
||||
run: brew install boehmgc make sfml gtk+3
|
||||
|
||||
24
.github/workflows/ci_publish.yml
vendored
24
.github/workflows/ci_publish.yml
vendored
@@ -11,20 +11,20 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04]
|
||||
os: [ubuntu-22.04]
|
||||
cpu: [amd64]
|
||||
name: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 'Install node.js 20.x'
|
||||
uses: actions/setup-node@v4
|
||||
- name: 'Install node.js'
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version: 24
|
||||
|
||||
- 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
|
||||
@@ -71,7 +60,7 @@ jobs:
|
||||
run: nim c -r -d:release ci/action.nim
|
||||
|
||||
- name: 'Comment'
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
@@ -87,4 +76,3 @@ jobs:
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v8
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
days-before-pr-stale: 365
|
||||
days-before-pr-close: 30
|
||||
|
||||
@@ -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:
|
||||
@@ -28,24 +28,24 @@ jobs:
|
||||
# # g++-multilib : Depends: gcc-multilib (>= 4:5.3.1-1ubuntu1) but it is not going to be installed
|
||||
# vmImage: 'ubuntu-18.04'
|
||||
# CPU: i386
|
||||
OSX_amd64:
|
||||
vmImage: 'macOS-13'
|
||||
CPU: amd64
|
||||
OSX_amd64_cpp:
|
||||
vmImage: 'macOS-13'
|
||||
CPU: amd64
|
||||
OSX_arm64:
|
||||
vmImage: 'macos-15'
|
||||
CPU: arm64
|
||||
OSX_arm64_cpp:
|
||||
vmImage: 'macos-15'
|
||||
CPU: arm64
|
||||
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
|
||||
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
slots when enlarging a sequence.
|
||||
- Added `hasDefaultValue` to `std/typetraits` to check if a type has a valid default value.
|
||||
- Added Viewport API for the JavaScript targets in the `dom` module.
|
||||
- Added `toSinglyLinkedRing` and `toDoublyLinkedRing` to `std/lists` to convert from `openArray`s.
|
||||
- ORC: To be enabled via `nimOrcStats` there is a new API called `GC_orcStats` that can be used to query how many
|
||||
objects the cyclic collector did free. If the number is zero that is a strong indicator that you can use `--mm:arc`
|
||||
instead of `--mm:orc`.
|
||||
- A `$` template is provided for `Path` in `std/paths`.
|
||||
|
||||
[//]: # "Deprecations:"
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -217,17 +217,38 @@ proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode; enforceDefaultOp: bool,
|
||||
fillBodyObj(c, n[0], body, x, y, enforceDefaultOp = false)
|
||||
c.filterDiscriminator = oldfilterDiscriminator
|
||||
of nkRecList:
|
||||
for t in items(n): fillBodyObj(c, t, body, x, y, enforceDefaultOp, enforceWasMoved)
|
||||
# destroys in reverse order #24719
|
||||
if c.kind == attachedDestructor:
|
||||
for i in countdown(n.len-1, 0):
|
||||
fillBodyObj(c, n[i], body, x, y, enforceDefaultOp, enforceWasMoved)
|
||||
else:
|
||||
for t in items(n): fillBodyObj(c, t, body, x, y, enforceDefaultOp, enforceWasMoved)
|
||||
else:
|
||||
illFormedAstLocal(n, c.g.config)
|
||||
|
||||
proc fillBodyObjTImpl(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||
if t.len > 0 and t[0] != nil:
|
||||
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)
|
||||
fillBodyObj(c, t.n, body, x, y, enforceDefaultOp = false)
|
||||
template fillBase =
|
||||
if t.len > 0 and t[0] != nil:
|
||||
let dest = newNodeIT(nkHiddenSubConv, c.info, t[0])
|
||||
dest.add newNodeI(nkEmpty, c.info)
|
||||
dest.add x
|
||||
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, dest, src)
|
||||
template fillFields =
|
||||
fillBodyObj(c, t.n, body, x, y, enforceDefaultOp = false)
|
||||
|
||||
if c.kind == attachedDestructor:
|
||||
# destroys in reverse order #24719
|
||||
fillFields()
|
||||
fillBase()
|
||||
else:
|
||||
fillBase()
|
||||
fillFields()
|
||||
|
||||
proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||
var hasCase = isCaseObj(t.n)
|
||||
@@ -1036,9 +1057,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 +1096,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 +1106,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 +1148,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)
|
||||
@@ -1169,7 +1188,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
fillStrOp(a, typ, result.ast[bodyPos], d, src)
|
||||
else:
|
||||
fillBody(a, typ, result.ast[bodyPos], d, src)
|
||||
if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy, attachedDup} and not lacksMTypeField(typ):
|
||||
if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy, attachedDup} and not isObjLackingTypeField(typ):
|
||||
# bug #19205: Do not forget to also copy the hidden type field:
|
||||
genTypeFieldCopy(a, typ, result.ast[bodyPos], d, src)
|
||||
|
||||
@@ -1179,6 +1198,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:
|
||||
|
||||
@@ -1345,7 +1345,9 @@ proc readTypeParameter(c: PContext, typ: PType,
|
||||
# This seems semantically correct and then we'll be able
|
||||
# to return the section symbol directly here
|
||||
let foundType = makeTypeDesc(c, def[2].typ)
|
||||
return newSymNode(copySym(def[0].sym, c.idgen).linkTo(foundType), info)
|
||||
let s = copySym(def[0].sym, c.idgen)
|
||||
s.typ = foundType
|
||||
return newSymNode(s, info)
|
||||
|
||||
of nkConstSection:
|
||||
for def in statement:
|
||||
@@ -1370,7 +1372,9 @@ proc readTypeParameter(c: PContext, typ: PType,
|
||||
return c.graph.emptyNode
|
||||
else:
|
||||
let foundTyp = makeTypeDesc(c, rawTyp)
|
||||
return newSymNode(copySym(tParam.sym, c.idgen).linkTo(foundTyp), info)
|
||||
let s = copySym(tParam.sym, c.idgen)
|
||||
s.typ = foundTyp
|
||||
return newSymNode(s, info)
|
||||
|
||||
return nil
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1425,6 +1425,17 @@ proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
|
||||
a = a[i]
|
||||
result = a.kind == last
|
||||
|
||||
proc lacksMTypeField*(typ: PType): bool {.inline.} =
|
||||
## Returns true if the type is an object that lacks a m_type field.
|
||||
## It doesn't check base classes.
|
||||
(typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags
|
||||
|
||||
proc isObjLackingTypeField*(typ: PType): bool {.inline.} =
|
||||
## Returns true if the type is an object that lacks a type field.
|
||||
## Object types that store type headers are not final or pure and
|
||||
## have inheritable root types, which are not pure, neither.
|
||||
result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and
|
||||
(typ.baseClass == nil) or isPureObject(typ))
|
||||
|
||||
include sizealignoffsetimpl
|
||||
|
||||
@@ -1867,6 +1878,3 @@ proc isCharArrayPtr*(t: PType; allowPointerToChar: bool): bool =
|
||||
result = allowPointerToChar
|
||||
else:
|
||||
discard
|
||||
|
||||
proc lacksMTypeField*(typ: PType): bool {.inline.} =
|
||||
(typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags
|
||||
|
||||
@@ -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,
|
||||
@@ -1837,7 +1837,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen)
|
||||
else:
|
||||
stackTrace(c, tos, pc, "node has no type")
|
||||
else:
|
||||
of 3:
|
||||
# getTypeImpl opcode:
|
||||
ensureKind(rkNode)
|
||||
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
|
||||
@@ -1846,6 +1846,15 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen)
|
||||
else:
|
||||
stackTrace(c, tos, pc, "node has no type")
|
||||
else:
|
||||
# getTypeInstSkipAlias opcode:
|
||||
ensureKind(rkNode)
|
||||
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.typ, c.debug[pc], c.idgen, skipAlias = true)
|
||||
elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen, skipAlias = true)
|
||||
else:
|
||||
stackTrace(c, tos, pc, "node has no type")
|
||||
of opcNGetSize:
|
||||
decodeBImm(rkInt)
|
||||
let n = regs[rb].node
|
||||
@@ -2375,8 +2384,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
|
||||
|
||||
@@ -40,7 +40,7 @@ proc atomicTypeX(s: PSym; info: TLineInfo): PNode =
|
||||
result.info = info
|
||||
|
||||
proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator;
|
||||
inst=false; allowRecursionX=false): PNode
|
||||
inst=false; allowRecursionX=false; skipAlias = false): PNode
|
||||
|
||||
proc mapTypeToBracketX(cache: IdentCache; name: string; m: TMagic; t: PType; info: TLineInfo;
|
||||
idgen: IdGenerator;
|
||||
@@ -68,7 +68,7 @@ proc objectNode(cache: IdentCache; n: PNode; idgen: IdGenerator): PNode =
|
||||
|
||||
proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
idgen: IdGenerator;
|
||||
inst=false; allowRecursionX=false): PNode =
|
||||
inst=false; allowRecursionX=false; skipAlias = false): PNode =
|
||||
var allowRecursion = allowRecursionX
|
||||
template atomicType(name, m): untyped = atomicTypeX(cache, name, m, t, info, idgen)
|
||||
template atomicType(s): untyped = atomicTypeX(s, info)
|
||||
@@ -89,7 +89,8 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
id
|
||||
template newIdentDefs(s): untyped = newIdentDefs(s, s.typ)
|
||||
|
||||
if inst and not allowRecursion and t.sym != nil:
|
||||
if inst and not allowRecursion and t.sym != nil and
|
||||
not (skipAlias and t.kind == tyAlias):
|
||||
# getTypeInst behavior: return symbol
|
||||
return atomicType(t.sym)
|
||||
|
||||
@@ -122,7 +123,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
if t.base != nil:
|
||||
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
|
||||
result.add atomicType("typeDesc", mTypeDesc)
|
||||
result.add mapTypeToAst(t.base, info)
|
||||
result.add mapTypeToAstX(cache, t.base, info, idgen, inst, skipAlias = skipAlias)
|
||||
else:
|
||||
result = atomicType("typeDesc", mTypeDesc)
|
||||
of tyGenericInvocation:
|
||||
@@ -151,7 +152,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
else:
|
||||
result = mapTypeToAst(t.lastSon, info)
|
||||
of tyAlias:
|
||||
result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion)
|
||||
result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion, skipAlias = skipAlias)
|
||||
of tyOrdinal:
|
||||
result = mapTypeToAst(t.lastSon, info)
|
||||
of tyDistinct:
|
||||
@@ -316,8 +317,9 @@ proc opMapTypeToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGene
|
||||
|
||||
# the "Inst" version includes generic parameters in the resulting type tree
|
||||
# and also tries to look like the corresponding Nim type declaration
|
||||
proc opMapTypeInstToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator): PNode =
|
||||
result = mapTypeToAstX(cache, t, info, idgen, inst=true, allowRecursionX=false)
|
||||
proc opMapTypeInstToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator; skipAlias = false): PNode =
|
||||
# skipAlias: skips aliases and typedesc
|
||||
result = mapTypeToAstX(cache, t, info, idgen, inst=true, allowRecursionX=false, skipAlias = skipAlias)
|
||||
|
||||
# the "Impl" version includes generic parameters in the resulting type tree
|
||||
# and also tries to look like the corresponding Nim type implementation
|
||||
|
||||
@@ -1324,7 +1324,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}, m: TMag
|
||||
of "getType": 0
|
||||
of "typeKind": 1
|
||||
of "getTypeInst": 2
|
||||
else: 3 # "getTypeImpl"
|
||||
of "getTypeImpl": 3 # "getTypeImpl"
|
||||
else: 4 # getTypeInstSkipAlias
|
||||
c.gABC(n, opcNGetType, dest, tmp, rc)
|
||||
c.freeTemp(tmp)
|
||||
#genUnaryABC(c, n, dest, opcNGetType)
|
||||
@@ -1559,6 +1560,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 +1950,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 +2015,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()
|
||||
```
|
||||
|
||||
6
koch.nim
6
koch.nim
@@ -11,13 +11,13 @@
|
||||
|
||||
const
|
||||
# examples of possible values for repos: Head, ea82b54
|
||||
NimbleStableCommit = "123f97a5e4ee9ba35720c0869e19a047c43c797e" # 0.16.4
|
||||
NimbleStableCommit = "9207e8b2bbdf66b5a4d1020214cff44d2d30df92" # 0.20.1
|
||||
AtlasStableCommit = "5faec3e9a33afe99a7d22377dd1b45a5391f5504"
|
||||
ChecksumsStableCommit = "bd9bf4eaea124bf8d01e08f92ac1b14c6879d8d3"
|
||||
ChecksumsStableCommit = "f8f6bd34bfa3fe12c64b919059ad856a96efcba0" # 2.0.1
|
||||
SatStableCommit = "faf1617f44d7632ee9601ebc13887644925dcc01"
|
||||
|
||||
# examples of possible values for fusion: #head, #ea82b54, 1.2.3
|
||||
FusionStableHash = "#372ee4313827ef9f2ea388840f7d6b46c2b1b014"
|
||||
FusionStableHash = "#562467452b32cb7a97410ea177f083e6d8405734"
|
||||
HeadHash = "#head"
|
||||
when not defined(windows):
|
||||
const
|
||||
|
||||
@@ -1574,10 +1574,13 @@ proc extractTypeImpl(n: NimNode): NimNode =
|
||||
result = n[2]
|
||||
else: error("Invalid node to retrieve type implementation of: " & $n.kind)
|
||||
|
||||
|
||||
proc getTypeInstSkipAlias(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
|
||||
|
||||
proc customPragmaNode(n: NimNode): NimNode =
|
||||
expectKind(n, {nnkSym, nnkDotExpr, nnkBracketExpr, nnkTypeOfExpr, nnkType, nnkCheckedFieldExpr})
|
||||
let
|
||||
typ = n.getTypeInst()
|
||||
|
||||
let typ = n.getTypeInstSkipAlias()
|
||||
|
||||
if typ.kind == nnkBracketExpr and typ.len > 1 and typ[1].kind == nnkProcTy:
|
||||
return typ[1][1]
|
||||
|
||||
@@ -215,6 +215,11 @@ when defined(osx): # 2001 POSIX evidently does not concern Apple
|
||||
# present size & has no good reason to call this unless it is growing.
|
||||
if fcntl(a1, F_PREALLOCATE, fst.addr) != cint(-1): ftruncate(a1, a2 + a3)
|
||||
else: cint(-1)
|
||||
elif defined(openbsd):
|
||||
proc posix_fallocate*(a1: cint, a2, a3: Off): cint =
|
||||
# above assumption: "has no good reason to call this unless it is growing."
|
||||
# man ftruncate "it will be extended as if by writing bytes with the value zero."
|
||||
return ftruncate(a1, a2 + a3)
|
||||
else:
|
||||
proc posix_fallocate*(a1: cint, a2, a3: Off): cint {.
|
||||
importc, header: "<fcntl.h>".}
|
||||
|
||||
@@ -152,7 +152,7 @@ proc parseProtocol(protocol: string): tuple[orig: string, major, minor: int] =
|
||||
protocol)
|
||||
result.orig = protocol
|
||||
i.inc protocol.parseSaturatedNatural(result.major, i)
|
||||
i.inc # Skip .
|
||||
if i < protocol.len: inc i # Skip .
|
||||
i.inc protocol.parseSaturatedNatural(result.minor, i)
|
||||
|
||||
proc sendStatus(client: AsyncSocket, status: string): Future[void] =
|
||||
|
||||
@@ -710,6 +710,8 @@ proc remove*[T](L: var SinglyLinkedList[T], n: SinglyLinkedNode[T]): bool {.disc
|
||||
L.head = n.next
|
||||
if L.tail.next == n:
|
||||
L.tail.next = L.head # restore cycle
|
||||
if L.tail == n:
|
||||
L.tail = nil # reset tail if we removed the last node
|
||||
else:
|
||||
var prev = L.head
|
||||
while prev.next != n and prev.next != nil:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -25,6 +25,9 @@ export ReadDirEffect, WriteDirEffect
|
||||
type
|
||||
Path* = distinct string
|
||||
|
||||
template `$`*(x: Path): string =
|
||||
string(x)
|
||||
|
||||
func `==`*(x, y: Path): bool {.inline.} =
|
||||
## Compares two paths.
|
||||
##
|
||||
|
||||
@@ -14,6 +14,8 @@ at offset 0 then. The ``ref`` object header is independent from the
|
||||
runtime type and only contains a reference count.
|
||||
]#
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
when defined(gcOrc):
|
||||
const
|
||||
rcIncrement = 0b10000 # so that lowest 4 bits are not touched
|
||||
@@ -72,6 +74,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 +178,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)
|
||||
@@ -236,3 +241,5 @@ template tearDownForeignThreadGc* =
|
||||
|
||||
proc isObjDisplayCheck(source: PNimTypeV2, targetDepth: int16, token: uint32): bool {.compilerRtl, inl.} =
|
||||
result = targetDepth <= source.depth and source.display[targetDepth] == token
|
||||
|
||||
{.pop.} # raises: []
|
||||
|
||||
@@ -252,12 +252,12 @@ iterator elementsExcept(t, s: CellSet): PCell {.inline.} =
|
||||
var r = t.head
|
||||
while r != nil:
|
||||
let ss = cellSetGet(s, r.key)
|
||||
var i:uint = 0
|
||||
var i = 0'u
|
||||
while int(i) <= high(r.bits):
|
||||
var w = r.bits[i]
|
||||
if ss != nil:
|
||||
w = w and not ss.bits[i]
|
||||
var j:uint = 0
|
||||
var j = 0'u
|
||||
while w != 0:
|
||||
if (w and 1) != 0:
|
||||
yield cast[PCell]((r.key shl PageShift) or
|
||||
|
||||
@@ -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 = 17
|
||||
## is the patch number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@ const
|
||||
colorMask = 0b011
|
||||
|
||||
type
|
||||
TraceProc = proc (p, env: pointer) {.nimcall, benign.}
|
||||
DisposeProc = proc (p: pointer) {.nimcall, benign.}
|
||||
TraceProc = proc (p, env: pointer) {.nimcall, benign, raises: [].}
|
||||
DisposeProc = proc (p: pointer) {.nimcall, benign, raises: [].}
|
||||
|
||||
template color(c): untyped = c.rc and colorMask
|
||||
template setColor(c, col) =
|
||||
|
||||
@@ -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) =
|
||||
|
||||
@@ -60,6 +60,7 @@ comparisons).
|
||||
]#
|
||||
|
||||
{.push profiler:off.}
|
||||
{.push raises: [].}
|
||||
|
||||
const
|
||||
CycleIncrease = 2 # is a multiplicative increase
|
||||
@@ -595,7 +596,13 @@ proc sweep(gch: var GcHeap) =
|
||||
if isCell(x):
|
||||
# cast to PCell is correct here:
|
||||
var c = cast[PCell](x)
|
||||
if c notin gch.marked: freeCyclicCell(gch, c)
|
||||
if c notin gch.marked:
|
||||
# Don't free objects that have the ZctFlag set (created in finalizers)
|
||||
if (c.refcount and ZctFlag) == 0:
|
||||
freeCyclicCell(gch, c)
|
||||
else:
|
||||
# Clear the ZctFlag for the next collection cycle
|
||||
c.refcount = c.refcount and not ZctFlag
|
||||
|
||||
proc markS(gch: var GcHeap, c: PCell) =
|
||||
gcAssert isAllocatedPtr(gch.region, c), "markS: foreign heap root detected A!"
|
||||
@@ -906,4 +913,5 @@ when not defined(useNimRtl):
|
||||
result.add "[GC] stack bottom: " & gch.stack.bottom.repr
|
||||
result.add "[GC] max stack size: " & $gch.stat.maxStackSize & "\n"
|
||||
|
||||
{.pop.} # raises: []
|
||||
{.pop.} # profiler: off, stackTrace: off
|
||||
|
||||
@@ -25,33 +25,33 @@ when hasAlloc and not defined(js) and not usesDestructors:
|
||||
proc GC_enable*() {.rtl, inl, benign, raises: [].}
|
||||
## Enables the GC again.
|
||||
|
||||
proc GC_fullCollect*() {.rtl, benign.}
|
||||
proc GC_fullCollect*() {.rtl, benign, raises: [].}
|
||||
## Forces a full garbage collection pass.
|
||||
## Ordinary code does not need to call this (and should not).
|
||||
|
||||
proc GC_enableMarkAndSweep*() {.rtl, benign.}
|
||||
proc GC_disableMarkAndSweep*() {.rtl, benign.}
|
||||
proc GC_enableMarkAndSweep*() {.rtl, benign, raises: [].}
|
||||
proc GC_disableMarkAndSweep*() {.rtl, benign, raises: [].}
|
||||
## The current implementation uses a reference counting garbage collector
|
||||
## with a seldomly run mark and sweep phase to free cycles. The mark and
|
||||
## sweep phase may take a long time and is not needed if the application
|
||||
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
||||
## and activated separately from the rest of the GC.
|
||||
|
||||
proc GC_getStatistics*(): string {.rtl, benign.}
|
||||
proc GC_getStatistics*(): string {.rtl, benign, raises: [].}
|
||||
## Returns an informative string about the GC's activity. This may be useful
|
||||
## for tweaking.
|
||||
|
||||
proc GC_ref*[T](x: ref T) {.magic: "GCref", benign.}
|
||||
proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign.}
|
||||
proc GC_ref*(x: string) {.magic: "GCref", benign.}
|
||||
proc GC_ref*[T](x: ref T) {.magic: "GCref", benign, raises: [].}
|
||||
proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign, raises: [].}
|
||||
proc GC_ref*(x: string) {.magic: "GCref", benign, raises: [].}
|
||||
## Marks the object `x` as referenced, so that it will not be freed until
|
||||
## it is unmarked via `GC_unref`.
|
||||
## If called n-times for the same object `x`,
|
||||
## n calls to `GC_unref` are needed to unmark `x`.
|
||||
|
||||
proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign.}
|
||||
proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign.}
|
||||
proc GC_unref*(x: string) {.magic: "GCunref", benign.}
|
||||
proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign, raises: [].}
|
||||
proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign, raises: [].}
|
||||
proc GC_unref*(x: string) {.magic: "GCunref", benign, raises: [].}
|
||||
## See the documentation of `GC_ref <#GC_ref,string>`_.
|
||||
|
||||
proc nimGC_setStackBottom*(theStackBottom: pointer) {.compilerRtl, noinline, benign, raises: [].}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
# R.D. Lins / Information Processing Letters 109 (2008) 71–78
|
||||
#
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
include cellseqs_v2
|
||||
|
||||
const
|
||||
@@ -27,8 +29,8 @@ const
|
||||
logOrc = defined(nimArcIds)
|
||||
|
||||
type
|
||||
TraceProc = proc (p, env: pointer) {.nimcall, benign.}
|
||||
DisposeProc = proc (p: pointer) {.nimcall, benign.}
|
||||
TraceProc = proc (p, env: pointer) {.nimcall, benign, raises: [].}
|
||||
DisposeProc = proc (p: pointer) {.nimcall, benign, raises: [].}
|
||||
|
||||
template color(c): untyped = c.rc and colorMask
|
||||
template setColor(c, col) =
|
||||
@@ -520,3 +522,5 @@ proc nimDecRefIsLastCyclicStatic(p: pointer; desc: PNimTypeV2): bool {.compilerR
|
||||
dec cell.rc, rcIncrement
|
||||
#if cell.color == colPurple:
|
||||
rememberCycle(result, cell, desc)
|
||||
|
||||
{.pop.} # raises: []
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -61,15 +61,25 @@ elif defined(netbsd):
|
||||
result = threadId
|
||||
|
||||
elif defined(freebsd):
|
||||
proc syscall(arg: cint, arg0: ptr cint): cint {.varargs, importc: "syscall", header: "<unistd.h>".}
|
||||
var SYS_thr_self {.importc:"SYS_thr_self", header:"<sys/syscall.h>".}: cint
|
||||
when defined(amd64) or defined(i386):
|
||||
const SYS_thr_self = 432
|
||||
else:
|
||||
var SYS_thr_self {.importc:"SYS_thr_self", header:"<sys/syscall.h>".}: cint
|
||||
|
||||
when defined(cpu64):
|
||||
type
|
||||
Off {.importc: "off_t", header: "<sys/types.h>".} = int64
|
||||
Quad {.importc: "quad_t", header: "<sys/types.h>".} = int64
|
||||
proc syscall(arg: Quad): Off {.varargs, importc: "__syscall", header: "<unistd.h>".}
|
||||
else:
|
||||
proc syscall(arg: cint): cint {.varargs, importc: "syscall", header: "<unistd.h>".}
|
||||
|
||||
proc getThreadId*(): int =
|
||||
## Gets the ID of the currently running thread.
|
||||
var tid = 0.cint
|
||||
var tid = when defined(cpu64): Off(0) else: cint(0)
|
||||
if threadId == 0:
|
||||
discard syscall(SYS_thr_self, addr tid)
|
||||
threadId = tid
|
||||
threadId = int(tid)
|
||||
result = threadId
|
||||
|
||||
elif defined(macosx):
|
||||
|
||||
@@ -83,7 +83,7 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string, isOrc =
|
||||
|
||||
if "boehm" notin options and not isOrc:
|
||||
# hcr tests
|
||||
|
||||
|
||||
testSpec r, makeTest("tests/dll/nimhcr_basic.nim", options & " --threads:off --forceBuild --hotCodeReloading:on " & rpath, cat)
|
||||
|
||||
# force build required - see the comments in the .nim file for more details
|
||||
@@ -162,6 +162,7 @@ proc gcTests(r: var TResults, cat: Category, options: string) =
|
||||
test "stackrefleak"
|
||||
test "cyclecollector"
|
||||
testWithoutBoehm "trace_globals"
|
||||
test "tfinalizers"
|
||||
|
||||
# ------------------------- threading tests -----------------------------------
|
||||
|
||||
@@ -446,7 +447,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 +463,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 +566,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
|
||||
|
||||
@@ -38,7 +38,8 @@ pkg "argparse"
|
||||
pkg "arraymancer", "nimble install -y; nimble uninstall -i -y nimcuda; nimble install nimcuda@0.2.1; nim c tests/tests_cpu.nim"
|
||||
pkg "ast_pattern_matching", "nim c -r tests/test1.nim"
|
||||
pkg "asyncftpclient", "nimble compileExample"
|
||||
pkg "asyncthreadpool", "nimble test --mm:refc"
|
||||
when not defined(arm64):
|
||||
pkg "asyncthreadpool", "nimble test --mm:refc"
|
||||
pkg "awk"
|
||||
pkg "bigints"
|
||||
pkg "binaryheap", "nim c -r binaryheap.nim"
|
||||
@@ -57,8 +58,9 @@ pkg "combparser", "nimble test --mm:orc"
|
||||
pkg "compactdict"
|
||||
pkg "comprehension", "nimble test", "https://github.com/alehander92/comprehension"
|
||||
pkg "confutils", "nimble install -y toml_serialization json_serialization unittest2; nimble test"
|
||||
pkg "constantine", "nimble make_lib"
|
||||
pkg "criterion"
|
||||
# pkg "constantine", "nimble make_lib"
|
||||
when not defined(arm64):
|
||||
pkg "criterion"
|
||||
pkg "dashing", "nim c tests/functional.nim"
|
||||
pkg "delaunay"
|
||||
pkg "docopt"
|
||||
@@ -85,11 +87,11 @@ pkg "json_serialization"
|
||||
pkg "jstin"
|
||||
pkg "karax", "nim c -r tests/tester.nim"
|
||||
pkg "kdtree", "nimble test -d:nimLegacyRandomInitRand", "https://github.com/jblindsay/kdtree"
|
||||
pkg "lockfreequeues"
|
||||
# pkg "lockfreequeues"
|
||||
pkg "loopfusion"
|
||||
pkg "macroutils"
|
||||
pkg "manu"
|
||||
pkg "markdown"
|
||||
# pkg "markdown"
|
||||
pkg "measuremancer", "nimble testDeps; nimble -y test"
|
||||
# when unchained is version 0.3.7 or higher, use `nimble testDeps;`
|
||||
pkg "memo"
|
||||
@@ -112,15 +114,16 @@ pkg "nimes", "nim c src/nimes.nim"
|
||||
pkg "nimfp", "nim c -o:nfp -r src/fp.nim"
|
||||
pkg "nimgame2", "nim c --mm:refc nimgame2/nimgame.nim"
|
||||
pkg "nimgen", "nim c -o:nimgenn -r src/nimgen/runcfg.nim"
|
||||
pkg "nimib"
|
||||
# pkg "nimib"
|
||||
pkg "nimlsp"
|
||||
pkg "nimly", "nim c -r tests/test_readme_example.nim"
|
||||
pkg "nimPNG", useHead = true
|
||||
pkg "nimpy", "nim c -r tests/nimfrompy.nim"
|
||||
pkg "nimquery"
|
||||
pkg "nimsl"
|
||||
# pkg "nimsl"
|
||||
pkg "nimsvg"
|
||||
pkg "nimterop", "nimble minitest", url = "https://github.com/nim-lang/nimterop"
|
||||
when not defined(arm64):
|
||||
pkg "nimterop", "nimble minitest", url = "https://github.com/nim-lang/nimterop"
|
||||
pkg "nimwc", "nim c nimwc.nim"
|
||||
pkg "nitter", "nim c src/nitter.nim", "https://github.com/zedeus/nitter"
|
||||
pkg "norm", "testament r tests/common/tmodel.nim"
|
||||
@@ -131,7 +134,8 @@ pkg "optionsutils"
|
||||
pkg "ormin", "nim c -o:orminn ormin.nim"
|
||||
pkg "parsetoml"
|
||||
pkg "patty"
|
||||
pkg "pixie"
|
||||
when not defined(arm64):
|
||||
pkg "pixie"
|
||||
pkg "plotly", "nim c examples/all.nim"
|
||||
pkg "pnm"
|
||||
pkg "polypbren"
|
||||
@@ -152,7 +156,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"
|
||||
@@ -174,7 +178,8 @@ pkg "unicodeplus", "nim c -d:release -r tests/tests.nim"
|
||||
pkg "union", "nim c -r tests/treadme.nim", url = "https://github.com/alaviss/union"
|
||||
pkg "unittest2"
|
||||
pkg "unpack"
|
||||
pkg "weave", "nimble test_gc_arc", useHead = true
|
||||
when not defined(arm64):
|
||||
pkg "weave", "nimble install -y cligen@#HEAD; nimble test_gc_arc", useHead = true
|
||||
pkg "websock", "nim c -d:chronosStrictException -d:chronicles_log_level=INFO --mm:refc tests/all_tests.nim"
|
||||
pkg "websocket", "nim c websocket.nim"
|
||||
pkg "with"
|
||||
|
||||
@@ -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)
|
||||
|
||||
39
tests/arc/tdestructor_order.nim
Normal file
39
tests/arc/tdestructor_order.nim
Normal file
@@ -0,0 +1,39 @@
|
||||
discard """
|
||||
output: '''
|
||||
destroying d
|
||||
destroying c
|
||||
destroying a 2
|
||||
destroying d
|
||||
destroying c
|
||||
destroying a 1
|
||||
'''
|
||||
joinable: false
|
||||
"""
|
||||
|
||||
type
|
||||
Aaaa {.inheritable.} = object
|
||||
vvvv: int
|
||||
Bbbb = object of Aaaa
|
||||
c: Cccc
|
||||
d: Dddd
|
||||
Cccc = object
|
||||
Dddd = object
|
||||
|
||||
Holder = object
|
||||
member: ref Aaaa
|
||||
|
||||
proc `=destroy`(v: Cccc) =
|
||||
echo "destroying c"
|
||||
|
||||
proc `=destroy`(v: Dddd) =
|
||||
echo "destroying d"
|
||||
|
||||
proc `=destroy`(v: Aaaa) =
|
||||
echo "destroying a ", v.vvvv
|
||||
|
||||
func makeHolder(vvvv: int): ref Holder =
|
||||
(ref Holder)(member: (ref Bbbb)(vvvv: vvvv))
|
||||
|
||||
block:
|
||||
var v = makeHolder(1)
|
||||
var v2 = makeHolder(2)
|
||||
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
|
||||
"""
|
||||
|
||||
|
||||
@@ -161,3 +161,21 @@ typedef struct { int base; } S;
|
||||
|
||||
var t = newT()
|
||||
doAssert t.s.base == 1
|
||||
|
||||
type QObject* {.inheritable, pure.} = object
|
||||
h*: pointer
|
||||
|
||||
proc `=destroy`(self: var QObject) =discard
|
||||
|
||||
proc `=copy`(dest: var QObject, source: QObject) {.error.}
|
||||
|
||||
type QAbstractItemModel* = object of QObject
|
||||
|
||||
type VTable = ref object
|
||||
inst: QAbstractItemModel
|
||||
|
||||
proc g() =
|
||||
var x: VTable = VTable()
|
||||
x.inst = QAbstractItemModel()
|
||||
|
||||
g()
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
discard """
|
||||
disabled: "osx"
|
||||
"""
|
||||
|
||||
proc testAsm() =
|
||||
let src = 41
|
||||
var dst = 0
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
output: '''----1
|
||||
output: '''
|
||||
----1
|
||||
myobj constructed
|
||||
myobj destroyed
|
||||
----2
|
||||
@@ -14,8 +15,8 @@ mygeneric3 constructed
|
||||
mygeneric1 destroyed
|
||||
----5
|
||||
mydistinctObj constructed
|
||||
myobj destroyed
|
||||
mygeneric2 destroyed
|
||||
myobj destroyed
|
||||
------------------8
|
||||
mygeneric1 destroyed
|
||||
----6
|
||||
|
||||
@@ -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
|
||||
|
||||
19
tests/gc/tfinalizers.nim
Normal file
19
tests/gc/tfinalizers.nim
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
type
|
||||
PNode = ref TNode
|
||||
TNode = object
|
||||
le: PNode
|
||||
|
||||
proc finalizeNode(n: PNode) =
|
||||
var s = @[0]
|
||||
|
||||
proc returnTree() =
|
||||
var cycle: PNode
|
||||
new(cycle, finalizeNode)
|
||||
cycle.le = cycle
|
||||
|
||||
for i in 1..100:
|
||||
returnTree()
|
||||
|
||||
GC_fullCollect()
|
||||
GC_fullCollect()
|
||||
@@ -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]]()
|
||||
@@ -531,3 +531,13 @@ block:
|
||||
|
||||
check(a)
|
||||
check(b)
|
||||
|
||||
block:
|
||||
template p {.pragma.}
|
||||
|
||||
func foo[T0](v: T0): bool =
|
||||
type T = T0
|
||||
T.hasCustomPragma(p)
|
||||
|
||||
type X {.p.} = object
|
||||
doAssert foo(X())
|
||||
|
||||
13
tests/pragmas/tgenericparamcustompragma.nim
Normal file
13
tests/pragmas/tgenericparamcustompragma.nim
Normal file
@@ -0,0 +1,13 @@
|
||||
# issue #23713
|
||||
|
||||
import std/macros
|
||||
|
||||
template p {.pragma.}
|
||||
|
||||
type
|
||||
X {.p.} = object
|
||||
|
||||
Y[T] = object
|
||||
t: T
|
||||
|
||||
doAssert Y[X].T.hasCustomPragma(p)
|
||||
@@ -1,6 +1,7 @@
|
||||
discard """
|
||||
matrix: "--mm:refc; --mm:orc"
|
||||
targets: "c cpp js"
|
||||
disabled: "osx"
|
||||
"""
|
||||
import std/assertions
|
||||
# TODO: in future work move existing arithmetic tests (tests/arithm/*) into this file
|
||||
|
||||
@@ -3,6 +3,7 @@ discard """
|
||||
disabled: "openbsd"
|
||||
disabled: "freebsd"
|
||||
disabled: "windows"
|
||||
disabled: "osx"
|
||||
"""
|
||||
|
||||
#[
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -273,5 +273,17 @@ template main =
|
||||
list.add(n4)
|
||||
doAssert list.toSeq == @["sonic", "the", "hedgehog"]
|
||||
|
||||
|
||||
block:
|
||||
var list = initSinglyLinkedList[int]()
|
||||
|
||||
list.add(4)
|
||||
list.remove(list.head)
|
||||
|
||||
list.add(5)
|
||||
list.remove(list.head)
|
||||
|
||||
list.add(6)
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user