mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-17 14:31:15 +00:00
Merge branch 'devel' into pr_remove_macros
This commit is contained in:
54
tests/alloc/tmembug.nim
Normal file
54
tests/alloc/tmembug.nim
Normal file
@@ -0,0 +1,54 @@
|
||||
discard """
|
||||
joinable: false
|
||||
"""
|
||||
|
||||
import std / [atomics, strutils, sequtils]
|
||||
|
||||
type
|
||||
BackendMessage* = object
|
||||
field*: seq[int]
|
||||
|
||||
var
|
||||
chan1: Channel[BackendMessage]
|
||||
chan2: Channel[BackendMessage]
|
||||
|
||||
chan1.open()
|
||||
chan2.open()
|
||||
|
||||
proc routeMessage*(msg: BackendMessage) =
|
||||
discard chan2.trySend(msg)
|
||||
|
||||
var
|
||||
recv: Thread[void]
|
||||
stopToken: Atomic[bool]
|
||||
|
||||
proc recvMsg() =
|
||||
while not stopToken.load(moRelaxed):
|
||||
let resp = chan1.tryRecv()
|
||||
if resp.dataAvailable:
|
||||
routeMessage(resp.msg)
|
||||
echo "child consumes ", formatSize getOccupiedMem()
|
||||
|
||||
createThread[void](recv, recvMsg)
|
||||
|
||||
const MESSAGE_COUNT = 100
|
||||
|
||||
proc main() =
|
||||
let msg: BackendMessage = BackendMessage(field: (0..500).toSeq())
|
||||
for j in 0..0: #100:
|
||||
echo "New iteration"
|
||||
|
||||
for _ in 1..MESSAGE_COUNT:
|
||||
chan1.send(msg)
|
||||
echo "After sending"
|
||||
|
||||
var counter = 0
|
||||
while counter < MESSAGE_COUNT:
|
||||
let resp = recv(chan2)
|
||||
counter.inc
|
||||
echo "After receiving ", formatSize getOccupiedMem()
|
||||
|
||||
stopToken.store true, moRelaxed
|
||||
joinThreads(recv)
|
||||
|
||||
main()
|
||||
58
tests/alloc/tmembug2.nim
Normal file
58
tests/alloc/tmembug2.nim
Normal file
@@ -0,0 +1,58 @@
|
||||
discard """
|
||||
disabled: "true"
|
||||
"""
|
||||
|
||||
import std / [atomics, strutils, sequtils, isolation]
|
||||
|
||||
import threading / channels
|
||||
|
||||
type
|
||||
BackendMessage* = object
|
||||
field*: seq[int]
|
||||
|
||||
const MESSAGE_COUNT = 100
|
||||
|
||||
var
|
||||
chan1 = newChan[BackendMessage](MESSAGE_COUNT*2)
|
||||
chan2 = newChan[BackendMessage](MESSAGE_COUNT*2)
|
||||
|
||||
#chan1.open()
|
||||
#chan2.open()
|
||||
|
||||
proc routeMessage*(msg: BackendMessage) =
|
||||
var m = isolate(msg)
|
||||
discard chan2.trySend(m)
|
||||
|
||||
var
|
||||
thr: Thread[void]
|
||||
stopToken: Atomic[bool]
|
||||
|
||||
proc recvMsg() =
|
||||
while not stopToken.load(moRelaxed):
|
||||
var resp: BackendMessage
|
||||
if chan1.tryRecv(resp):
|
||||
#if resp.dataAvailable:
|
||||
routeMessage(resp)
|
||||
echo "child consumes ", formatSize getOccupiedMem()
|
||||
|
||||
createThread[void](thr, recvMsg)
|
||||
|
||||
proc main() =
|
||||
let msg: BackendMessage = BackendMessage(field: (0..5).toSeq())
|
||||
for j in 0..100:
|
||||
echo "New iteration"
|
||||
|
||||
for _ in 1..MESSAGE_COUNT:
|
||||
chan1.send(msg)
|
||||
echo "After sending"
|
||||
|
||||
var counter = 0
|
||||
while counter < MESSAGE_COUNT:
|
||||
let resp = recv(chan2)
|
||||
counter.inc
|
||||
echo "After receiving ", formatSize getOccupiedMem()
|
||||
|
||||
stopToken.store true, moRelaxed
|
||||
joinThreads(thr)
|
||||
|
||||
main()
|
||||
@@ -136,4 +136,38 @@ proc main2 =
|
||||
doAssert a.len == 2
|
||||
doAssert b.len == 0
|
||||
|
||||
main2()
|
||||
main2()
|
||||
|
||||
block:
|
||||
type
|
||||
TestObj = object of RootObj
|
||||
name: string
|
||||
|
||||
TestSubObj = object of TestObj
|
||||
objname: string
|
||||
|
||||
proc `=destroy`(x: TestObj) =
|
||||
`=destroy`(x.name)
|
||||
|
||||
proc `=destroy`(x: TestSubObj) =
|
||||
`=destroy`(x.objname)
|
||||
`=destroy`(TestObj(x))
|
||||
|
||||
proc testCase() =
|
||||
let t1 {.used.} = TestSubObj(objname: "tso1", name: "to1")
|
||||
|
||||
proc main() =
|
||||
testCase()
|
||||
|
||||
main()
|
||||
|
||||
block: # bug #23858
|
||||
type Object = object
|
||||
a: int
|
||||
b: ref int
|
||||
var x = 0
|
||||
proc fn(): auto {.cdecl.} =
|
||||
inc x
|
||||
return Object()
|
||||
discard fn()
|
||||
doAssert x == 1
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
output: '''
|
||||
Destructor for TestTestObj
|
||||
=destroy called
|
||||
123xyzabc
|
||||
destroyed: false
|
||||
@@ -36,9 +37,33 @@ destroying variable: 20
|
||||
destroying variable: 10
|
||||
closed
|
||||
'''
|
||||
cmd: "nim c --gc:arc --deepcopy:on -d:nimAllocPagesViaMalloc $file"
|
||||
cmd: "nim c --mm:arc --deepcopy:on -d:nimAllocPagesViaMalloc $file"
|
||||
"""
|
||||
|
||||
block: # bug #23627
|
||||
type
|
||||
TestObj = object of RootObj
|
||||
|
||||
Test2 = object of RootObj
|
||||
foo: TestObj
|
||||
|
||||
TestTestObj = object of RootObj
|
||||
shit: TestObj
|
||||
|
||||
proc `=destroy`(x: TestTestObj) =
|
||||
echo "Destructor for TestTestObj"
|
||||
let test = Test2(foo: TestObj())
|
||||
|
||||
proc testCaseT() =
|
||||
let tt1 {.used.} = TestTestObj(shit: TestObj())
|
||||
|
||||
|
||||
proc main() =
|
||||
testCaseT()
|
||||
|
||||
main()
|
||||
|
||||
|
||||
# bug #9401
|
||||
|
||||
type
|
||||
@@ -46,13 +71,12 @@ type
|
||||
len: int
|
||||
data: ptr UncheckedArray[float]
|
||||
|
||||
proc `=destroy`*(m: var MyObj) =
|
||||
proc `=destroy`*(m: MyObj) =
|
||||
|
||||
echo "=destroy called"
|
||||
|
||||
if m.data != nil:
|
||||
deallocShared(m.data)
|
||||
m.data = nil
|
||||
|
||||
type
|
||||
MyObjDistinct = distinct MyObj
|
||||
@@ -104,7 +128,7 @@ bbb("123")
|
||||
type Variable = ref object
|
||||
value: int
|
||||
|
||||
proc `=destroy`(self: var typeof(Variable()[])) =
|
||||
proc `=destroy`(self: typeof(Variable()[])) =
|
||||
echo "destroying variable: ",self.value
|
||||
|
||||
proc newVariable(value: int): Variable =
|
||||
@@ -158,7 +182,7 @@ type
|
||||
B = ref object of A
|
||||
x: int
|
||||
|
||||
proc `=destroy`(x: var AObj) =
|
||||
proc `=destroy`(x: AObj) =
|
||||
close(x.io)
|
||||
echo "closed"
|
||||
|
||||
@@ -742,3 +766,26 @@ block: # bug #23524
|
||||
doAssert t2.a == 100
|
||||
|
||||
main()
|
||||
|
||||
block: # bug #23907
|
||||
type
|
||||
Thingy = object
|
||||
value: int
|
||||
|
||||
ExecProc[C] = proc(value: sink C): int {.nimcall.}
|
||||
|
||||
proc `=copy`(a: var Thingy, b: Thingy) {.error.}
|
||||
|
||||
var thingyDestroyCount = 0
|
||||
|
||||
proc `=destroy`(thingy: Thingy) =
|
||||
assert(thingyDestroyCount <= 0)
|
||||
thingyDestroyCount += 1
|
||||
|
||||
proc store(value: sink Thingy): int =
|
||||
result = value.value
|
||||
|
||||
let callback: ExecProc[Thingy] = store
|
||||
|
||||
doAssert callback(Thingy(value: 123)) == 123
|
||||
|
||||
|
||||
@@ -338,3 +338,29 @@ block:
|
||||
doAssert ff.s == 12
|
||||
|
||||
mainSync()
|
||||
|
||||
import std/sequtils
|
||||
|
||||
# bug #23690
|
||||
type
|
||||
SomeObj* = object of RootObj
|
||||
|
||||
Item* = object
|
||||
case kind*: 0..1
|
||||
of 0:
|
||||
a*: int
|
||||
b*: SomeObj
|
||||
of 1:
|
||||
c*: string
|
||||
|
||||
ItemExt* = object
|
||||
a*: Item
|
||||
b*: string
|
||||
|
||||
proc do1(x: int): seq[(string, Item)] =
|
||||
result = @[("zero", Item(kind: 1, c: "first"))]
|
||||
|
||||
proc do2(x: int, e: ItemExt): seq[(string, ItemExt)] =
|
||||
do1(x).map(proc(v: (string, Item)): auto = (v[0], ItemExt(a: v[1], b: e.b)))
|
||||
|
||||
doAssert $do2(0, ItemExt(a: Item(kind: 1, c: "second"), b: "third")) == """@[("zero", (a: (kind: 1, c: "first"), b: "third"))]"""
|
||||
|
||||
@@ -68,3 +68,19 @@ block:
|
||||
doAssert foo(noBugConst) == expected
|
||||
let noBugSeq = @["0", "c", "a"]
|
||||
doAssert foo(noBugSeq) == expected
|
||||
|
||||
block: # bug #20865
|
||||
var p: pointer
|
||||
var x: array[0, int]
|
||||
# echo toOpenArray(x, 0, 1)[0] # Raises IndexDefect
|
||||
doAssertRaises(IndexDefect):
|
||||
echo toOpenArray(cast[ptr array[0, int]](p)[], 0, 1)[0] # Does not raise IndexDefect
|
||||
|
||||
block: # bug #20987
|
||||
var v: array[1, byte]
|
||||
|
||||
var p = cast[ptr array[0, byte]](addr v)
|
||||
|
||||
doAssertRaises(IndexDefect):
|
||||
echo toOpenArray(p[], 1, 2)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ discard """
|
||||
# Test the new ``emit`` pragma:
|
||||
|
||||
{.emit: """
|
||||
#include <stdio.h>
|
||||
static int cvariable = 420;
|
||||
|
||||
""".}
|
||||
|
||||
@@ -3,4 +3,5 @@ func test*(input: var openArray[int32], start: int = 0, fin: int = input.len - 1
|
||||
|
||||
var someSeq = @[1'i32]
|
||||
|
||||
test(someSeq)
|
||||
test(someSeq)
|
||||
# bug with gcc 14
|
||||
@@ -24,7 +24,10 @@ type
|
||||
fulfilled: Atomic[bool]
|
||||
|
||||
var x: Pledge
|
||||
when defined(gcRefc):
|
||||
when defined(cpp):
|
||||
# TODO: fixme
|
||||
discard "it doesn't work for refc/orc because of contrived `Atomic` in cpp"
|
||||
elif defined(gcRefc):
|
||||
doAssert x.repr == "[p = nil]"
|
||||
elif not defined(cpp): # fixme # bug #20081
|
||||
else: # fixme # bug #20081
|
||||
doAssert x.repr == "Pledge(p: nil)"
|
||||
|
||||
25
tests/ccgbugs/t23796.nim
Normal file
25
tests/ccgbugs/t23796.nim
Normal file
@@ -0,0 +1,25 @@
|
||||
discard """
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
# bug #23796
|
||||
|
||||
{.emit: """
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void fooArr(float data[3]) {}
|
||||
void fooIntArr(int id, float data[3]) {}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
""".}
|
||||
|
||||
proc fooArr(data: var array[3, cfloat]) {.importc.}
|
||||
proc fooIntArr(id: cint, data: var array[3, cfloat]) {.importc, nodecl.}
|
||||
|
||||
var arr = [cfloat 1, 2, 3]
|
||||
fooArr(arr)
|
||||
fooIntArr(1, arr)
|
||||
@@ -4,6 +4,7 @@ success
|
||||
M1 M2
|
||||
ok
|
||||
'''
|
||||
matrix: "--mm:refc;--mm:orc"
|
||||
"""
|
||||
|
||||
type
|
||||
@@ -133,3 +134,30 @@ proc foo = # bug #23280
|
||||
doAssert L mod 6 == 0
|
||||
|
||||
foo()
|
||||
|
||||
block: # bug #9940
|
||||
{.emit:"""/*TYPESECTION*/
|
||||
typedef struct { int base; } S;
|
||||
""".}
|
||||
|
||||
type S {.importc: "S", completeStruct.} = object
|
||||
base: cint
|
||||
proc init(x:ptr S) =
|
||||
x.base = 1
|
||||
|
||||
type
|
||||
Foo = object
|
||||
a: seq[float]
|
||||
b: seq[float]
|
||||
c: seq[float]
|
||||
d: seq[float]
|
||||
s: S
|
||||
|
||||
proc newT(): Foo =
|
||||
var t: Foo
|
||||
t.s.addr.init
|
||||
doAssert t.s.base == 1
|
||||
t
|
||||
|
||||
var t = newT()
|
||||
doAssert t.s.base == 1
|
||||
|
||||
@@ -5,11 +5,11 @@ discard """
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE6stringN14titaniummangle3FooE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3int7varargsI6stringE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncEN14titaniummangle3BooE'"
|
||||
ccodecheck: "'_ZN8testFunc8testFuncE8typeDescIN14titaniummangle17EnumAnotherSampleEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE8typeDescIN14titaniummangle17EnumAnotherSampleEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3ptrI14uncheckedArrayI3intEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3setIN14titaniummangle10EnumSampleEE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE4procI6string6stringE'"
|
||||
ccodecheck: "'_ZN8testFunc8testFuncE3intN10Comparable10ComparableE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3intN10Comparable10ComparableE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE3int3int'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncEN14titaniummangle10EnumSampleE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncEN14titaniummangle17EnumAnotherSampleE'"
|
||||
@@ -37,7 +37,6 @@ type
|
||||
Comparable = concept x, y
|
||||
(x < y) is bool
|
||||
|
||||
type
|
||||
Foo = object
|
||||
a: int32
|
||||
b: int32
|
||||
@@ -45,8 +44,10 @@ type
|
||||
FooTuple = tuple
|
||||
a: int
|
||||
b: int
|
||||
|
||||
Container[T] = object
|
||||
data: T
|
||||
data: T
|
||||
|
||||
Container2[T, T2] = object
|
||||
data: T
|
||||
data2: T2
|
||||
|
||||
20
tests/compileoption/texperimental.nim
Normal file
20
tests/compileoption/texperimental.nim
Normal file
@@ -0,0 +1,20 @@
|
||||
static:
|
||||
doAssert compileOption("experimental", "dotOperators")
|
||||
doAssert compileOption("experimental", "callOperator")
|
||||
doAssert compileOption("experimental", "parallel")
|
||||
doAssert compileOption("experimental", "destructor")
|
||||
doAssert compileOption("experimental", "notnil")
|
||||
doAssert compileOption("experimental", "dynamicBindSym")
|
||||
doAssert compileOption("experimental", "codeReordering")
|
||||
doAssert compileOption("experimental", "compiletimeFFI")
|
||||
doAssert compileOption("experimental", "vmopsDanger")
|
||||
doAssert compileOption("experimental", "strictFuncs")
|
||||
doAssert compileOption("experimental", "views")
|
||||
doAssert compileOption("experimental", "strictNotNil")
|
||||
doAssert compileOption("experimental", "strictEffects")
|
||||
doAssert compileOption("experimental", "flexibleOptionalParams")
|
||||
doAssert compileOption("experimental", "strictDefs")
|
||||
doAssert compileOption("experimental", "strictCaseObjects")
|
||||
doAssert compileOption("experimental", "inferGenericTypes")
|
||||
doAssert compileOption("experimental", "genericsOpenSym")
|
||||
doAssert compileOption("experimental", "vtables")
|
||||
19
tests/compileoption/texperimental.nims
Normal file
19
tests/compileoption/texperimental.nims
Normal file
@@ -0,0 +1,19 @@
|
||||
switch("experimental", "dotOperators")
|
||||
switch("experimental", "callOperator")
|
||||
switch("experimental", "parallel")
|
||||
switch("experimental", "destructor")
|
||||
switch("experimental", "notnil")
|
||||
switch("experimental", "dynamicBindSym")
|
||||
switch("experimental", "codeReordering")
|
||||
switch("experimental", "compiletimeFFI")
|
||||
switch("experimental", "vmopsDanger")
|
||||
switch("experimental", "strictFuncs")
|
||||
switch("experimental", "views")
|
||||
switch("experimental", "strictNotNil")
|
||||
switch("experimental", "strictEffects")
|
||||
switch("experimental", "flexibleOptionalParams")
|
||||
switch("experimental", "strictDefs")
|
||||
switch("experimental", "strictCaseObjects")
|
||||
switch("experimental", "inferGenericTypes")
|
||||
switch("experimental", "genericsOpenSym")
|
||||
switch("experimental", "vtables")
|
||||
@@ -45,3 +45,4 @@ switch("define", "nimPreviewNonVarDestructor")
|
||||
switch("warningAserror", "UnnamedBreak")
|
||||
switch("legacy", "verboseTypeMismatch")
|
||||
switch("experimental", "vtables")
|
||||
switch("experimental", "genericsOpenSym")
|
||||
|
||||
12
tests/controlflow/tunreachable2.nim
Normal file
12
tests/controlflow/tunreachable2.nim
Normal file
@@ -0,0 +1,12 @@
|
||||
discard """
|
||||
matrix: "--warningAsError:UnreachableCode"
|
||||
"""
|
||||
|
||||
proc test(): bool =
|
||||
block okay:
|
||||
if true: break okay
|
||||
return false
|
||||
|
||||
return true # Line 7 is here
|
||||
|
||||
doAssert test()
|
||||
4
tests/cpp/fam.h
Normal file
4
tests/cpp/fam.h
Normal file
@@ -0,0 +1,4 @@
|
||||
struct Test{
|
||||
~Test() {
|
||||
}
|
||||
};
|
||||
54
tests/cpp/t23657.nim
Normal file
54
tests/cpp/t23657.nim
Normal file
@@ -0,0 +1,54 @@
|
||||
discard """
|
||||
targets: "cpp"
|
||||
cmd: "nim cpp -r $file"
|
||||
output: '''
|
||||
1.0
|
||||
1.0
|
||||
'''
|
||||
|
||||
"""
|
||||
{.emit:"""/*TYPESECTION*/
|
||||
struct Point {
|
||||
float x, y, z;
|
||||
Point(float x, float y, float z): x(x), y(y), z(z) {}
|
||||
Point() = default;
|
||||
};
|
||||
struct Direction {
|
||||
float x, y, z;
|
||||
Direction(float x, float y, float z): x(x), y(y), z(z) {}
|
||||
Direction() = default;
|
||||
};
|
||||
struct Axis {
|
||||
Point origin;
|
||||
Direction direction;
|
||||
Axis(Point origin, Direction direction): origin(origin), direction(direction) {}
|
||||
Axis() = default;
|
||||
};
|
||||
|
||||
""".}
|
||||
|
||||
type
|
||||
Point {.importcpp.} = object
|
||||
x, y, z: float
|
||||
|
||||
Direction {.importcpp.} = object
|
||||
x, y, z: float
|
||||
|
||||
Axis {.importcpp.} = object
|
||||
origin: Point
|
||||
direction: Direction
|
||||
|
||||
proc makeAxis(origin: Point, direction: Direction): Axis {. constructor, importcpp:"Axis(@)".}
|
||||
proc makePoint(x, y, z: float): Point {. constructor, importcpp:"Point(@)".}
|
||||
proc makeDirection(x, y, z: float): Direction {. constructor, importcpp:"Direction(@)".}
|
||||
|
||||
var axis1 = makeAxis(Point(x: 1.0, y: 2.0, z: 3.0), Direction(x: 4.0, y: 5.0, z: 6.0)) #Triggers the error (T1)
|
||||
var axis2Ctor = makeAxis(makePoint(1.0, 2.0, 3.0), makeDirection(4.0, 5.0, 6.0)) #Do not triggers
|
||||
|
||||
proc main() = #Do not triggers as Tx are inside the body
|
||||
let test = makeAxis(Point(x: 1.0, y: 2.0, z: 3.0), Direction(x: 4.0, y: 5.0, z: 6.0))
|
||||
echo test.origin.x
|
||||
|
||||
main()
|
||||
|
||||
echo $axis1.origin.x #Make sures it's init
|
||||
@@ -1,6 +1,5 @@
|
||||
discard """
|
||||
cmd: "nim cpp $file"
|
||||
output: '''{"vas": "kas", "123": "123"}'''
|
||||
targets: "cpp"
|
||||
"""
|
||||
|
||||
@@ -18,4 +17,4 @@ import tables
|
||||
var t = initTable[string, string]()
|
||||
discard t.hasKeyOrPut("123", "123")
|
||||
discard t.mgetOrPut("vas", "kas")
|
||||
echo t
|
||||
doAssert t.len == 2
|
||||
|
||||
7
tests/cpp/tfam.nim
Normal file
7
tests/cpp/tfam.nim
Normal file
@@ -0,0 +1,7 @@
|
||||
discard """
|
||||
targets: "cpp"
|
||||
"""
|
||||
type
|
||||
Test {.importcpp, header: "fam.h".} = object
|
||||
|
||||
let test = newSeq[Test]()
|
||||
31
tests/destructor/t23748.nim
Normal file
31
tests/destructor/t23748.nim
Normal file
@@ -0,0 +1,31 @@
|
||||
discard """
|
||||
matrix: "--gc:refc; --gc:arc"
|
||||
output: '''
|
||||
hello 42
|
||||
hello 42
|
||||
len = 2
|
||||
'''
|
||||
"""
|
||||
|
||||
# bug #23748
|
||||
|
||||
type
|
||||
O = ref object
|
||||
s: string
|
||||
cb: seq[proc()]
|
||||
|
||||
proc push1(o: O, i: int) =
|
||||
let o = o
|
||||
echo o.s, " ", i
|
||||
o.cb.add(proc() = echo o.s, " ", i)
|
||||
|
||||
proc push2(o: O, i: int) =
|
||||
let o = o
|
||||
echo o.s, " ", i
|
||||
proc p() = echo o.s, " ", i
|
||||
o.cb.add(p)
|
||||
|
||||
let o = O(s: "hello", cb: @[])
|
||||
o.push1(42)
|
||||
o.push2(42)
|
||||
echo "len = ", o.cb.len
|
||||
51
tests/destructor/t23837.nim
Normal file
51
tests/destructor/t23837.nim
Normal file
@@ -0,0 +1,51 @@
|
||||
discard """
|
||||
output: '''
|
||||
Deallocating OwnedString
|
||||
HelloWorld
|
||||
'''
|
||||
matrix: "--cursorinference:on; --cursorinference:off"
|
||||
target: "c"
|
||||
"""
|
||||
|
||||
# bug #23837
|
||||
{.
|
||||
emit: [
|
||||
"""
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
char *allocCString() {
|
||||
char *result = (char *) malloc(10 + 1);
|
||||
strcpy(result, "HelloWorld");
|
||||
return result;
|
||||
}
|
||||
|
||||
"""
|
||||
]
|
||||
.}
|
||||
|
||||
proc rawWrapper(): cstring {.importc: "allocCString", cdecl.}
|
||||
proc free(p: pointer) {.importc: "free", cdecl.}
|
||||
|
||||
# -------------------------
|
||||
|
||||
type OwnedString = distinct cstring
|
||||
|
||||
proc `=destroy`(s: OwnedString) =
|
||||
free(cstring s)
|
||||
echo "Deallocating OwnedString"
|
||||
|
||||
func `$`(s: OwnedString): string {.borrow.}
|
||||
|
||||
proc leakyWrapper(): string =
|
||||
let ostring = rawWrapper().OwnedString
|
||||
$ostring
|
||||
|
||||
# -------------------------
|
||||
|
||||
proc main() =
|
||||
# destructor not called - definitely lost: 11 bytes in 1 blocks
|
||||
# doesn't leak with --cursorInference:off
|
||||
let s = leakyWrapper()
|
||||
echo s
|
||||
|
||||
main()
|
||||
8
tests/destructor/tdistinctseq.nim
Normal file
8
tests/destructor/tdistinctseq.nim
Normal file
@@ -0,0 +1,8 @@
|
||||
discard """
|
||||
matrix: "-u:nimPreviewNonVarDestructor;"
|
||||
"""
|
||||
type DistinctSeq* = distinct seq[int]
|
||||
|
||||
# `=destroy`(cast[ptr DistinctSeq](0)[])
|
||||
var x = @[].DistinctSeq
|
||||
`=destroy`(x)
|
||||
19
tests/destructor/tgotoexc_leak.nim
Normal file
19
tests/destructor/tgotoexc_leak.nim
Normal file
@@ -0,0 +1,19 @@
|
||||
discard """
|
||||
output: '''0
|
||||
true'''
|
||||
cmd: "nim c --gc:arc $file"
|
||||
"""
|
||||
|
||||
# bug #22398
|
||||
|
||||
for i in 0 ..< 10_000:
|
||||
try:
|
||||
try:
|
||||
raise newException(ValueError, "")
|
||||
except CatchableError:
|
||||
discard
|
||||
raise newException(ValueError, "") # or raise getCurrentException(), just raise works ok
|
||||
except ValueError:
|
||||
discard
|
||||
echo getOccupiedMem()
|
||||
echo getCurrentException() == nil
|
||||
@@ -14,3 +14,11 @@ proc foo = # bug #23359
|
||||
doAssert bar.value == 42
|
||||
|
||||
foo()
|
||||
|
||||
block: # bug #23902
|
||||
proc foo(a: sink string): auto = (a, a)
|
||||
|
||||
proc bar(a: sink int): auto = return a
|
||||
|
||||
proc foo(a: sink string) =
|
||||
var x = (a, a)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
discard """
|
||||
cmd: '''nim c --newruntime $file'''
|
||||
errormsg: "'=copy' is not available for type <owned Button>; requires a copy because it's not the last read of ':envAlt.b1'; routine: main"
|
||||
errormsg: "'=copy' is not available for type <owned Button>; requires a copy because it's not the last read of ':envAlt.b0'; routine: main"
|
||||
line: 48
|
||||
"""
|
||||
|
||||
|
||||
12
tests/discard/t23677.nim
Normal file
12
tests/discard/t23677.nim
Normal file
@@ -0,0 +1,12 @@
|
||||
discard """
|
||||
errormsg: "expression '0' is of type 'int literal(0)' and has to be used (or discarded); start of expression here: t23677.nim(1, 1)"
|
||||
line: 10
|
||||
column: 3
|
||||
"""
|
||||
|
||||
# issue #23677
|
||||
|
||||
if true:
|
||||
0
|
||||
else:
|
||||
raise newException(ValueError, "err")
|
||||
@@ -5,6 +5,7 @@ tdiscardable
|
||||
1
|
||||
something defered
|
||||
something defered
|
||||
hi
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -110,3 +111,65 @@ block:
|
||||
|
||||
doAssertRaises(ValueError):
|
||||
doAssert foo() == 12
|
||||
|
||||
block: # issue #10440
|
||||
proc x(): int {.discardable.} = discard
|
||||
try:
|
||||
x()
|
||||
finally:
|
||||
echo "hi"
|
||||
|
||||
import macros
|
||||
|
||||
block: # issue #14665
|
||||
macro test(): untyped =
|
||||
let b = @[1, 2, 3, 4]
|
||||
|
||||
result = nnkStmtList.newTree()
|
||||
var i = 0
|
||||
while i < b.len:
|
||||
if false:
|
||||
# this quote do is mandatory, removing it fixes the problem
|
||||
result.add quote do:
|
||||
let testtest = 5
|
||||
else:
|
||||
result.add quote do:
|
||||
let test = 6
|
||||
inc i
|
||||
# removing this continue fixes the problem too
|
||||
continue
|
||||
inc i
|
||||
test()
|
||||
|
||||
block: # bug #23775
|
||||
proc retInt(): int {.discardable.} =
|
||||
42
|
||||
|
||||
proc retString(): string {.discardable.} =
|
||||
"text"
|
||||
|
||||
type
|
||||
Enum = enum
|
||||
A, B, C, D
|
||||
|
||||
proc doStuff(msg: Enum) =
|
||||
case msg:
|
||||
of A:
|
||||
retString()
|
||||
of B:
|
||||
retInt()
|
||||
of C:
|
||||
discard retString()
|
||||
else:
|
||||
let _ = retString()
|
||||
|
||||
doStuff(C)
|
||||
|
||||
block:
|
||||
proc test(): (int, int) {.discardable.} =
|
||||
discard
|
||||
|
||||
if true:
|
||||
test()
|
||||
else:
|
||||
quit()
|
||||
|
||||
19
tests/discard/tfinallyerrmsg.nim
Normal file
19
tests/discard/tfinallyerrmsg.nim
Normal file
@@ -0,0 +1,19 @@
|
||||
discard """
|
||||
cmd: "nim check $file"
|
||||
"""
|
||||
|
||||
block: # issue #19672
|
||||
try:
|
||||
10 #[tt.Error
|
||||
^ expression '10' is of type 'int literal(10)' and has to be used (or discarded); start of expression here: tfinallyerrmsg.nim(5, 1)]#
|
||||
finally:
|
||||
echo "Finally block"
|
||||
|
||||
block: # issue #13871
|
||||
template t(body: int) =
|
||||
try:
|
||||
body
|
||||
finally:
|
||||
echo "expression"
|
||||
t: 2 #[tt.Error
|
||||
^ expression '2' is of type 'int literal(2)' and has to be used (or discarded)]#
|
||||
@@ -184,3 +184,84 @@ block: # bug #12589
|
||||
A = int64.high()
|
||||
|
||||
doAssert ord(A) == int64.high()
|
||||
|
||||
import std/enumutils
|
||||
from std/sequtils import toSeq
|
||||
import std/macros
|
||||
|
||||
block: # unordered enum
|
||||
block:
|
||||
type
|
||||
unordered_enum = enum
|
||||
a = 1
|
||||
b = 0
|
||||
|
||||
doAssert (ord(a), ord(b)) == (1, 0)
|
||||
doAssert unordered_enum.toSeq == @[a, b]
|
||||
|
||||
block:
|
||||
type
|
||||
unordered_enum = enum
|
||||
a = 1
|
||||
b = 0
|
||||
c
|
||||
|
||||
doAssert (ord(a), ord(b), ord(c)) == (1, 0, 2)
|
||||
|
||||
block:
|
||||
type
|
||||
unordered_enum = enum
|
||||
a = 100
|
||||
b
|
||||
c = 50
|
||||
d
|
||||
|
||||
doAssert (ord(a), ord(b), ord(c), ord(d)) == (100, 101, 50, 51)
|
||||
|
||||
block:
|
||||
type
|
||||
unordered_enum = enum
|
||||
a = 7
|
||||
b = 6
|
||||
c = 5
|
||||
d
|
||||
|
||||
doAssert (ord(a), ord(b), ord(c), ord(d)) == (7, 6, 5, 8)
|
||||
doAssert unordered_enum.toSeq == @[a, b, c, d]
|
||||
|
||||
block:
|
||||
type
|
||||
unordered_enum = enum
|
||||
a = 100
|
||||
b
|
||||
c = 500
|
||||
d
|
||||
e
|
||||
f = 50
|
||||
g
|
||||
h
|
||||
|
||||
doAssert (ord(a), ord(b), ord(c), ord(d), ord(e), ord(f), ord(g), ord(h)) ==
|
||||
(100, 101, 500, 501, 502, 50, 51, 52)
|
||||
|
||||
block:
|
||||
type
|
||||
unordered_enum = enum
|
||||
A
|
||||
B
|
||||
C = -1
|
||||
D
|
||||
E
|
||||
G = -999
|
||||
|
||||
doAssert (ord(A), ord(B), ord(C), ord(D), ord(E), ord(G)) ==
|
||||
(0, 1, -1, 2, 3, -999)
|
||||
|
||||
block:
|
||||
type
|
||||
SomeEnum = enum
|
||||
seA = 3
|
||||
seB = 2
|
||||
seC = "foo"
|
||||
|
||||
doAssert (ord(seA), ord(seB), ord(seC)) == (3, 2, 4)
|
||||
|
||||
10
tests/enum/tenum_duplicate.nim
Normal file
10
tests/enum/tenum_duplicate.nim
Normal file
@@ -0,0 +1,10 @@
|
||||
discard """
|
||||
errormsg: "duplicate value in enum 'd'"
|
||||
"""
|
||||
|
||||
type
|
||||
unordered_enum = enum
|
||||
a = 1
|
||||
b = 0
|
||||
c
|
||||
d = 2
|
||||
9
tests/errmsgs/t22852.nim
Normal file
9
tests/errmsgs/t22852.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
discard """
|
||||
exitcode: 1
|
||||
outputsub: '''
|
||||
Error: unhandled exception: value out of range: -2 notin 0 .. 9223372036854775807 [RangeDefect]
|
||||
'''
|
||||
"""
|
||||
|
||||
# bug #22852
|
||||
echo [0][2..^2]
|
||||
@@ -7,7 +7,7 @@ block:
|
||||
when false:
|
||||
let x = 123
|
||||
else:
|
||||
template x: untyped = 456
|
||||
template x: untyped {.inject.} = 456
|
||||
echo x #[tt.Error
|
||||
^ undeclared identifier: 'x`gensym0'; if declared in a template, this identifier may be inconsistently marked inject or gensym]#
|
||||
foo()
|
||||
|
||||
@@ -2,16 +2,18 @@ discard """
|
||||
cmd: "nim check --hints:off $file"
|
||||
action: "reject"
|
||||
nimout: '''
|
||||
tmetaobjectfields.nim(24, 5) Error: 'array' is not a concrete type
|
||||
tmetaobjectfields.nim(28, 5) Error: 'seq' is not a concrete type
|
||||
tmetaobjectfields.nim(32, 5) Error: 'set' is not a concrete type
|
||||
tmetaobjectfields.nim(35, 3) Error: 'sink' is not a concrete type
|
||||
tmetaobjectfields.nim(37, 3) Error: 'lent' is not a concrete type
|
||||
tmetaobjectfields.nim(54, 16) Error: 'seq' is not a concrete type
|
||||
tmetaobjectfields.nim(58, 5) Error: 'ptr' is not a concrete type
|
||||
tmetaobjectfields.nim(59, 5) Error: 'ref' is not a concrete type
|
||||
tmetaobjectfields.nim(60, 5) Error: 'auto' is not a concrete type
|
||||
tmetaobjectfields.nim(61, 5) Error: 'UncheckedArray' is not a concrete type
|
||||
tmetaobjectfields.nim(26, 5) Error: 'array' is not a concrete type
|
||||
tmetaobjectfields.nim(30, 5) Error: 'seq' is not a concrete type
|
||||
tmetaobjectfields.nim(34, 5) Error: 'set' is not a concrete type
|
||||
tmetaobjectfields.nim(37, 3) Error: 'sink' is not a concrete type
|
||||
tmetaobjectfields.nim(39, 3) Error: 'lent' is not a concrete type
|
||||
tmetaobjectfields.nim(56, 16) Error: 'seq' is not a concrete type
|
||||
tmetaobjectfields.nim(60, 5) Error: 'ptr' is not a concrete type
|
||||
tmetaobjectfields.nim(61, 5) Error: 'ref' is not a concrete type
|
||||
tmetaobjectfields.nim(62, 5) Error: 'auto' is not a concrete type
|
||||
tmetaobjectfields.nim(63, 5) Error: 'UncheckedArray' is not a concrete type
|
||||
tmetaobjectfields.nim(68, 5) Error: 'object' is not a concrete type
|
||||
tmetaobjectfields.nim(72, 5) Error: 'Type3011:ObjectType' is not a concrete type
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -59,3 +61,15 @@ type
|
||||
b: ref
|
||||
c: auto
|
||||
d: UncheckedArray
|
||||
|
||||
# bug #3011
|
||||
type
|
||||
Type3011 = ref object
|
||||
context: ref object
|
||||
|
||||
type
|
||||
Value3011 = ref object
|
||||
typ: Type3011
|
||||
|
||||
proc x3011(): Value3011 =
|
||||
nil
|
||||
|
||||
34
tests/generics/mopensymimport1.nim
Normal file
34
tests/generics/mopensymimport1.nim
Normal file
@@ -0,0 +1,34 @@
|
||||
type
|
||||
Result*[T, E] = object
|
||||
when T is void:
|
||||
when E is void:
|
||||
oResultPrivate*: bool
|
||||
else:
|
||||
case oResultPrivate*: bool
|
||||
of false:
|
||||
eResultPrivate*: E
|
||||
of true:
|
||||
discard
|
||||
else:
|
||||
when E is void:
|
||||
case oResultPrivate*: bool
|
||||
of false:
|
||||
discard
|
||||
of true:
|
||||
vResultPrivate*: T
|
||||
else:
|
||||
case oResultPrivate*: bool
|
||||
of false:
|
||||
eResultPrivate*: E
|
||||
of true:
|
||||
vResultPrivate*: T
|
||||
|
||||
template valueOr*[T: not void, E](self: Result[T, E], def: untyped): untyped =
|
||||
let s = (self) # TODO avoid copy
|
||||
case s.oResultPrivate
|
||||
of true:
|
||||
s.vResultPrivate
|
||||
of false:
|
||||
when E isnot void:
|
||||
template error: untyped {.used, inject.} = s.eResultPrivate
|
||||
def
|
||||
16
tests/generics/mopensymimport2.nim
Normal file
16
tests/generics/mopensymimport2.nim
Normal file
@@ -0,0 +1,16 @@
|
||||
{.experimental: "genericsOpenSym".}
|
||||
|
||||
import mopensymimport1
|
||||
|
||||
type Xxx = enum
|
||||
error
|
||||
value
|
||||
|
||||
proc f(): Result[int, cstring] =
|
||||
Result[int, cstring](oResultPrivate: false, eResultPrivate: "f")
|
||||
|
||||
proc g*(T: type): string =
|
||||
let x = f().valueOr:
|
||||
return $error
|
||||
|
||||
"ok"
|
||||
14
tests/generics/t23790.nim
Normal file
14
tests/generics/t23790.nim
Normal file
@@ -0,0 +1,14 @@
|
||||
# bug #23790
|
||||
|
||||
discard compiles($default(seq[seq[ref int]]))
|
||||
discard compiles($default(seq[seq[ref uint]]))
|
||||
discard compiles($default(seq[seq[ref int8]]))
|
||||
discard compiles($default(seq[seq[ref uint8]]))
|
||||
discard compiles($default(seq[seq[ref int16]]))
|
||||
discard compiles($default(seq[seq[ref uint16]]))
|
||||
discard compiles($default(seq[seq[ref int32]]))
|
||||
discard compiles($default(seq[seq[ref uint32]]))
|
||||
discard compiles($default(seq[seq[ref int64]]))
|
||||
discard compiles($default(seq[seq[ref uint64]]))
|
||||
proc s(_: int | string) = discard
|
||||
s(0)
|
||||
91
tests/generics/t23853.nim
Normal file
91
tests/generics/t23853.nim
Normal file
@@ -0,0 +1,91 @@
|
||||
# issue #23853
|
||||
|
||||
block simplified:
|
||||
type QuadraticExt[F] = object
|
||||
coords: array[2, F]
|
||||
template Name(E: type QuadraticExt): int = 123
|
||||
template getBigInt(Name: static int): untyped = int
|
||||
type Foo[GT] = object
|
||||
a: getBigInt(GT.Name)
|
||||
var x: Foo[QuadraticExt[int]]
|
||||
|
||||
import std/macros
|
||||
|
||||
type
|
||||
Algebra* = enum
|
||||
BN254_Snarks
|
||||
BLS12_381
|
||||
|
||||
Fp*[Name: static Algebra] = object
|
||||
limbs*: array[4, uint64]
|
||||
|
||||
QuadraticExt*[F] = object
|
||||
## Quadratic Extension field
|
||||
coords*: array[2, F]
|
||||
|
||||
CubicExt*[F] = object
|
||||
## Cubic Extension field
|
||||
coords*: array[3, F]
|
||||
|
||||
ExtensionField*[F] = QuadraticExt[F] or CubicExt[F]
|
||||
|
||||
Fp2*[Name: static Algebra] =
|
||||
QuadraticExt[Fp[Name]]
|
||||
|
||||
Fp4*[Name: static Algebra] =
|
||||
QuadraticExt[Fp2[Name]]
|
||||
|
||||
Fp6*[Name: static Algebra] =
|
||||
CubicExt[Fp2[Name]]
|
||||
|
||||
Fp12*[Name: static Algebra] =
|
||||
CubicExt[Fp4[Name]]
|
||||
# QuadraticExt[Fp6[Name]]
|
||||
|
||||
template Name*(E: type ExtensionField): Algebra =
|
||||
E.F.Name
|
||||
|
||||
const BLS12_381_Order = [uint64 0x1, 0x2, 0x3, 0x4]
|
||||
const BLS12_381_Modulus = [uint64 0x5, 0x6, 0x7, 0x8]
|
||||
|
||||
|
||||
{.experimental: "dynamicBindSym".}
|
||||
|
||||
macro baseFieldModulus*(Name: static Algebra): untyped =
|
||||
result = bindSym($Name & "_Modulus")
|
||||
|
||||
macro scalarFieldModulus*(Name: static Algebra): untyped =
|
||||
result = bindSym($Name & "_Order")
|
||||
|
||||
type FieldKind* = enum
|
||||
kBaseField
|
||||
kScalarField
|
||||
|
||||
template getBigInt*(Name: static Algebra, kind: static FieldKind): untyped =
|
||||
# Workaround:
|
||||
# in `ptr UncheckedArray[BigInt[EC.getScalarField().bits()]]
|
||||
# EC.getScalarField is not accepted by the compiler
|
||||
#
|
||||
# and `ptr UncheckedArray[BigInt[Fr[EC.F.Name].bits]]` gets undeclared field: 'Name'
|
||||
#
|
||||
# but `ptr UncheckedArray[getBigInt(EC.getName(), kScalarField)]` works fine
|
||||
when kind == kBaseField:
|
||||
Name.baseFieldModulus().typeof()
|
||||
else:
|
||||
Name.scalarFieldModulus().typeof()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
type BenchMultiexpContext*[GT] = object
|
||||
elems: seq[GT]
|
||||
exponents: seq[getBigInt(GT.Name, kScalarField)]
|
||||
|
||||
proc createBenchMultiExpContext*(GT: typedesc, inputSizes: openArray[int]): BenchMultiexpContext[GT] =
|
||||
discard
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc main() =
|
||||
let ctx = createBenchMultiExpContext(Fp12[BLS12_381], [2, 4, 8, 16])
|
||||
|
||||
main()
|
||||
@@ -186,3 +186,11 @@ block:
|
||||
|
||||
var b: JsonValueRef[string]
|
||||
scanValue(b)
|
||||
|
||||
block: # bug #21347
|
||||
type K[T] = object
|
||||
template s[T]() = discard
|
||||
proc b1(n: bool | bool) = s[K[K[int]]]()
|
||||
proc b2(n: bool) = s[K[K[int]]]()
|
||||
b1(false) # Error: 's' has unspecified generic parameters
|
||||
b2(false) # Builds, on its own
|
||||
|
||||
@@ -113,3 +113,62 @@ block: # issue #22605, original complex example
|
||||
"ok"
|
||||
|
||||
doAssert g2(int) == "error"
|
||||
|
||||
block: # issue #23865
|
||||
type Xxx = enum
|
||||
error
|
||||
value
|
||||
|
||||
type
|
||||
Result[T, E] = object
|
||||
when T is void:
|
||||
when E is void:
|
||||
oResultPrivate: bool
|
||||
else:
|
||||
case oResultPrivate: bool
|
||||
of false:
|
||||
eResultPrivate: E
|
||||
of true:
|
||||
discard
|
||||
else:
|
||||
when E is void:
|
||||
case oResultPrivate: bool
|
||||
of false:
|
||||
discard
|
||||
of true:
|
||||
vResultPrivate: T
|
||||
else:
|
||||
case oResultPrivate: bool
|
||||
of false:
|
||||
eResultPrivate: E
|
||||
of true:
|
||||
vResultPrivate: T
|
||||
|
||||
func error[T, E](self: Result[T, E]): E =
|
||||
## Fetch error of result if set, or raise Defect
|
||||
case self.oResultPrivate
|
||||
of true:
|
||||
when T isnot void:
|
||||
raiseResultDefect("Trying to access error when value is set", self.vResultPrivate)
|
||||
else:
|
||||
raiseResultDefect("Trying to access error when value is set")
|
||||
of false:
|
||||
when E isnot void:
|
||||
self.eResultPrivate
|
||||
|
||||
template valueOr[T: not void, E](self: Result[T, E], def: untyped): untyped =
|
||||
let s = (self) # TODO avoid copy
|
||||
case s.oResultPrivate
|
||||
of true:
|
||||
s.vResultPrivate
|
||||
of false:
|
||||
when E isnot void:
|
||||
template error: untyped {.used, inject.} = s.eResultPrivate
|
||||
def
|
||||
proc f(): Result[int, cstring] =
|
||||
Result[int, cstring](oResultPrivate: false, eResultPrivate: "f")
|
||||
proc g(T: type): string =
|
||||
let x = f().valueOr:
|
||||
return $error
|
||||
"ok"
|
||||
doAssert g(int) == "f"
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
discard """
|
||||
matrix: "--skipParentCfg --filenames:legacyRelProj"
|
||||
"""
|
||||
|
||||
type Xxx = enum
|
||||
error
|
||||
value
|
||||
@@ -42,8 +46,13 @@ proc f(): Result[int, cstring] =
|
||||
|
||||
proc g(T: type): string =
|
||||
let x = f().valueOr:
|
||||
{.push warningAsError[GenericsIgnoredInjection]: on.}
|
||||
# test spurious error
|
||||
discard true
|
||||
let _ = f
|
||||
{.pop.}
|
||||
return $error #[tt.Warning
|
||||
^ a new symbol 'error' has been injected during instantiation of g, however 'error' [enumField declared in tmacroinjectedsymwarning.nim(2, 3)] captured at the proc declaration will be used instead; either enable --experimental:genericsOpenSym to use the injected symbol or `bind` this captured symbol explicitly [GenericsIgnoredInjection]]#
|
||||
^ a new symbol 'error' has been injected during instantiation of g, however 'error' [enumField declared in tmacroinjectedsymwarning.nim(6, 3)] captured at the proc declaration will be used instead; either enable --experimental:genericsOpenSym to use the injected symbol or `bind` this captured symbol explicitly [GenericsIgnoredInjection]]#
|
||||
|
||||
"ok"
|
||||
|
||||
|
||||
24
tests/generics/tnestedissues.nim
Normal file
24
tests/generics/tnestedissues.nim
Normal file
@@ -0,0 +1,24 @@
|
||||
block: # issue #23568
|
||||
type G[T] = object
|
||||
j: T
|
||||
proc s[T](u: int) = discard
|
||||
proc s[T]() = discard
|
||||
proc c(e: int | int): G[G[G[int]]] = s[G[G[int]]]()
|
||||
discard c(0)
|
||||
|
||||
import std/options
|
||||
|
||||
block: # issue #23310
|
||||
type
|
||||
BID = string or uint64
|
||||
Future[T] = ref object of RootObj
|
||||
internalValue: T
|
||||
InternalRaisesFuture[T] = ref object of Future[T]
|
||||
proc newInternalRaisesFutureImpl[T](): InternalRaisesFuture[T] =
|
||||
let fut = InternalRaisesFuture[T]()
|
||||
template newFuture[T](): auto =
|
||||
newInternalRaisesFutureImpl[T]()
|
||||
proc problematic(blockId: BID): Future[Option[seq[int]]] =
|
||||
let resultFuture = newFuture[Option[seq[int]]]()
|
||||
return resultFuture
|
||||
let x = problematic("latest")
|
||||
5
tests/generics/topensymimport.nim
Normal file
5
tests/generics/topensymimport.nim
Normal file
@@ -0,0 +1,5 @@
|
||||
# issue #23386
|
||||
|
||||
import mopensymimport2
|
||||
|
||||
doAssert g(int) == "f"
|
||||
@@ -140,3 +140,26 @@ block: # issue #1771
|
||||
|
||||
var a: Foo[range[0..2], float]
|
||||
doAssert test(a) == 0.0
|
||||
|
||||
block: # issue #23730
|
||||
proc test(M: static[int]): array[1 shl M, int] = discard
|
||||
doAssert len(test(3)) == 8
|
||||
doAssert len(test(5)) == 32
|
||||
|
||||
block: # issue #19819
|
||||
type
|
||||
Example[N: static int] = distinct int
|
||||
What[E: Example] = Example[E.N + E.N]
|
||||
|
||||
block: # issue #23339
|
||||
type
|
||||
A = object
|
||||
B = object
|
||||
template aToB(t: typedesc[A]): typedesc = B
|
||||
type
|
||||
Inner[I] = object
|
||||
innerField: I
|
||||
Outer[O] = object
|
||||
outerField: Inner[O.aToB]
|
||||
var x: Outer[A]
|
||||
doAssert typeof(x.outerField.innerField) is B
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
discard """
|
||||
errormsg: "cannot instantiate: 'GenericNodeObj[T]'; Maybe generic arguments are missing?"
|
||||
line: 21
|
||||
errormsg: "'Node' is not a concrete type"
|
||||
line: 11
|
||||
"""
|
||||
# bug #2509
|
||||
type
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
discard """
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
doAssert typeOf(1.int64 + 1.int) is int64
|
||||
doAssert typeOf(1.uint64 + 1.uint) is uint64
|
||||
doAssert int64 is SomeNumber
|
||||
@@ -12,3 +16,34 @@ doAssert typeOf(myInt16 + myInt) is int # of type `int`
|
||||
doAssert typeOf(myInt16 + 2i32) is int32 # of type `int32`
|
||||
doAssert int32 isnot int64
|
||||
doAssert int32 isnot int
|
||||
|
||||
block: # bug #23947
|
||||
template foo =
|
||||
let test_u64 : uint64 = 0xFF07.uint64
|
||||
let test_u8 : uint8 = test_u64.uint8
|
||||
# Error: illegal conversion from '65287' to '[0..255]'
|
||||
doAssert test_u8 == 7
|
||||
|
||||
static: foo()
|
||||
foo()
|
||||
|
||||
block:
|
||||
# bug #22085
|
||||
const
|
||||
x = uint32(uint64.high) # vm error
|
||||
u = uint64.high
|
||||
v = uint32(u) # vm error
|
||||
|
||||
let
|
||||
z = uint64.high
|
||||
y = uint32(z) # runtime ok
|
||||
|
||||
let
|
||||
w = uint32(uint64.high) # semfold error
|
||||
|
||||
doAssert x == w
|
||||
doAssert v == y
|
||||
|
||||
# bug #14522
|
||||
doAssert 0xFF000000_00000000.uint64 == 18374686479671623680'u64
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
discard """
|
||||
matrix: "; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
|
||||
targets: "c js"
|
||||
matrix: "; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
|
||||
output: '''
|
||||
0 0
|
||||
0 0
|
||||
@@ -8,7 +7,6 @@ Success'''
|
||||
"""
|
||||
# Test the different integer operations
|
||||
|
||||
# TODO: fixme --backend:js cannot change targets!!!
|
||||
|
||||
import std/private/jsutils
|
||||
|
||||
|
||||
@@ -504,3 +504,26 @@ block: # void iterator
|
||||
except:
|
||||
discard
|
||||
var a = it
|
||||
|
||||
block: # Locals present in only 1 state should be on the stack
|
||||
proc checkOnStack(a: pointer, shouldBeOnStack: bool) =
|
||||
# Quick and dirty way to check if a points to stack
|
||||
var dummy = 0
|
||||
let dummyAddr = addr dummy
|
||||
let distance = abs(cast[int](dummyAddr) - cast[int](a))
|
||||
const requiredDistance = 300
|
||||
if shouldBeOnStack:
|
||||
doAssert(distance <= requiredDistance, "a is not on stack, but should")
|
||||
else:
|
||||
doAssert(distance > requiredDistance, "a is on stack, but should not")
|
||||
|
||||
iterator it(): int {.closure.} =
|
||||
var a = 1
|
||||
var b = 2
|
||||
var c {.liftLocals.} = 3
|
||||
checkOnStack(addr a, true)
|
||||
checkOnStack(addr b, false)
|
||||
checkOnStack(addr c, false)
|
||||
yield a
|
||||
yield b
|
||||
test(it, 1, 2)
|
||||
|
||||
17
tests/js/tdanger.nim
Normal file
17
tests/js/tdanger.nim
Normal file
@@ -0,0 +1,17 @@
|
||||
discard """
|
||||
matrix: ";--d:danger"
|
||||
"""
|
||||
|
||||
block:
|
||||
proc foo() =
|
||||
var name = int64(12)
|
||||
var x = uint32(name)
|
||||
var m = x + 12
|
||||
|
||||
var y = int32(name)
|
||||
var n = y + 1
|
||||
|
||||
doAssert m == uint32(n + 11)
|
||||
|
||||
|
||||
foo()
|
||||
@@ -1,4 +1,5 @@
|
||||
discard """
|
||||
matrix: "--legacy:jsnolambdalifting;"
|
||||
output: '''
|
||||
3
|
||||
2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
matrix: "--jsbigint64:off; --jsbigint64:on"
|
||||
matrix: "--jsbigint64:off -d:nimStringHash2; --jsbigint64:on"
|
||||
"""
|
||||
|
||||
import std/private/jsutils
|
||||
|
||||
37
tests/lookups/t23749.nim
Normal file
37
tests/lookups/t23749.nim
Normal file
@@ -0,0 +1,37 @@
|
||||
discard """
|
||||
action: compile
|
||||
"""
|
||||
|
||||
{.pragma: callback, gcsafe, raises: [].}
|
||||
|
||||
type
|
||||
DataProc* = proc(val: openArray[byte]) {.callback.}
|
||||
GetProc = proc (db: RootRef, key: openArray[byte], onData: DataProc): bool {.nimcall, callback.}
|
||||
KvStoreRef* = ref object
|
||||
obj: RootRef
|
||||
getProc: GetProc
|
||||
|
||||
template get(dbParam: KvStoreRef, key: openArray[byte], onData: untyped): bool =
|
||||
let db = dbParam
|
||||
db.getProc(db.obj, key, onData)
|
||||
|
||||
func decode(input: openArray[byte], maxSize = 128): seq[byte] =
|
||||
@[]
|
||||
|
||||
proc getSnappySSZ(db: KvStoreRef, key: openArray[byte]): string =
|
||||
var status = "not found"
|
||||
proc decode(data: openArray[byte]) =
|
||||
status =
|
||||
if true: "found"
|
||||
else: "corrupted"
|
||||
discard db.get(key, decode)
|
||||
status
|
||||
|
||||
|
||||
var ksr: KvStoreRef
|
||||
var k = [byte(1), 2, 3, 4, 5]
|
||||
|
||||
proc foo(): string =
|
||||
getSnappySSZ(ksr, toOpenArray(k, 1, 3))
|
||||
|
||||
echo foo()
|
||||
22
tests/lookups/tenumlocalsym.nim
Normal file
22
tests/lookups/tenumlocalsym.nim
Normal file
@@ -0,0 +1,22 @@
|
||||
block:
|
||||
type Enum = enum a, b
|
||||
|
||||
block:
|
||||
let a = b
|
||||
let x: Enum = a
|
||||
doAssert x == b
|
||||
|
||||
block:
|
||||
type
|
||||
Enum = enum
|
||||
a = 2
|
||||
b = 10
|
||||
|
||||
iterator items2(): Enum =
|
||||
for a in [a, b]:
|
||||
yield a
|
||||
|
||||
var s = newSeq[Enum]()
|
||||
for i in items2():
|
||||
s.add i
|
||||
doAssert s == @[a, b]
|
||||
13
tests/lookups/tmoduleclash1.nim
Normal file
13
tests/lookups/tmoduleclash1.nim
Normal file
@@ -0,0 +1,13 @@
|
||||
# issue #23596
|
||||
|
||||
import std/heapqueue
|
||||
type Algo = enum heapqueue, quick
|
||||
when false:
|
||||
let x = heapqueue
|
||||
let y: Algo = heapqueue
|
||||
proc bar*(algo=quick) =
|
||||
var x: HeapQueue[int]
|
||||
case algo
|
||||
of heapqueue: echo 1 # `Algo.heapqueue` works on devel
|
||||
of quick: echo 2
|
||||
echo x.len
|
||||
6
tests/lookups/tmoduleclash2.nim
Normal file
6
tests/lookups/tmoduleclash2.nim
Normal file
@@ -0,0 +1,6 @@
|
||||
import std/heapqueue
|
||||
proc heapqueue(x: int) = discard
|
||||
let x: proc (x: int) = heapqueue
|
||||
let y: proc = heapqueue
|
||||
when false:
|
||||
let z = heapqueue
|
||||
23
tests/macros/t23547.nim
Normal file
23
tests/macros/t23547.nim
Normal file
@@ -0,0 +1,23 @@
|
||||
# https://github.com/nim-lang/Nim/issues/23547
|
||||
|
||||
type
|
||||
A[T] = object
|
||||
x: T
|
||||
|
||||
proc mulCheckSparse[F](dummy: var A[F], xmulchecksparse: static A[F]) =
|
||||
static:
|
||||
echo "mulCheckSparse: ", typeof(dummy), ", ", typeof(xmulchecksparse) # when generic params not specified: A[system.int], A
|
||||
|
||||
template sumImpl(xsumimpl: typed) =
|
||||
static:
|
||||
echo "sumImpl: ", typeof(xsumimpl) # A
|
||||
var a = A[int](x: 55)
|
||||
mulCheckSparse(a, xsumimpl) # fails here
|
||||
|
||||
proc sum[T](xsum: static T) =
|
||||
static:
|
||||
echo "sum: ", typeof(xsum) # A[system.int]
|
||||
sumImpl(xsum)
|
||||
|
||||
const constA = A[int](x : 100)
|
||||
sum[A[int]](constA)
|
||||
157
tests/macros/t23784.nim
Normal file
157
tests/macros/t23784.nim
Normal file
@@ -0,0 +1,157 @@
|
||||
discard """
|
||||
joinable: false
|
||||
"""
|
||||
|
||||
|
||||
# debug ICE: genCheckedRecordField
|
||||
# apparently after https://github.com/nim-lang/Nim/pull/23477
|
||||
|
||||
# bug #23784
|
||||
|
||||
import std/bitops, std/macros
|
||||
|
||||
# --------------------------------------------------------------
|
||||
|
||||
type Algebra = enum
|
||||
BN254_Snarks
|
||||
|
||||
type SecretWord* = distinct uint64
|
||||
const WordBitWidth* = sizeof(SecretWord) * 8
|
||||
|
||||
func wordsRequired*(bits: int): int {.inline.} =
|
||||
const divShiftor = fastLog2(WordBitWidth)
|
||||
result = (bits + WordBitWidth - 1) shr divShiftor
|
||||
|
||||
type
|
||||
BigInt*[bits: static int] = object
|
||||
limbs*: array[bits.wordsRequired, SecretWord] # <--- crash points to here
|
||||
|
||||
# --------------------------------------------------------------
|
||||
|
||||
const CurveBitWidth = [
|
||||
BN254_Snarks: 254
|
||||
]
|
||||
|
||||
const BN254_Snarks_Modulus = BigInt[254](limbs: [SecretWord 0x1, SecretWord 0x2, SecretWord 0x3, SecretWord 0x4])
|
||||
const BN254_Snarks_Order = BigInt[254](limbs: [SecretWord 0x1, SecretWord 0x1, SecretWord 0x2, SecretWord 0x2])
|
||||
|
||||
func montyOne*(M: BigInt[254]): BigInt[254] =
|
||||
## Returns "1 (mod M)" in the Montgomery domain.
|
||||
## This is equivalent to R (mod M) in the natural domain
|
||||
BigInt[254](limbs: [SecretWord 0x1, SecretWord 0x1, SecretWord 0x1, SecretWord 0x1])
|
||||
|
||||
|
||||
{.experimental: "dynamicBindSym".}
|
||||
|
||||
type
|
||||
DerivedConstantMode* = enum
|
||||
kModulus
|
||||
kOrder
|
||||
|
||||
macro genDerivedConstants*(mode: static DerivedConstantMode): untyped =
|
||||
## Generate constants derived from the main constants
|
||||
##
|
||||
## For example
|
||||
## - the Montgomery magic constant "R^2 mod N" in ROM
|
||||
## For each curve under the private symbol "MyCurve_R2modP"
|
||||
## - the Montgomery magic constant -1/P mod 2^Wordbitwidth
|
||||
## For each curve under the private symbol "MyCurve_NegInvModWord
|
||||
## - ...
|
||||
|
||||
# Now typedesc are NimNode and there is no way to translate
|
||||
# NimNode -> typedesc easily so we can't
|
||||
# "for curve in low(Curve) .. high(Curve):"
|
||||
# As an ugly workaround, we count
|
||||
# The item at position 0 is a pragma
|
||||
result = newStmtList()
|
||||
|
||||
template used(name: string): NimNode =
|
||||
nnkPragmaExpr.newTree(
|
||||
ident(name),
|
||||
nnkPragma.newTree(ident"used")
|
||||
)
|
||||
|
||||
let ff = if mode == kModulus: "_Fp" else: "_Fr"
|
||||
|
||||
for curveSym in low(Algebra) .. high(Algebra):
|
||||
let curve = $curveSym
|
||||
let M = if mode == kModulus: bindSym(curve & "_Modulus")
|
||||
else: bindSym(curve & "_Order")
|
||||
|
||||
# const MyCurve_montyOne = montyOne(MyCurve_Modulus)
|
||||
result.add newConstStmt(
|
||||
used(curve & ff & "_MontyOne"), newCall(
|
||||
bindSym"montyOne",
|
||||
M
|
||||
)
|
||||
)
|
||||
|
||||
# --------------------------------------------------------------
|
||||
|
||||
{.experimental: "dynamicBindSym".}
|
||||
|
||||
genDerivedConstants(kModulus)
|
||||
genDerivedConstants(kOrder)
|
||||
|
||||
proc bindConstant(ff: NimNode, property: string): NimNode =
|
||||
# Need to workaround https://github.com/nim-lang/Nim/issues/14021
|
||||
# which prevents checking if a type FF[Name] = Fp[Name] or Fr[Name]
|
||||
# was instantiated with Fp or Fr.
|
||||
# getTypeInst only returns FF and sameType doesn't work.
|
||||
# so quote do + when checks.
|
||||
let T = getTypeInst(ff)
|
||||
T.expectKind(nnkBracketExpr)
|
||||
doAssert T[0].eqIdent("typedesc")
|
||||
|
||||
let curve =
|
||||
if T[1].kind == nnkBracketExpr: # typedesc[Fp[BLS12_381]] as used internally
|
||||
# doAssert T[1][0].eqIdent"Fp" or T[1][0].eqIdent"Fr", "Found ident: '" & $T[1][0] & "' instead of 'Fp' or 'Fr'"
|
||||
T[1][1].expectKind(nnkIntLit) # static enum are ints in the VM
|
||||
$Algebra(T[1][1].intVal)
|
||||
else: # typedesc[bls12381_fp] alias as used for C exports
|
||||
let T1 = getTypeInst(T[1].getImpl()[2])
|
||||
if T1.kind != nnkBracketExpr or
|
||||
T1[1].kind != nnkIntLit:
|
||||
echo T.repr()
|
||||
echo T1.repr()
|
||||
echo getTypeInst(T1).treerepr()
|
||||
error "getTypeInst didn't return the full instantiation." &
|
||||
" Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44"
|
||||
$Algebra(T1[1].intVal)
|
||||
|
||||
let curve_fp = bindSym(curve & "_Fp_" & property)
|
||||
let curve_fr = bindSym(curve & "_Fr_" & property)
|
||||
result = quote do:
|
||||
when `ff` is Fp:
|
||||
`curve_fp`
|
||||
elif `ff` is Fr:
|
||||
`curve_fr`
|
||||
else:
|
||||
{.error: "Unreachable, received type: " & $`ff`.}
|
||||
|
||||
# --------------------------------------------------------------
|
||||
|
||||
template matchingBigInt*(Name: static Algebra): untyped =
|
||||
## BigInt type necessary to store the prime field Fp
|
||||
# Workaround: https://github.com/nim-lang/Nim/issues/16774
|
||||
# as we cannot do array accesses in type section.
|
||||
# Due to generic sandwiches, it must be exported.
|
||||
BigInt[CurveBitWidth[Name]]
|
||||
|
||||
type
|
||||
Fp*[Name: static Algebra] = object
|
||||
mres*: matchingBigInt(Name)
|
||||
|
||||
macro getMontyOne*(ff: type Fp): untyped =
|
||||
## Get one in Montgomery representation (i.e. R mod P)
|
||||
result = bindConstant(ff, "MontyOne")
|
||||
|
||||
func getOne*(T: type Fp): T {.noInit, inline.} =
|
||||
result = cast[ptr T](unsafeAddr getMontyOne(T))[]
|
||||
|
||||
# --------------------------------------------------------------
|
||||
proc foo(T: Fp) =
|
||||
discard T
|
||||
|
||||
let a = Fp[BN254_Snarks].getOne()
|
||||
foo(a) # oops this was a leftover that broke the bisect.
|
||||
@@ -365,3 +365,14 @@ block: # enum.len
|
||||
doAssert MyEnum.enumLen == 4
|
||||
doAssert OtherEnum.enumLen == 3
|
||||
doAssert MyFlag.enumLen == 4
|
||||
|
||||
when true: # Odd bug where alias can seep inside of `distinctBase`
|
||||
import std/unittest
|
||||
|
||||
type
|
||||
AdtChild* = concept t
|
||||
distinctBase(t)
|
||||
|
||||
proc `$`*[T: AdtChild](adtChild: T): string = ""
|
||||
|
||||
check 10 is int
|
||||
|
||||
28
tests/metatype/twrong_same_type.nim
Normal file
28
tests/metatype/twrong_same_type.nim
Normal file
@@ -0,0 +1,28 @@
|
||||
# bug #23418
|
||||
|
||||
template mapIt*(x: untyped): untyped =
|
||||
type OutType {.gensym.} = typeof(x) #typeof(x, typeOfProc)
|
||||
newSeq[OutType](5)
|
||||
|
||||
type F[E] = object
|
||||
|
||||
proc start(v: int): F[(ValueError,)] = discard
|
||||
proc stop(v: int): F[tuple[]] = discard
|
||||
|
||||
assert $typeof(mapIt(start(9))) == "seq[F[(ValueError,)]]"
|
||||
assert $typeof(mapIt(stop(9))) == "seq[F[tuple[]]]"
|
||||
|
||||
# bug #23445
|
||||
|
||||
type F2[T; I: static int] = distinct int
|
||||
|
||||
proc start2(v: int): F2[void, 22] = discard
|
||||
proc stop2(v: int): F2[void, 33] = discard
|
||||
|
||||
var a = mapIt(start2(5))
|
||||
|
||||
assert $type(a) == "seq[F2[system.void, 22]]", $type(a)
|
||||
|
||||
var b = mapIt(stop2(5))
|
||||
|
||||
assert $type(b) == "seq[F2[system.void, 33]]", $type(b)
|
||||
@@ -9,3 +9,6 @@ const
|
||||
type
|
||||
MyEnum* = enum
|
||||
foo, bar
|
||||
|
||||
proc foo2*[T: int, M: string, U](x: T, y: U, z: M) =
|
||||
echo 1
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -224,13 +224,15 @@ sub/mmain.idx""", context
|
||||
doAssert exitCode == 0, msg
|
||||
|
||||
let data = parseJson(readFile(output))["entries"]
|
||||
doAssert data.len == 4
|
||||
doAssert data.len == 5
|
||||
let doSomething = data[0]
|
||||
doAssert doSomething["name"].getStr == "doSomething"
|
||||
doAssert doSomething["type"].getStr == "skProc"
|
||||
doAssert doSomething["line"].getInt == 1
|
||||
doAssert doSomething["col"].getInt == 0
|
||||
doAssert doSomething["code"].getStr == "proc doSomething(x, y: int): int {.raises: [], tags: [], forbids: [].}"
|
||||
let foo2 = data[4]
|
||||
doAssert $foo2["signature"] == """{"arguments":[{"name":"x","type":"T"},{"name":"y","type":"U"},{"name":"z","type":"M"}],"genericParams":[{"name":"T","types":"int"},{"name":"M","types":"string"},{"name":"U"}]}"""
|
||||
|
||||
block: # nim jsondoc # bug #11953
|
||||
let file = testsDir / "misc/mjsondoc.nim"
|
||||
@@ -241,7 +243,7 @@ sub/mmain.idx""", context
|
||||
doAssert exitCode == 0, msg
|
||||
|
||||
let data = parseJson(readFile(destDir / "mjsondoc.json"))["entries"]
|
||||
doAssert data.len == 4
|
||||
doAssert data.len == 5
|
||||
let doSomething = data[0]
|
||||
doAssert doSomething["name"].getStr == "doSomething"
|
||||
doAssert doSomething["type"].getStr == "skProc"
|
||||
|
||||
@@ -18,7 +18,7 @@ renderer.setDrawColor 29, 64, 153, 255
|
||||
renderer.clear
|
||||
renderer.setDrawColor 255, 255, 255, 255
|
||||
|
||||
when defined(c):
|
||||
when false: # no long work with gcc 14!
|
||||
# just to ensure code from NimInAction still works, but
|
||||
# the `else` branch would work as well in C mode
|
||||
var points = [
|
||||
|
||||
@@ -121,7 +121,7 @@ template main {.dirty.} =
|
||||
rVal: R = default(R) # Works fine
|
||||
objVal = default(Obj)
|
||||
|
||||
doAssert rVal == 0 # it should be 1
|
||||
doAssert rVal == 1
|
||||
doAssert objVal.r == 1
|
||||
|
||||
block: # bug #16744
|
||||
@@ -134,7 +134,7 @@ template main {.dirty.} =
|
||||
rVal: R = default(R) # Works fine
|
||||
objVal = Obj()
|
||||
|
||||
doAssert rVal == 0 # it should be 1
|
||||
doAssert rVal == 1 # it should be 1
|
||||
doAssert objVal.r == 1
|
||||
|
||||
block: # bug #3608
|
||||
@@ -745,5 +745,19 @@ template main {.dirty.} =
|
||||
doAssert b.list[North] == 1
|
||||
|
||||
|
||||
block:
|
||||
type
|
||||
range1 = range[1..10]
|
||||
range2 = range[-1..10]
|
||||
|
||||
proc foo =
|
||||
doAssert default(range1) == 1
|
||||
doAssert default(range2) == -1
|
||||
|
||||
let s = default(array[5, range1])
|
||||
doAssert s == [range1 1, 1, 1, 1, 1]
|
||||
|
||||
foo()
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
19
tests/openarray/tuncheckedarray.nim
Normal file
19
tests/openarray/tuncheckedarray.nim
Normal file
@@ -0,0 +1,19 @@
|
||||
discard """
|
||||
exitcode: 0
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
proc main =
|
||||
block: # issue 19171
|
||||
var a = ['A']
|
||||
proc mutB(x: var openArray[char]) =
|
||||
x[0] = 'B'
|
||||
mutB(toOpenArray(cast[ptr UncheckedArray[char]](addr a), 0, 0))
|
||||
doAssert a[0] == 'B'
|
||||
proc mutC(x: var openArray[char]; c: char) =
|
||||
x[0] = c
|
||||
let p = cast[ptr UncheckedArray[char]](addr a)
|
||||
mutC(toOpenArray(p, 0, 0), 'C')
|
||||
doAssert p[0] == 'C'
|
||||
|
||||
main()
|
||||
33
tests/osproc/twaitforexit.nim
Normal file
33
tests/osproc/twaitforexit.nim
Normal file
@@ -0,0 +1,33 @@
|
||||
import std/[osproc, os, times]
|
||||
|
||||
block: # bug #5091
|
||||
when defined(linux):
|
||||
const filename = "false"
|
||||
var p = startProcess(filename, options = {poStdErrToStdOut, poUsePath})
|
||||
os.sleep(1000) # make sure process has exited already
|
||||
|
||||
let atStart = getTime()
|
||||
const msWait = 2000
|
||||
|
||||
try:
|
||||
discard waitForExit(p, msWait)
|
||||
except OSError:
|
||||
discard
|
||||
|
||||
# check that we don't have to wait msWait milliseconds
|
||||
doAssert(getTime() < atStart + milliseconds(msWait))
|
||||
|
||||
block: # bug #23825
|
||||
var thr: array[0..99, Thread[int]]
|
||||
|
||||
proc threadFunc(i: int) {.thread.} =
|
||||
let sleepTime = float(i) / float(thr.len + 1)
|
||||
doAssert sleepTime < 1.0
|
||||
let p = startProcess("sleep", workingDir = "", args = @[$sleepTime], options = {poUsePath, poParentStreams})
|
||||
# timeout = 1_000_000 seconds ~= 278 hours ~= 11.5 days
|
||||
doAssert p.waitForExit(timeout=1_000_000_000) == 0
|
||||
|
||||
for i in low(thr)..high(thr):
|
||||
createThread(thr[i], threadFunc, i)
|
||||
|
||||
joinThreads(thr)
|
||||
62
tests/overload/t23755.nim
Normal file
62
tests/overload/t23755.nim
Normal file
@@ -0,0 +1,62 @@
|
||||
type
|
||||
BigInt[bits: static int] = object
|
||||
limbs: array[8, uint64]
|
||||
|
||||
block:
|
||||
proc view[N](a: array[N, uint64]) =
|
||||
discard
|
||||
|
||||
proc view[N](a: var array[N, uint64]) =
|
||||
discard
|
||||
|
||||
var r: BigInt[64]
|
||||
r.limbs.view()
|
||||
|
||||
|
||||
type Limbs[N: static int] = array[N, uint64]
|
||||
|
||||
block:
|
||||
proc view(a: Limbs) =
|
||||
discard
|
||||
|
||||
proc view(a: var Limbs) =
|
||||
discard
|
||||
|
||||
var r: BigInt[64]
|
||||
r.limbs.view()
|
||||
|
||||
|
||||
block:
|
||||
type IntArray[N: static[int]] = array[N, int]
|
||||
|
||||
proc p[T](a: IntArray[T]): bool= true
|
||||
proc p(a: IntArray[5]): bool= false
|
||||
|
||||
var s: IntArray[5]
|
||||
doAssert s.p == false
|
||||
|
||||
block:
|
||||
type IntArray[N: static[int]] = array[N, int]
|
||||
|
||||
proc `$`(a: IntArray): string =
|
||||
return "test"
|
||||
|
||||
var s: IntArray[5] = [1,1,1,1,1]
|
||||
doAssert `$`(s) == "test"
|
||||
|
||||
block:
|
||||
proc p[n:static[int]](a: array[n, char]):bool=true
|
||||
proc p[T, IDX](a: array[IDX, T]):bool=false
|
||||
|
||||
var g: array[32, char]
|
||||
doAssert p(g)
|
||||
|
||||
block: # issue #23823
|
||||
func p[N,T](a, b: array[N,T]) =
|
||||
discard
|
||||
|
||||
func p[N: static int; T](x, y: array[N, T]) =
|
||||
discard
|
||||
|
||||
var a: array[5, int]
|
||||
p(a,a)
|
||||
@@ -2,7 +2,7 @@ block:
|
||||
let txt = "Hello World"
|
||||
|
||||
template `[]`[T](p: ptr T, span: Slice[int]): untyped =
|
||||
toOpenArray(cast[ptr array[0, T]](p)[], span.a, span.b)
|
||||
toOpenArray(cast[ptr UncheckedArray[T]](p), span.a, span.b)
|
||||
|
||||
doAssert $cast[ptr uint8](txt[0].addr)[0 ..< txt.len] ==
|
||||
"[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]"
|
||||
@@ -12,7 +12,7 @@ block:
|
||||
let txt = "Hello World"
|
||||
|
||||
template `[]`[T](p: ptr T, span: Slice[int]): untyped =
|
||||
toOpenArray(cast[ptr array[0, T]](p)[], span.a, span.b)
|
||||
toOpenArray(cast[ptr UncheckedArray[T]](p), span.a, span.b)
|
||||
|
||||
doAssert $cast[ptr uint8](txt[0].addr)[0 ..< txt.len] ==
|
||||
"[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]"
|
||||
|
||||
@@ -77,27 +77,30 @@ testPred(1)
|
||||
|
||||
|
||||
|
||||
# bug #6526
|
||||
type
|
||||
BaseObj = ref object of RootObj
|
||||
DerivedObj = ref object of BaseObj
|
||||
OtherDerivate = ref object of BaseObj
|
||||
block: # bug #6526
|
||||
type
|
||||
BaseObj = ref object of RootObj
|
||||
DerivedObj = ref object of BaseObj
|
||||
OtherDerivate = ref object of BaseObj
|
||||
|
||||
proc `==`*[T1, T2: BaseObj](a: T1, b: T2): bool =
|
||||
echo "baseobj =="
|
||||
return true
|
||||
proc p[T](a: T, b: T): bool =
|
||||
assert false
|
||||
|
||||
let a = DerivedObj()
|
||||
let b = DerivedObj()
|
||||
echo a == b
|
||||
proc p[T1, T2: BaseObj](a: T1, b: T2): bool =
|
||||
echo "baseobj =="
|
||||
return true
|
||||
|
||||
proc `==`*[T1, T2: OtherDerivate](a: T1, b: T2): bool =
|
||||
echo "even better! =="
|
||||
return true
|
||||
let a = DerivedObj()
|
||||
let b = DerivedObj()
|
||||
echo p(a,b)
|
||||
|
||||
let a2 = OtherDerivate()
|
||||
let b2 = OtherDerivate()
|
||||
echo a2 == b2
|
||||
proc p[T1, T2: OtherDerivate](a: T1, b: T2): bool =
|
||||
echo "even better! =="
|
||||
return true
|
||||
|
||||
let a2 = OtherDerivate()
|
||||
let b2 = OtherDerivate()
|
||||
echo p(a2, b2)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -506,3 +506,63 @@ block:
|
||||
doAssert(p2(F(float,1.0),F(float,2)) == 3.0)
|
||||
doAssert(p2(F(float,1.0),F(float,2.0)) == 3.0)
|
||||
#doAssert(p2(F(float,1),F(int,2.0)) == 3.0)
|
||||
|
||||
block: # PR #23870
|
||||
type
|
||||
A {.inheritable.} = object
|
||||
B = object of A
|
||||
C = object of B
|
||||
|
||||
proc p[T: A](x: T): int = 0
|
||||
proc p[T: B](x: T): int = 1
|
||||
|
||||
proc d(x: A): int = 0
|
||||
proc d(x: B): int = 1
|
||||
|
||||
proc g[T:A](x: typedesc[T]): int = 0
|
||||
proc g[T: B](x: typedesc[T]): int = 1
|
||||
|
||||
proc f[T](x: typedesc[T]): int = 0
|
||||
proc f[T:B](x: typedesc[T]): int = 1
|
||||
|
||||
assert p(C()) == 1
|
||||
assert d(C()) == 1
|
||||
assert g(C) == 1
|
||||
assert f(C) == 1
|
||||
|
||||
block: # PR #23870
|
||||
type
|
||||
A = object of RootObj
|
||||
PT = proc(ev: A) {.closure.}
|
||||
sdt = seq[(PT, PT)]
|
||||
|
||||
proc encap() =
|
||||
proc p(a: A) {.closure.} =
|
||||
discard
|
||||
|
||||
var s: sdt
|
||||
s.add (p, nil)
|
||||
|
||||
encap()
|
||||
|
||||
block: # PR #23870
|
||||
type
|
||||
A = object of RootObj
|
||||
B = object of A
|
||||
C = object of B
|
||||
|
||||
proc p(a: B | RootObj): int =
|
||||
0
|
||||
|
||||
proc p(a: A | A): int =
|
||||
1
|
||||
|
||||
assert p(C()) == 0
|
||||
|
||||
proc d(a: RootObj | B): int =
|
||||
0
|
||||
|
||||
proc d(a: A | A): int =
|
||||
1
|
||||
|
||||
assert d(C()) == 0
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
discard """
|
||||
output: '''ob2 @[]
|
||||
ob @[]
|
||||
ob3 @[]
|
||||
3
|
||||
ob2 @[]
|
||||
ob @[]
|
||||
ob3 @[]
|
||||
'''
|
||||
matrix: "--mm:refc"
|
||||
"""
|
||||
|
||||
# bug #4776
|
||||
|
||||
import tables
|
||||
import tables, algorithm
|
||||
|
||||
type
|
||||
Base* = ref object of RootObj
|
||||
@@ -35,20 +27,21 @@ globalTable.add("ob", d)
|
||||
globalTable.add("ob2", d)
|
||||
globalTable.add("ob3", d)
|
||||
|
||||
proc `<`(x, y: seq[int]): bool = x.len < y.len
|
||||
proc kvs(t: TableRef[string, Base]): seq[(string, seq[int])] =
|
||||
for k, v in t.pairs: result.add (k, v.someSeq)
|
||||
result.sort
|
||||
|
||||
proc testThread(channel: ptr TableChannel) {.thread.} =
|
||||
globalTable = channel[].recv()
|
||||
for k, v in pairs globaltable:
|
||||
echo k, " ", v.someSeq
|
||||
var myObj: Base
|
||||
deepCopy(myObj, globalTable["ob"])
|
||||
myObj.someSeq = newSeq[int](100)
|
||||
let table = channel[].recv() # same table
|
||||
echo table.len
|
||||
for k, v in mpairs table:
|
||||
echo k, " ", v.someSeq
|
||||
assert(table.contains("ob")) # fails!
|
||||
assert(table.contains("ob2")) # fails!
|
||||
assert(table.contains("ob3")) # fails!
|
||||
assert table.kvs == globalTable.kvs # Last to see above spot checks first
|
||||
|
||||
var channel: TableChannel
|
||||
|
||||
|
||||
@@ -99,3 +99,28 @@ block: # bug #23019
|
||||
k(w)
|
||||
{.pop.}
|
||||
{.pop.}
|
||||
|
||||
{.push exportC.}
|
||||
|
||||
block:
|
||||
proc foo11() =
|
||||
const factor = [1, 2, 3, 4]
|
||||
doAssert factor[0] == 1
|
||||
proc foo21() =
|
||||
const factor = [1, 2, 3, 4]
|
||||
doAssert factor[0] == 1
|
||||
|
||||
foo11()
|
||||
foo21()
|
||||
|
||||
template foo31() =
|
||||
let factor = [1, 2, 3, 4]
|
||||
doAssert factor[0] == 1
|
||||
template foo41() =
|
||||
let factor = [1, 2, 3, 4]
|
||||
doAssert factor[0] == 1
|
||||
|
||||
foo31()
|
||||
foo41()
|
||||
|
||||
{.pop.}
|
||||
|
||||
26
tests/proc/t23874.nim
Normal file
26
tests/proc/t23874.nim
Normal file
@@ -0,0 +1,26 @@
|
||||
block:
|
||||
type Head[T] = object
|
||||
wasc: bool
|
||||
|
||||
proc `=destroy`[T](x: var Head[T]) =
|
||||
discard
|
||||
|
||||
proc `=copy`[T](x: var Head[T], y: Head[T]) =
|
||||
x.wasc = true
|
||||
|
||||
proc `=dup`[T](x: Head[T]): Head[T] =
|
||||
result.wasc = true
|
||||
|
||||
proc update(h: var Head) =
|
||||
discard
|
||||
|
||||
proc digest(h: sink Head) =
|
||||
assert h.wasc
|
||||
|
||||
var h = Head[int](wasc: false)
|
||||
h.digest() # sink h
|
||||
h.update() # use after sink
|
||||
|
||||
block:
|
||||
proc two(a: sink auto) =discard
|
||||
assert typeof(two[int]) is proc(a: sink int) {.nimcall.}
|
||||
@@ -1,8 +1,8 @@
|
||||
discard """
|
||||
cmd: "nim check --hint:Processing:off --hint:Conf:off $file"
|
||||
errormsg: "18446744073709551615 can't be converted to int8"
|
||||
nimout: '''tcompiletime_range_checks.nim(36, 21) Error: 2147483648 can't be converted to int32
|
||||
tcompiletime_range_checks.nim(37, 23) Error: -1 can't be converted to uint64
|
||||
nimout: '''
|
||||
tcompiletime_range_checks.nim(36, 21) Error: 2147483648 can't be converted to int32
|
||||
tcompiletime_range_checks.nim(38, 34) Error: 255 can't be converted to FullNegativeRange
|
||||
tcompiletime_range_checks.nim(39, 34) Error: 18446744073709551615 can't be converted to HalfNegativeRange
|
||||
tcompiletime_range_checks.nim(40, 34) Error: 300 can't be converted to FullPositiveRange
|
||||
|
||||
26
tests/refc/tsinkbug.nim
Normal file
26
tests/refc/tsinkbug.nim
Normal file
@@ -0,0 +1,26 @@
|
||||
discard """
|
||||
matrix: "--gc:refc; --gc:arc"
|
||||
output: '''
|
||||
Value is: 42
|
||||
Value is: 42'''
|
||||
"""
|
||||
|
||||
type AnObject* = object of RootObj
|
||||
value*: int
|
||||
|
||||
proc mutate(a: sink AnObject) =
|
||||
a.value = 1
|
||||
|
||||
var obj = AnObject(value: 42)
|
||||
echo "Value is: ", obj.value
|
||||
mutate(obj)
|
||||
echo "Value is: ", obj.value
|
||||
|
||||
proc p(x: sink string) =
|
||||
var y = move(x)
|
||||
doAssert x.len == 0
|
||||
doAssert y.len == 4
|
||||
|
||||
p("1234")
|
||||
var s = "oooo"
|
||||
p(s)
|
||||
@@ -84,6 +84,9 @@ let t = polar(a)
|
||||
doAssert(rect(t.r, t.phi) =~ a)
|
||||
doAssert(rect(1.0, 2.0) =~ complex(-0.4161468365471424, 0.9092974268256817))
|
||||
|
||||
doAssert(almostEqual(a, a + complex(1e-16, 1e-16)))
|
||||
doAssert(almostEqual(a, a + complex(2e-15, 2e-15), unitsInLastPlace = 5))
|
||||
|
||||
|
||||
let
|
||||
i64: Complex32 = complex(0.0f, 1.0f)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:on; --backend:js --jsbigint64:off"
|
||||
matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:on; --backend:c -d:nimStringHash2; --backend:cpp -d:nimStringHash2; --backend:js -d:nimStringHash2"
|
||||
"""
|
||||
|
||||
import std/hashes
|
||||
@@ -31,7 +31,8 @@ block hashes:
|
||||
doAssert hashWangYi1(123) == wy123
|
||||
const wyNeg123 = hashWangYi1(-123)
|
||||
doAssert wyNeg123 != 0
|
||||
doAssert hashWangYi1(-123) == wyNeg123
|
||||
when not defined(js): # TODO: fixme it doesn't work for JS
|
||||
doAssert hashWangYi1(-123) == wyNeg123
|
||||
|
||||
|
||||
# "hashIdentity value incorrect at 456"
|
||||
@@ -45,20 +46,31 @@ block hashes:
|
||||
else:
|
||||
doAssert hashWangYi1(456) == -6421749900419628582
|
||||
|
||||
template jsNoInt64: untyped =
|
||||
when defined js:
|
||||
when compiles(compileOption("jsbigint64")):
|
||||
when not compileOption("jsbigint64"): true
|
||||
else: false
|
||||
else: false
|
||||
else: false
|
||||
const sHash2 = (when defined(nimStringHash2) or jsNoInt64(): true else: false)
|
||||
|
||||
block empty:
|
||||
const emptyStrHash = # Hash=int=4B on js even w/--jsbigint64:on => cast[Hash]
|
||||
when sHash2: 0 else: cast[Hash](-7286425919675154353i64)
|
||||
var
|
||||
a = ""
|
||||
b = newSeq[char]()
|
||||
c = newSeq[int]()
|
||||
d = cstring""
|
||||
e = "abcd"
|
||||
doAssert hash(a) == 0
|
||||
doAssert hash(b) == 0
|
||||
doAssert hash(a) == emptyStrHash
|
||||
doAssert hash(b) == emptyStrHash
|
||||
doAssert hash(c) == 0
|
||||
doAssert hash(d) == 0
|
||||
doAssert hash(d) == emptyStrHash
|
||||
doAssert hashIgnoreCase(a) == 0
|
||||
doAssert hashIgnoreStyle(a) == 0
|
||||
doAssert hash(e, 3, 2) == 0
|
||||
doAssert hash(e, 3, 2) == emptyStrHash
|
||||
|
||||
block sameButDifferent:
|
||||
doAssert hash("aa bb aaaa1234") == hash("aa bb aaaa1234", 0, 13)
|
||||
@@ -92,7 +104,10 @@ block largeSize: # longer than 4 characters
|
||||
proc main() =
|
||||
doAssert hash(0.0) == hash(0)
|
||||
# bug #16061
|
||||
doAssert hash(cstring"abracadabra") == 97309975
|
||||
when not sHash2: # Hash=int=4B on js even w/--jsbigint64:on => cast[Hash]
|
||||
doAssert hash(cstring"abracadabra") == cast[Hash](-1119910118870047694i64)
|
||||
else:
|
||||
doAssert hash(cstring"abracadabra") == 97309975
|
||||
doAssert hash(cstring"abracadabra") == hash("abracadabra")
|
||||
|
||||
when sizeof(int) == 8 or defined(js):
|
||||
|
||||
@@ -53,9 +53,9 @@ proc asyncTest() {.async.} =
|
||||
doAssert("<title>Example Domain</title>" in body)
|
||||
|
||||
resp = await client.request("http://example.com/404")
|
||||
doAssert(resp.code.is4xx)
|
||||
doAssert(resp.code == Http404)
|
||||
doAssert(resp.status == $Http404)
|
||||
doAssert(resp.code.is4xx or resp.code.is5xx)
|
||||
doAssert(resp.code == Http404 or resp.code == Http500)
|
||||
doAssert(resp.status == $Http404 or resp.status == $Http500)
|
||||
|
||||
when false: # occasionally does not give success code
|
||||
resp = await client.request("https://google.com/")
|
||||
@@ -115,9 +115,9 @@ proc syncTest() =
|
||||
doAssert("<title>Example Domain</title>" in resp.body)
|
||||
|
||||
resp = client.request("http://example.com/404")
|
||||
doAssert(resp.code.is4xx)
|
||||
doAssert(resp.code == Http404)
|
||||
doAssert(resp.status == $Http404)
|
||||
doAssert(resp.code.is4xx or resp.code.is5xx)
|
||||
doAssert(resp.code == Http404 or resp.code == Http500)
|
||||
doAssert(resp.status == $Http404 or resp.status == $Http500)
|
||||
|
||||
when false: # occasionally does not give success code
|
||||
resp = client.request("https://google.com/")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
matrix: "--mm:refc; --backend:cpp --mm:refc; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
|
||||
matrix: "; --backend:cpp; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
|
||||
"""
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ for i in 0 .. 10000:
|
||||
except:
|
||||
discard
|
||||
# memory diff should less than 4M
|
||||
doAssert(abs(getOccupiedMem() - startMemory) < 4 * 1024 * 1024) # todo fixme doesn;t work for ORC
|
||||
doAssert(abs(getOccupiedMem() - startMemory) < 4 * 1024 * 1024)
|
||||
|
||||
|
||||
# test `$`
|
||||
|
||||
@@ -19,5 +19,10 @@ template main() =
|
||||
# see also `runnableExamples`.
|
||||
# xxx we should have a way to avoid duplicating code between runnableExamples and tests
|
||||
|
||||
doAssert m.getMimetype("nim") == "text/nim"
|
||||
doAssert m.getMimetype("nimble") == "text/nimble"
|
||||
doAssert m.getMimetype("nimf") == "text/nim"
|
||||
doAssert m.getMimetype("nims") == "text/nim"
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
@@ -99,3 +99,14 @@ block: # With this included, static: test() crashes the compiler (from a
|
||||
checkParseSize " 12" , 0, 1 # Leading white
|
||||
# Value Edge cases
|
||||
checkParseSize "9223372036854775807", 19, int64.high
|
||||
|
||||
block: # bug #23936
|
||||
func parsePyFloat(
|
||||
a: openArray[char], # here must be openArray instead of string to reproduce this bug
|
||||
res: var BiggestFloat): int =
|
||||
result = parseFloat(a, res)
|
||||
|
||||
static:
|
||||
var f = 0.0
|
||||
doAssert "1.0".parsePyFloat(f) == 3
|
||||
doAssert f == 1.0
|
||||
|
||||
@@ -6,15 +6,12 @@ import std/paths
|
||||
import std/assertions
|
||||
import pathnorm
|
||||
from std/private/ospaths2 {.all.} import joinPathImpl
|
||||
import std/sugar
|
||||
import std/[sugar, sets]
|
||||
|
||||
|
||||
proc normalizePath*(path: Path; dirSep = DirSep): Path =
|
||||
result = Path(pathnorm.normalizePath(path.string, dirSep))
|
||||
|
||||
func `==`(x, y: Path): bool =
|
||||
x.string == y.string
|
||||
|
||||
func joinPath*(parts: varargs[Path]): Path =
|
||||
var estimatedLen = 0
|
||||
var state = 0
|
||||
@@ -231,4 +228,11 @@ block ospaths:
|
||||
when doslikeFileSystem:
|
||||
doAssert joinPath(Path"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools\\", Path"..\\..\\VC\\vcvarsall.bat") == r"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat".Path
|
||||
doAssert joinPath(Path"C:\\foo", Path"..\\a") == r"C:\a".Path
|
||||
doAssert joinPath(Path"C:\\foo\\", Path"..\\a") == r"C:\a".Path
|
||||
doAssert joinPath(Path"C:\\foo\\", Path"..\\a") == r"C:\a".Path
|
||||
|
||||
|
||||
block: # bug #23663
|
||||
var s: HashSet[Path]
|
||||
s.incl("/a/b/c/..".Path)
|
||||
doAssert "/a/b/".Path in s
|
||||
doAssert "/a/b/c".Path notin s
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
discard """
|
||||
joinable: false # to avoid messing with global rand state
|
||||
matrix: "--mm:refc; --mm:orc; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
|
||||
matrix: "--mm:refc; --mm:orc; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
|
||||
"""
|
||||
import std/[assertions, formatfloat]
|
||||
import std/[random, math, stats, sets, tables]
|
||||
@@ -297,6 +297,9 @@ block: # bug #22360
|
||||
inc fc
|
||||
|
||||
when defined(js):
|
||||
doAssert (tc, fc) == (483, 517), $(tc, fc)
|
||||
when compileOption("jsbigint64"):
|
||||
doAssert (tc, fc) == (517, 483), $(tc, fc)
|
||||
else:
|
||||
doAssert (tc, fc) == (515, 485), $(tc, fc)
|
||||
else:
|
||||
doAssert (tc, fc) == (510, 490), $(tc, fc)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
|
||||
matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
|
||||
"""
|
||||
|
||||
import std/strutils
|
||||
@@ -527,9 +527,9 @@ template main() =
|
||||
|
||||
block: # toHex
|
||||
doAssert(toHex(100i16, 32) == "00000000000000000000000000000064")
|
||||
doAssert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C")
|
||||
whenJsNoBigInt64: discard
|
||||
do:
|
||||
doAssert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C")
|
||||
doAssert(toHex(high(uint64)) == "FFFFFFFFFFFFFFFF")
|
||||
doAssert(toHex(high(uint64), 16) == "FFFFFFFFFFFFFFFF")
|
||||
doAssert(toHex(high(uint64), 32) == "0000000000000000FFFFFFFFFFFFFFFF")
|
||||
|
||||
@@ -4,7 +4,7 @@ discard """
|
||||
"""
|
||||
|
||||
import stdtest/testutils
|
||||
import std/assertions
|
||||
import std/[assertions, formatfloat]
|
||||
|
||||
# TODO: in future work move existing `system` tests here, where they belong
|
||||
|
||||
@@ -83,24 +83,36 @@ block:
|
||||
X = object
|
||||
a: string
|
||||
b: set[char]
|
||||
c: int
|
||||
d: float
|
||||
e: int64
|
||||
|
||||
var y = X(b: {'a'})
|
||||
|
||||
var x = X(b: {'a'}, e: 10)
|
||||
|
||||
var y = move x
|
||||
|
||||
doAssert x.a == ""
|
||||
doAssert x.b == {}
|
||||
doAssert x.c == 0
|
||||
doAssert x.d == 0.0
|
||||
doAssert x.e == 0
|
||||
|
||||
reset(y)
|
||||
|
||||
doAssert y.a == ""
|
||||
doAssert y.b == {}
|
||||
doAssert y.c == 0
|
||||
doAssert y.d == 0.0
|
||||
doAssert y.e == 0
|
||||
|
||||
block:
|
||||
type
|
||||
X = object
|
||||
a: string
|
||||
b: int
|
||||
|
||||
var y = X(b: 1314)
|
||||
|
||||
reset(y)
|
||||
|
||||
doAssert y.b == 0
|
||||
var x = 2
|
||||
var y = move x
|
||||
doAssert y == 2
|
||||
doAssert x == 0
|
||||
reset y
|
||||
doAssert y == 0
|
||||
|
||||
block:
|
||||
type
|
||||
@@ -170,3 +182,19 @@ block: # bug #20516
|
||||
|
||||
when not defined(js):
|
||||
let a = create(Foo)
|
||||
|
||||
block: # bug #6549
|
||||
when not defined(js):
|
||||
block:
|
||||
const v = 18446744073709551615'u64
|
||||
|
||||
doAssert $v == "18446744073709551615"
|
||||
doAssert $float32(v) == "1.8446744e+19", $float32(v)
|
||||
doAssert $float64(v) == "1.8446744073709552e+19", $float64(v)
|
||||
|
||||
block:
|
||||
let v = 18446744073709551615'u64
|
||||
|
||||
doAssert $v == "18446744073709551615"
|
||||
doAssert $float32(v) == "1.8446744e+19"
|
||||
doAssert $float64(v) == "1.8446744073709552e+19"
|
||||
|
||||
@@ -523,3 +523,39 @@ block:
|
||||
doAssert resB == "abcdef"
|
||||
|
||||
testReturnValues()
|
||||
|
||||
|
||||
block: # bug #23635
|
||||
block:
|
||||
type
|
||||
Store = object
|
||||
run: proc (a: int) {.nimcall, gcsafe.}
|
||||
|
||||
block:
|
||||
var count = 0
|
||||
proc hello(a: int) =
|
||||
inc count, a
|
||||
|
||||
var store = Store()
|
||||
store.run = hello
|
||||
|
||||
let b = toTask store.run(13)
|
||||
b.invoke()
|
||||
doAssert count == 13
|
||||
|
||||
block:
|
||||
type
|
||||
Store = object
|
||||
run: proc () {.nimcall, gcsafe.}
|
||||
|
||||
block:
|
||||
var count = 0
|
||||
proc hello() =
|
||||
inc count, 1
|
||||
|
||||
var store = Store()
|
||||
store.run = hello
|
||||
|
||||
let b = toTask store.run()
|
||||
b.invoke()
|
||||
doAssert count == 1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
matrix: "--mm:refc; --mm:orc; --backend:js --jsbigint64:on; --backend:js --jsbigint64:off"
|
||||
matrix: "--mm:refc; --mm:orc; --backend:js --jsbigint64:on; --backend:js --jsbigint64:off -d:nimStringHash2"
|
||||
"""
|
||||
|
||||
import times, strutils, unittest
|
||||
@@ -71,7 +71,7 @@ template runTimezoneTests() =
|
||||
"2006-01-12T22:04:05Z", 11)
|
||||
# RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
|
||||
parseTest("2006-01-12T15:04:05.999999999Z-07:00",
|
||||
"yyyy-MM-dd'T'HH:mm:ss'.999999999Z'zzz", "2006-01-12T22:04:05Z", 11)
|
||||
"yyyy-MM-dd'T'HH:mm:ss.'999999999Z'zzz", "2006-01-12T22:04:05Z", 11)
|
||||
for tzFormat in ["z", "zz", "zzz"]:
|
||||
# formatting timezone as 'Z' for UTC
|
||||
parseTest("2001-01-12T22:04:05Z", "yyyy-MM-dd'T'HH:mm:ss" & tzFormat,
|
||||
@@ -770,3 +770,15 @@ block: # ttimes
|
||||
proc test(): DateTime {.gcsafe.} =
|
||||
result = "1970".parse("yyyy")
|
||||
doAssert test().year == 1970
|
||||
|
||||
block: # test FormatLiterals
|
||||
# since #23861
|
||||
block:
|
||||
let dt = dateTime(2024, mJul, 21, 17, 01, 02, 123_321_123, utc())
|
||||
check dt.format("ss.fff") == "02.123"
|
||||
check dt.format("fff.ffffff") == "123.123321"
|
||||
block:
|
||||
let dt = parse("2024.07.21", "yyyy.MM.dd")
|
||||
check dt.year == 2024
|
||||
check dt.month == mJul
|
||||
check dt.monthday == 21
|
||||
|
||||
@@ -74,3 +74,20 @@ block:
|
||||
|
||||
doAssert getEnumOrdinal(y, "Hello") == 0
|
||||
doAssert getEnumOrdinal(y, "hello") == 1
|
||||
|
||||
block: # bug #23556
|
||||
proc test =
|
||||
var
|
||||
t: seq[int]
|
||||
aseq = toAny(t)
|
||||
|
||||
invokeNewSeq(aseq, 0)
|
||||
|
||||
# Got random value only when loop 8 times.
|
||||
for i in 1 .. 8:
|
||||
extendSeq(aseq)
|
||||
|
||||
doAssert t == @[0, 0, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
for i in 1 .. 7:
|
||||
test()
|
||||
|
||||
@@ -57,6 +57,7 @@ doAssert isAlpha("r")
|
||||
doAssert isAlpha("α")
|
||||
doAssert isAlpha("ϙ")
|
||||
doAssert isAlpha("ஶ")
|
||||
doAssert isAlpha("网")
|
||||
doAssert(not isAlpha("$"))
|
||||
doAssert(not isAlpha(""))
|
||||
|
||||
@@ -66,6 +67,7 @@ doAssert isAlpha("𐌼𐌰𐌲𐌲𐌻𐌴𐍃𐍄𐌰𐌽")
|
||||
doAssert isAlpha("ὕαλονϕαγεῖνδύναμαιτοῦτοοὔμεβλάπτει")
|
||||
doAssert isAlpha("Јамогујестистаклоитоминештети")
|
||||
doAssert isAlpha("Կրնամապակիուտեևինծիանհանգիստչըներ")
|
||||
doAssert isAlpha("编程语言")
|
||||
doAssert(not isAlpha("$Foo✓"))
|
||||
doAssert(not isAlpha("⠙⠕⠑⠎⠝⠞"))
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ block:
|
||||
doAssert cast[float64](got) == test
|
||||
|
||||
block:
|
||||
var hugeIntArray: array[50, byte]
|
||||
var hugeIntArray: array[9, byte]
|
||||
var readedInt: uint64
|
||||
|
||||
template chk(a) =
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
|
||||
matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
|
||||
"""
|
||||
|
||||
#[
|
||||
@@ -109,10 +109,10 @@ block:
|
||||
# if `uint8(a1)` changes meaning to `cast[uint8](a1)` in future, update this test;
|
||||
# until then, this is the correct semantics.
|
||||
let a3 = $a2
|
||||
doAssert a2 < 3
|
||||
doAssert a3 == "-1"
|
||||
doAssert a2 == 255'u8
|
||||
doAssert a3 == "255"
|
||||
proc intToStr(a: uint8): cstring {.importjs: "(# + \"\")".}
|
||||
doAssert $intToStr(a2) == "-1"
|
||||
doAssert $intToStr(a2) == "255"
|
||||
else:
|
||||
block:
|
||||
let x = -1'i8
|
||||
|
||||
@@ -219,3 +219,9 @@ proc bug23223 = # bug #23223
|
||||
doAssert stuff == "hello"
|
||||
|
||||
bug23223()
|
||||
|
||||
block: # bug #23894
|
||||
let v = high(uint) div 2
|
||||
let s = v + 1 # 9223372036854775808
|
||||
let m = succ v
|
||||
doAssert s == m
|
||||
|
||||
87
tests/template/t13426.nim
Normal file
87
tests/template/t13426.nim
Normal file
@@ -0,0 +1,87 @@
|
||||
discard """
|
||||
cmd: "nim check --hints:off $file"
|
||||
errormsg: ""
|
||||
nimout: '''
|
||||
t13426.nim(81, 6) template/generic instantiation of `fun` from here
|
||||
t13426.nim(80, 24) Error: type mismatch: got <int> but expected 'string'
|
||||
t13426.nim(81, 6) template/generic instantiation of `fun` from here
|
||||
t13426.nim(80, 17) Error: type mismatch: got <uint, string>
|
||||
but expected one of:
|
||||
proc `and`(x, y: uint): uint
|
||||
first type mismatch at position: 2
|
||||
required type for y: uint
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: uint64): uint64
|
||||
first type mismatch at position: 2
|
||||
required type for y: uint64
|
||||
but expression 'high(@[1])' is of type: string
|
||||
10 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them
|
||||
|
||||
expression: 1'u and high(@[1])
|
||||
t13426.nim(81, 6) template/generic instantiation of `fun` from here
|
||||
t13426.nim(80, 17) Error: expression '' has no type (or is ambiguous)
|
||||
t13426.nim(87, 6) template/generic instantiation of `fun` from here
|
||||
t13426.nim(86, 22) Error: type mismatch: got <int> but expected 'string'
|
||||
t13426.nim(87, 6) template/generic instantiation of `fun` from here
|
||||
t13426.nim(86, 15) Error: type mismatch: got <int literal(1), string>
|
||||
but expected one of:
|
||||
proc `and`(x, y: int): int
|
||||
first type mismatch at position: 2
|
||||
required type for y: int
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: int16): int16
|
||||
first type mismatch at position: 2
|
||||
required type for y: int16
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: int32): int32
|
||||
first type mismatch at position: 2
|
||||
required type for y: int32
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: int64): int64
|
||||
first type mismatch at position: 2
|
||||
required type for y: int64
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: int8): int8
|
||||
first type mismatch at position: 2
|
||||
required type for y: int8
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: uint): uint
|
||||
first type mismatch at position: 2
|
||||
required type for y: uint
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: uint16): uint16
|
||||
first type mismatch at position: 2
|
||||
required type for y: uint16
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: uint32): uint32
|
||||
first type mismatch at position: 2
|
||||
required type for y: uint32
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: uint64): uint64
|
||||
first type mismatch at position: 2
|
||||
required type for y: uint64
|
||||
but expression 'high(@[1])' is of type: string
|
||||
proc `and`(x, y: uint8): uint8
|
||||
first type mismatch at position: 2
|
||||
required type for y: uint8
|
||||
but expression 'high(@[1])' is of type: string
|
||||
2 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them
|
||||
|
||||
expression: 1 and high(@[1])
|
||||
t13426.nim(87, 6) template/generic instantiation of `fun` from here
|
||||
t13426.nim(86, 15) Error: expression '' has no type (or is ambiguous)
|
||||
'''
|
||||
"""
|
||||
|
||||
# bug # #13426
|
||||
block:
|
||||
template bar(t): string = high(t)
|
||||
proc fun[A](key: A) =
|
||||
var h = 1'u and bar(@[1])
|
||||
fun(0)
|
||||
|
||||
block:
|
||||
template bar(t): string = high(t)
|
||||
proc fun[A](key: A) =
|
||||
var h = 1 and bar(@[1])
|
||||
fun(0)
|
||||
@@ -6,3 +6,15 @@ block: # #20002
|
||||
discard 3.bar # evaluates to 10 but only check if it compiles for now
|
||||
block:
|
||||
foo()
|
||||
|
||||
block: # issue #23813
|
||||
template r(body: untyped) =
|
||||
proc x() {.gensym.} =
|
||||
body
|
||||
template g() =
|
||||
r:
|
||||
let y = 0
|
||||
r:
|
||||
proc y() = discard
|
||||
y()
|
||||
g()
|
||||
|
||||
51
tests/threads/tmembug.nim
Normal file
51
tests/threads/tmembug.nim
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
import std / [atomics, strutils, sequtils]
|
||||
|
||||
type
|
||||
BackendMessage* = object
|
||||
field*: seq[int]
|
||||
|
||||
var
|
||||
chan1: Channel[BackendMessage]
|
||||
chan2: Channel[BackendMessage]
|
||||
|
||||
chan1.open()
|
||||
chan2.open()
|
||||
|
||||
proc routeMessage*(msg: BackendMessage) =
|
||||
discard chan2.trySend(msg)
|
||||
|
||||
var
|
||||
recv: Thread[void]
|
||||
stopToken: Atomic[bool]
|
||||
|
||||
proc recvMsg() =
|
||||
while not stopToken.load(moRelaxed):
|
||||
let resp = chan1.tryRecv()
|
||||
if resp.dataAvailable:
|
||||
routeMessage(resp.msg)
|
||||
echo "child consumes ", formatSize getOccupiedMem()
|
||||
|
||||
createThread[void](recv, recvMsg)
|
||||
|
||||
const MESSAGE_COUNT = 100
|
||||
|
||||
proc main() =
|
||||
let msg: BackendMessage = BackendMessage(field: (0..500).toSeq())
|
||||
for j in 0..0: #100:
|
||||
echo "New iteration"
|
||||
|
||||
for _ in 1..MESSAGE_COUNT:
|
||||
chan1.send(msg)
|
||||
echo "After sending"
|
||||
|
||||
var counter = 0
|
||||
while counter < MESSAGE_COUNT:
|
||||
let resp = recv(chan2)
|
||||
counter.inc
|
||||
echo "After receiving ", formatSize getOccupiedMem()
|
||||
|
||||
stopToken.store true, moRelaxed
|
||||
joinThreads(recv)
|
||||
|
||||
main()
|
||||
2
tests/typerel/tuncheckedarray_eq.nim
Normal file
2
tests/typerel/tuncheckedarray_eq.nim
Normal file
@@ -0,0 +1,2 @@
|
||||
type p = ptr UncheckedArray[char]
|
||||
doAssert p is ptr UncheckedArray
|
||||
@@ -124,3 +124,13 @@ proc bug22597 = # bug #22597
|
||||
doAssert i == 1
|
||||
|
||||
bug22597()
|
||||
|
||||
block: # bug #20048
|
||||
type
|
||||
Test = object
|
||||
tokens: openArray[string]
|
||||
|
||||
func init(Self: typedesc[Test], tokens: openArray[string]): Self = Self(tokens: tokens)
|
||||
|
||||
let data = Test.init(["123"])
|
||||
doAssert @(data.tokens) == @["123"]
|
||||
|
||||
90
tests/views/tviews2.nim
Normal file
90
tests/views/tviews2.nim
Normal file
@@ -0,0 +1,90 @@
|
||||
discard """
|
||||
targets: "c js"
|
||||
"""
|
||||
|
||||
{.experimental: "views".}
|
||||
|
||||
block:
|
||||
type
|
||||
Foo = object
|
||||
id: openArray[char]
|
||||
|
||||
proc foo(): Foo =
|
||||
var source = "1245"
|
||||
result = Foo(id: source.toOpenArray(0, 1))
|
||||
|
||||
doAssert foo().id == @['1', '2']
|
||||
|
||||
block: # bug #15778
|
||||
type
|
||||
Reader = object
|
||||
data: openArray[char]
|
||||
current: int
|
||||
|
||||
var count = 0
|
||||
|
||||
proc read(data: var Reader, length: int): openArray[char] =
|
||||
inc count
|
||||
let start = data.current
|
||||
data.current.inc length
|
||||
return data.data.toOpenArray(start, data.current-1)
|
||||
|
||||
var data = "hello there"
|
||||
var reader = Reader(data: data.toOpenArray(0, data.len-1), current: 0)
|
||||
doAssert @(reader.read(2)) == @['h', 'e']
|
||||
doAssert @(reader.read(3)) == @['l', 'l', 'o']
|
||||
doAssert count == 2
|
||||
|
||||
block: # bug #16671
|
||||
block:
|
||||
type X = ref object of RootObj
|
||||
type Y = ref object of X
|
||||
field: openArray[int]
|
||||
|
||||
var s: seq[X]
|
||||
proc f() =
|
||||
s.add(Y(field: [1]))
|
||||
|
||||
f()
|
||||
|
||||
block:
|
||||
type X = ref object of RootObj
|
||||
type Y = ref object of X
|
||||
field: openArray[int]
|
||||
|
||||
var s: seq[X]
|
||||
proc f() =
|
||||
s.add(Y(field: toOpenArray([1, 2, 3], 0, 1)))
|
||||
|
||||
f()
|
||||
|
||||
block: # bug #15746
|
||||
type
|
||||
Reader = object
|
||||
data: openArray[char]
|
||||
current: int
|
||||
|
||||
proc initReader(data: openArray[char], offset = 0): Reader =
|
||||
result = Reader(data: data, current: offset)
|
||||
|
||||
let s = "\x01\x00\x00\x00"
|
||||
doAssert initReader(s).data[0].int == 1
|
||||
|
||||
block:
|
||||
proc foo(x: openArray[char]) =
|
||||
discard x
|
||||
|
||||
foo("12254")
|
||||
foo(@['a', 'b'])
|
||||
|
||||
var a1 = "12254"
|
||||
foo(a1)
|
||||
|
||||
var a2 = @['a', 'b']
|
||||
foo(a2)
|
||||
|
||||
var s = "138443"
|
||||
var ooo: openArray[char] = s
|
||||
var xxx: openArray[char] = ooo
|
||||
foo(ooo)
|
||||
foo(xxx)
|
||||
@@ -17,3 +17,18 @@ x = "ah"
|
||||
echo foo[x]
|
||||
x = "possible."
|
||||
echo foo[x]
|
||||
|
||||
block: # bug #19840
|
||||
const testBytes = [byte 0xD8, 0x08, 0xDF, 0x45, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x61]
|
||||
var tempStr = "__________________"
|
||||
|
||||
tempStr.prepareMutation
|
||||
copyMem(addr tempStr[0], addr testBytes[0], testBytes.len)
|
||||
|
||||
block: # bug #22389
|
||||
func foo(): ptr UncheckedArray[byte] =
|
||||
const bar = [77.byte]
|
||||
cast[ptr UncheckedArray[byte]](addr bar[0])
|
||||
|
||||
doAssert foo()[0] == 77
|
||||
|
||||
|
||||
@@ -67,3 +67,23 @@ template fn=
|
||||
doAssert test([0,1,2,3,4,5]).id == 0
|
||||
fn() # ok
|
||||
static: fn()
|
||||
|
||||
|
||||
block: # bug #22095
|
||||
type
|
||||
StUint = object
|
||||
limbs: array[4, uint64]
|
||||
|
||||
func shlAddMod(a: var openArray[uint64]) =
|
||||
a[0] = 10
|
||||
|
||||
func divRem(r: var openArray[uint64]) =
|
||||
shlAddMod(r.toOpenArray(0, 3))
|
||||
|
||||
func fn(): StUint =
|
||||
divRem(result.limbs)
|
||||
|
||||
const
|
||||
z = fn()
|
||||
|
||||
doAssert z.limbs[0] == 10
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user