Merge branch 'devel' of github.com:nim-lang/Nim into devel

This commit is contained in:
Araq
2017-05-16 20:51:50 +02:00
19 changed files with 679 additions and 71 deletions

View File

@@ -175,7 +175,12 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
result.add mapTypeToAst(t.sons[i], info)
else:
result = mapTypeToAstX(t.lastSon, info, inst, allowRecursion)
of tyGenericBody, tyOrdinal:
of tyGenericBody:
if inst:
result = mapTypeToAstX(t.lastSon, info, inst, true)
else:
result = mapTypeToAst(t.lastSon, info)
of tyOrdinal:
result = mapTypeToAst(t.lastSon, info)
of tyDistinct:
if inst:

View File

@@ -79,6 +79,9 @@ const
DT_SOCK* = 12 ## UNIX domain socket.
DT_WHT* = 14
# Special types
type Sighandler = proc (a: cint) {.noconv.}
# Platform specific stuff
when defined(linux) and defined(amd64):
@@ -86,6 +89,9 @@ when defined(linux) and defined(amd64):
else:
include posix_other
# There used to be this name in posix.nim a long time ago, not sure why!
{.deprecated: [cSIG_HOLD: SIG_HOLD].}
when not defined(macosx):
proc st_atime*(s: Stat): Time {.inline.} =
## Second-granularity time of last access
@@ -659,7 +665,7 @@ proc sighold*(a1: cint): cint {.importc, header: "<signal.h>".}
proc sigignore*(a1: cint): cint {.importc, header: "<signal.h>".}
proc siginterrupt*(a1, a2: cint): cint {.importc, header: "<signal.h>".}
proc sigismember*(a1: var Sigset, a2: cint): cint {.importc, header: "<signal.h>".}
proc signal*(a1: cint, a2: proc (x: cint) {.noconv.}) {.
proc signal*(a1: cint, a2: Sighandler) {.
importc, header: "<signal.h>".}
proc sigpause*(a1: cint): cint {.importc, header: "<signal.h>".}
proc sigpending*(a1: var Sigset): cint {.importc, header: "<signal.h>".}

View File

@@ -36,6 +36,9 @@ type
{.deprecated: [TSocketHandle: SocketHandle].}
# not detected by detect.nim, guarded by #ifdef __USE_UNIX98 in glibc
const SIG_HOLD* = cast[SigHandler](2)
type
Timespec* {.importc: "struct timespec",
header: "<time.h>", final, pure.} = object ## struct timespec

View File

@@ -399,6 +399,9 @@ const SS_ONSTACK* = cint(1)
const SS_DISABLE* = cint(2)
const MINSIGSTKSZ* = cint(2048)
const SIGSTKSZ* = cint(8192)
const SIG_DFL* = cast[Sighandler](0)
const SIG_ERR* = cast[Sighandler](-1)
const SIG_IGN* = cast[Sighandler](1)
# <sys/ipc.h>
const IPC_CREAT* = cint(512)

View File

@@ -414,6 +414,10 @@ var SS_ONSTACK* {.importc: "SS_ONSTACK", header: "<signal.h>".}: cint
var SS_DISABLE* {.importc: "SS_DISABLE", header: "<signal.h>".}: cint
var MINSIGSTKSZ* {.importc: "MINSIGSTKSZ", header: "<signal.h>".}: cint
var SIGSTKSZ* {.importc: "SIGSTKSZ", header: "<signal.h>".}: cint
var SIG_HOLD* {.importc: "SIG_HOLD", header: "<signal.h>".}: Sighandler
var SIG_DFL* {.importc: "SIG_DFL", header: "<signal.h>".}: Sighandler
var SIG_ERR* {.importc: "SIG_ERR", header: "<signal.h>".}: Sighandler
var SIG_IGN* {.importc: "SIG_IGN", header: "<signal.h>".}: Sighandler
# <sys/ipc.h>
var IPC_CREAT* {.importc: "IPC_CREAT", header: "<sys/ipc.h>".}: cint

View File

@@ -9,7 +9,7 @@
include "system/inclrtl"
import os, oids, tables, strutils, times, heapqueue, options
import os, tables, strutils, times, heapqueue, options
import nativesockets, net, deques
@@ -163,8 +163,8 @@ include includes/asyncfutures
type
PDispatcherBase = ref object of RootRef
timers: HeapQueue[tuple[finishAt: float, fut: Future[void]]]
callbacks: Deque[proc ()]
timers*: HeapQueue[tuple[finishAt: float, fut: Future[void]]]
callbacks*: Deque[proc ()]
proc processTimers(p: PDispatcherBase) {.inline.} =
#Process just part if timers at a step

View File

@@ -339,13 +339,17 @@ proc writeBuffer*(f: AsyncFile, buf: pointer, size: int): Future[void] =
if not retFuture.finished:
if errcode == OSErrorCode(-1):
assert bytesCount == size.int32
f.offset.inc(size)
retFuture.complete()
else:
retFuture.fail(newException(OSError, osErrorMsg(errcode)))
)
# passing -1 here should work according to MSDN, but doesn't. For more
# information see
# http://stackoverflow.com/questions/33650899/does-asynchronous-file-
# appending-in-windows-preserve-order
ol.offset = DWord(f.offset and 0xffffffff)
ol.offsetHigh = DWord(f.offset shr 32)
f.offset.inc(size)
# According to MSDN we're supposed to pass nil to lpNumberOfBytesWritten.
let ret = writeFile(f.fd.Handle, buf, size.int32, nil,
@@ -364,7 +368,6 @@ proc writeBuffer*(f: AsyncFile, buf: pointer, size: int): Future[void] =
retFuture.fail(newException(OSError, osErrorMsg(osLastError())))
else:
assert bytesWritten == size.int32
f.offset.inc(size)
retFuture.complete()
else:
var written = 0
@@ -410,7 +413,6 @@ proc write*(f: AsyncFile, data: string): Future[void] =
if not retFuture.finished:
if errcode == OSErrorCode(-1):
assert bytesCount == data.len.int32
f.offset.inc(data.len)
retFuture.complete()
else:
retFuture.fail(newException(OSError, osErrorMsg(errcode)))
@@ -420,6 +422,7 @@ proc write*(f: AsyncFile, data: string): Future[void] =
)
ol.offset = DWord(f.offset and 0xffffffff)
ol.offsetHigh = DWord(f.offset shr 32)
f.offset.inc(data.len)
# According to MSDN we're supposed to pass nil to lpNumberOfBytesWritten.
let ret = writeFile(f.fd.Handle, buffer, data.len.int32, nil,
@@ -441,7 +444,6 @@ proc write*(f: AsyncFile, data: string): Future[void] =
retFuture.fail(newException(OSError, osErrorMsg(osLastError())))
else:
assert bytesWritten == data.len.int32
f.offset.inc(data.len)
retFuture.complete()
else:
var written = 0

View File

@@ -516,7 +516,16 @@ when declared(getEnv) or defined(nimscript):
proc getConfigDir*(): string {.rtl, extern: "nos$1",
tags: [ReadEnvEffect, ReadIOEffect].} =
## Returns the config directory of the current user for applications.
##
## On non-Windows OSs, this proc conforms to the XDG Base Directory
## spec. Thus, this proc returns the value of the XDG_CONFIG_DIR environment
## variable if it is set, and returns the default configuration directory,
## "~/.config/", otherwise.
##
## An OS-dependent trailing slash is always present at the end of the
## returned string; `\\` on Windows and `/` on all other OSs.
when defined(windows): return string(getEnv("APPDATA")) & "\\"
elif getEnv("XDG_CONFIG_DIR"): return string(getEnv("XDG_CONFIG_DIR")) & "/"
else: return string(getEnv("HOME")) & "/.config/"
proc getTempDir*(): string {.rtl, extern: "nos$1",

View File

@@ -540,7 +540,8 @@ proc writeConfig*(dict: Config, filename: string) =
## Writes the contents of the table to the specified configuration file.
## Note: Comment statement will be ignored.
let file = open(filename, fmWrite)
let fileStream = newFileStream(filename)
defer: file.close()
let fileStream = newFileStream(file)
defer: fileStream.close()
dict.writeConfig(fileStream)

View File

@@ -282,8 +282,13 @@ proc raiseExceptionAux(e: ref Exception) =
proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
if e.name.isNil: e.name = ename
when hasSomeStackTrace:
e.trace = ""
rawWriteStackTrace(e.trace)
if e.trace.isNil:
e.trace = ""
rawWriteStackTrace(e.trace)
elif framePtr != nil:
e.trace.add "[[reraised from:\n"
auxWriteStackTrace(framePtr, e.trace)
e.trace.add "]]\n"
raiseExceptionAux(e)
proc reraiseException() {.compilerRtl.} =

View File

@@ -9,7 +9,7 @@
include "system/inclrtl"
import os, oids, tables, strutils, times, heapqueue, lists, options
import os, tables, strutils, times, heapqueue, lists, options
import nativesockets, net, deques

View File

@@ -2,19 +2,19 @@ discard """
file: "tasyncall.nim"
exitcode: 0
"""
import times, sequtils
import times, sequtils, unittest
import asyncdispatch
const
taskCount = 10
sleepDuration = 500
sleepDuration = 50
proc futureWithValue(x: int): Future[int] {.async.} =
await sleepAsync(sleepDuration)
return x
proc futureWithoutValue() {.async.} =
await sleepAsync(1000)
await sleepAsync(sleepDuration)
proc testFuturesWithValue(x: int): seq[int] =
var tasks = newSeq[Future[int]](taskCount)
@@ -40,38 +40,39 @@ proc testVarargs(x, y, z: int): seq[int] =
result = waitFor all(a, b, c)
block:
let
startTime = cpuTime()
results = testFuturesWithValue(42)
expected = repeat(42, taskCount)
execTime = cpuTime() - startTime
suite "tasyncall":
test "testFuturesWithValue":
let
startTime = cpuTime()
results = testFuturesWithValue(42)
expected = repeat(42, taskCount)
execTime = cpuTime() - startTime
doAssert execTime * 1000 < taskCount * sleepDuration
doAssert results == expected
doAssert execTime * 1000 < taskCount * sleepDuration
doAssert results == expected
block:
let startTime = cpuTime()
testFuturesWithoutValues()
let execTime = cpuTime() - startTime
test "testFuturesWithoutValues":
let startTime = cpuTime()
testFuturesWithoutValues()
let execTime = cpuTime() - startTime
doAssert execTime * 1000 < taskCount * sleepDuration
doAssert execTime * 1000 < taskCount * sleepDuration
block:
let
startTime = cpuTime()
results = testVarargs(1, 2, 3)
expected = @[1, 2, 3]
execTime = cpuTime() - startTime
test "testVarargs":
let
startTime = cpuTime()
results = testVarargs(1, 2, 3)
expected = @[1, 2, 3]
execTime = cpuTime() - startTime
doAssert execTime * 100 < taskCount * sleepDuration
doAssert results == expected
doAssert execTime * 100 < taskCount * sleepDuration
doAssert results == expected
block:
let
noIntFuturesFut = all(newSeq[Future[int]]())
noVoidFuturesFut = all(newSeq[Future[void]]())
test "all on seq[Future]":
let
noIntFuturesFut = all(newSeq[Future[int]]())
noVoidFuturesFut = all(newSeq[Future[void]]())
doAssert noIntFuturesFut.finished and not noIntFuturesFut.failed
doAssert noVoidFuturesFut.finished and not noVoidFuturesFut.failed
doAssert noIntFuturesFut.read() == @[]
doAssert noIntFuturesFut.finished and not noIntFuturesFut.failed
doAssert noVoidFuturesFut.finished and not noVoidFuturesFut.failed
doAssert noIntFuturesFut.read() == @[]

View File

@@ -0,0 +1,17 @@
discard """
output: '''string 1
string 2
string 3'''
"""
# bug #5532
import os, asyncfile, asyncdispatch
removeFile("test.txt")
let f = openAsync("test.txt", fmWrite)
var futs = newSeq[Future[void]]()
for i in 1..3:
futs.add(f.write("string " & $i & "\n"))
waitFor(all(futs))
f.close()
echo readFile("test.txt")

View File

@@ -21,49 +21,67 @@ proc symToIdent(x: NimNode): NimNode =
for c in x:
result.add symToIdent(c)
# check getTypeInst and getTypeImpl for given symbol x
macro testX(x,inst0: typed; recurse: static[bool]; implX: stmt): typed =
# check that getTypeInst(x) equals inst0
let inst = x.getTypeInst
let impl = x.getTypeImpl
let inst0r = inst0.symToIdent.treeRepr
let instr = inst.symToIdent.treeRepr
#echo inst0r
let inst0r = inst0.symToIdent.treeRepr
#echo instr
#echo inst0r
doAssert(instr == inst0r)
# check that getTypeImpl(x) is correct
# if implX is nil then compare to inst0
# else we expect implX to be a type definition
# and we extract the implementation from that
let impl = x.getTypeImpl
var impl0 =
if implX.kind == nnkNilLit: inst0
else: implX[0][2]
let impl0r = impl0.symToIdent.treerepr
let implr = impl.symToIdent.treerepr
#echo impl0r
let impl0r = impl0.symToIdent.treerepr
#echo implr
#echo impl0r
doAssert(implr == impl0r)
template echoString(s:string) = echo s.replace("\n","\n ")
result = newStmtList()
#template echoString(s: string) = echo s.replace("\n","\n ")
#result.add getAst(echoString(" " & inst0.repr))
#result.add getAst(echoString(" " & inst.repr))
#result.add getAst(echoString(" " & impl0.repr))
#result.add getAst(echoString(" " & impl.repr))
if recurse:
template testDecl(n, m :typed) =
# now test using a newly formed variable of type getTypeInst(x)
template testDecl(n,m: typed) =
testV(n, false):
type _ = m
result.add getAst(testDecl(inst.symToIdent, impl.symToIdent))
# test with a variable (instance) of type
template testV(inst, recurse, impl) =
block:
#echo "testV(" & astToStr(inst) & ", " & $recurse & "):" & astToStr(impl)
var x: inst
testX(x, inst, recurse, impl)
template testT(inst, recurse) =
block:
type myType = inst
testV(myType, recurse):
type _ = inst
# test with a newly created typedesc (myType)
# using the passed type as the implementation
template testT(impl, recurse) =
block:
type myType = impl
testV(myType, recurse):
type _ = impl
# test a built-in type whose instance is equal to the implementation
template test(inst) =
testT(inst, false)
testV(inst, true, nil)
template test(inst, impl) = testV(inst, true, impl)
# test a custom type with provided implementation
template test(inst, impl) =
testV(inst, true, impl)
type
Model = object of RootObj
@@ -87,9 +105,12 @@ type
value:T
Foo[N:static[int],T] = object
Bar[N:static[int],T] = object
#baz:Foo[N+1,GenericObject[T]]
#baz:Foo[N+1,GenericObject[T]] # currently fails
baz:Foo[N,GenericObject[T]]
Generic[T] = seq[int]
Concrete = Generic[int]
test(bool)
test(char)
test(int)
@@ -97,13 +118,17 @@ test(float)
test(ptr int)
test(ref int)
test(array[1..10,Bar[2,Foo[3,float]]])
test(array[MyEnum,Bar[2,Foo[3,float]]])
test(distinct Bar[2,Foo[3,float]])
test(tuple[a:int,b:Foo[-1,float]])
#test(MyEnum):
# type _ = enum
# valueA, valueB, valueC
test(set[MyEnum])
test(seq[int])
test(set[MyEnum])
test(proc (a: int, b: Foo[2,float]))
test(proc (a: int, b: Foo[2,float]): Bar[3,int])
test(MyEnum):
type _ = enum
valueA, valueB, valueC
test(Bar[2,Foo[3,float]]):
type _ = object
baz: Foo[2, GenericObject[Foo[3, float]]]
@@ -118,8 +143,12 @@ test(Tree):
value: int
left: ref Tree
right: ref Tree
test(proc (a: int, b: Foo[2,float]))
test(proc (a: int, b: Foo[2,float]): Bar[3,int])
test(Concrete):
type _ = Generic[int]
test(Generic[int]):
type _ = seq[int]
test(Generic[float]):
type _ = seq[int]
# bug #4862
static:

View File

@@ -0,0 +1,384 @@
## JSON tests based on https://github.com/nst/JSONTestSuite
import unittest,
json,
strutils
let parsing_testdata = {
"i_number_neg_int_huge_exp": """[-1e+9999]""",
"i_number_pos_double_huge_exp": """[1.5e+9999]""",
"i_object_key_lone_2nd_surrogate": """{"\uDFAA":0}""",
"i_string_1st_surrogate_but_2nd_missing": """["\uDADA"]""",
"i_string_1st_valid_surrogate_2nd_invalid": """["\uD888\u1234"]""",
"i_string_incomplete_surrogate_and_escape_valid": """["\uD800\n"]""",
"i_string_incomplete_surrogate_pair": """["\uDd1ea"]""",
"i_string_incomplete_surrogates_escape_valid": """["\uD800\uD800\n"]""",
"i_string_inverted_surrogates_U+1D11E": """["\uDd1e\uD834"]""",
"i_string_lone_second_surrogate": """["\uDFAA"]""",
"i_string_not_in_unicode_range": """["<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"]""",
"i_string_truncated-utf-8": """["<EFBFBD><EFBFBD>"]""",
"i_string_unicode_U+10FFFE_nonchar": """["\uDBFF\uDFFE"]""",
"i_string_unicode_U+1FFFE_nonchar": """["\uD83F\uDFFE"]""",
"i_string_unicode_U+FDD0_nonchar": """["\uFDD0"]""",
"i_string_unicode_U+FFFE_nonchar": """["\uFFFE"]""",
"i_string_UTF-16_invalid_lonely_surrogate": """["\ud800"]""",
"i_string_UTF-16_invalid_surrogate": """["\ud800abc"]""",
"i_string_UTF-8_invalid_sequence": """["日ш<EFBFBD>"]""",
"i_structure_500_nested_arrays": """[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]""",
"i_structure_UTF-8_BOM_empty_object": """{}""",
"n_array_1_true_without_comma": """[1 true]""",
"n_array_a_invalid_utf8": """[a<>]""",
"n_array_colon_instead_of_comma": """["": 1]""",
"n_array_comma_after_close": """[""],""",
"n_array_comma_and_number": """[,1]""",
"n_array_double_comma": """[1,,2]""",
"n_array_double_extra_comma": """["x",,]""",
"n_array_extra_close": """["x"]]""",
"n_array_extra_comma": """["",]""",
"n_array_incomplete_invalid_value": """[x""",
"n_array_incomplete": """["x"""",
"n_array_inner_array_no_comma": """[3[4]]""",
"n_array_invalid_utf8": """[<5B>]""",
"n_array_items_separated_by_semicolon": """[1:2]""",
"n_array_just_comma": """[,]""",
"n_array_just_minus": """[-]""",
"n_array_missing_value": """[ , ""]""",
"n_array_newlines_unclosed": """["a",""",
"n_array_newlines_unclosed": """4""",
"n_array_newlines_unclosed": """,1,""",
"n_array_number_and_comma": """[1,]""",
"n_array_number_and_several_commas": """[1,,]""",
"n_array_spaces_vertical_tab_formfeed": """[" a"\f]""",
"n_array_star_inside": """[*]""",
"n_array_unclosed": """[""""",
"n_array_unclosed_trailing_comma": """[1,""",
"n_array_unclosed_with_new_lines": """[1,""",
"n_array_unclosed_with_new_lines": """1""",
"n_array_unclosed_with_new_lines": """,1""",
"n_array_unclosed_with_object_inside": """[{}""",
"n_incomplete_false": """[fals]""",
"n_incomplete_null": """[nul]""",
"n_incomplete_true": """[tru]""",
"n_number_0.1.2": """[0.1.2]""",
"n_number_-01": """[-01]""",
"n_number_0.3e": """[0.3e]""",
"n_number_0.3e+": """[0.3e+]""",
"n_number_0_capital_E": """[0E]""",
"n_number_0_capital_E+": """[0E+]""",
"n_number_0.e1": """[0.e1]""",
"n_number_0e": """[0e]""",
"n_number_0e+": """[0e+]""",
"n_number_1_000": """[1 000.0]""",
"n_number_1.0e-": """[1.0e-]""",
"n_number_1.0e": """[1.0e]""",
"n_number_1.0e+": """[1.0e+]""",
"n_number_-1.0.": """[-1.0.]""",
"n_number_1eE2": """[1eE2]""",
"n_number_.-1": """[.-1]""",
"n_number_+1": """[+1]""",
"n_number_.2e-3": """[.2e-3]""",
"n_number_2.e-3": """[2.e-3]""",
"n_number_2.e+3": """[2.e+3]""",
"n_number_2.e3": """[2.e3]""",
"n_number_-2.": """[-2.]""",
"n_number_9.e+": """[9.e+]""",
"n_number_expression": """[1+2]""",
"n_number_hex_1_digit": """[0x1]""",
"n_number_hex_2_digits": """[0x42]""",
"n_number_infinity": """[Infinity]""",
"n_number_+Inf": """[+Inf]""",
"n_number_Inf": """[Inf]""",
"n_number_invalid+-": """[0e+-1]""",
"n_number_invalid-negative-real": """[-123.123foo]""",
"n_number_invalid-utf-8-in-bigger-int": """[123<32>]""",
"n_number_invalid-utf-8-in-exponent": """[1e1<65>]""",
"n_number_invalid-utf-8-in-int": """[0<>]""",
"n_number_++": """[++1234]""",
"n_number_minus_infinity": """[-Infinity]""",
"n_number_minus_sign_with_trailing_garbage": """[-foo]""",
"n_number_minus_space_1": """[- 1]""",
"n_number_-NaN": """[-NaN]""",
"n_number_NaN": """[NaN]""",
"n_number_neg_int_starting_with_zero": """[-012]""",
"n_number_neg_real_without_int_part": """[-.123]""",
"n_number_neg_with_garbage_at_end": """[-1x]""",
"n_number_real_garbage_after_e": """[1ea]""",
"n_number_real_with_invalid_utf8_after_e": """[1e<31>]""",
"n_number_real_without_fractional_part": """[1.]""",
"n_number_starting_with_dot": """[.123]""",
"n_number_then_00": """1\x00""",
"n_number_U+FF11_fullwidth_digit_one": """[]""",
"n_number_with_alpha_char": """[1.8011670033376514H-308]""",
"n_number_with_alpha": """[1.2a-3]""",
"n_number_with_leading_zero": """[012]""",
"n_object_bad_value": """["x", truth]""",
"n_object_bracket_key": """{[: "x"}""",
"n_object_comma_instead_of_colon": """{"x", null}""",
"n_object_double_colon": """{"x"::"b"}""",
"n_object_emoji": """{🇨🇭}""",
"n_object_garbage_at_end": """{"a":"a" 123}""",
"n_object_key_with_single_quotes": """{key: 'value'}""",
"n_object_missing_colon": """{"a" b}""",
"n_object_missing_key": """{:"b"}""",
"n_object_missing_semicolon": """{"a" "b"}""",
"n_object_missing_value": """{"a":""",
"n_object_no-colon": """{"a"""",
"n_object_non_string_key_but_huge_number_instead": """{9999E9999:1}""",
"n_object_non_string_key": """{1:1}""",
"n_object_pi_in_key_and_trailing_comma": """{"<EFBFBD>":"0",}""",
"n_object_repeated_null_null": """{null:null,null:null}""",
"n_object_several_trailing_commas": """{"id":0,,,,,}""",
"n_object_single_quote": """{'a':0}""",
"n_object_trailing_comma": """{"id":0,}""",
"n_object_trailing_comment": """{"a":"b"}/**/""",
"n_object_trailing_comment_open": """{"a":"b"}/**//""",
"n_object_trailing_comment_slash_open_incomplete": """{"a":"b"}/""",
"n_object_trailing_comment_slash_open": """{"a":"b"}//""",
"n_object_two_commas_in_a_row": """{"a":"b",,"c":"d"}""",
"n_object_unquoted_key": """{a: "b"}""",
"n_object_unterminated-value": """{"a":"a""",
"n_object_with_single_string": """{ "foo" : "bar", "a" }""",
"n_object_with_trailing_garbage": """{"a":"b"}#""",
"n_single_space": """ """,
"n_string_1_surrogate_then_escape": """["\uD800\"]""",
"n_string_1_surrogate_then_escape u1": """["\uD800\u1"]""",
"n_string_1_surrogate_then_escape u1x": """["\uD800\u1x"]""",
"n_string_1_surrogate_then_escape u": """["\uD800\u"]""",
"n_string_accentuated_char_no_quotes": """[é]""",
"n_string_backslash_00": """["\\x00"]""",
"n_string_escaped_backslash_bad": """["\\\"]""",
"n_string_escaped_ctrl_char_tab": """["\ "]""",
"n_string_escaped_emoji": """["\🌀"]""",
"n_string_escape_x": """["\x00"]""",
"n_string_incomplete_escaped_character": """["\u00A"]""",
"n_string_incomplete_escape": """["\"]""",
"n_string_incomplete_surrogate_escape_invalid": """["\uD800\uD800\x"]""",
"n_string_invalid_backslash_esc": """["\a"]""",
"n_string_invalid_unicode_escape": """["\uqqqq"]""",
"n_string_invalid_utf8_after_escape": """["\<EFBFBD>"]""",
"n_string_invalid-utf-8-in-escape": """["\u<EFBFBD>"]""",
"n_string_invalid_utf-8": """["<EFBFBD>"]""",
"n_string_iso_latin_1": """["<EFBFBD>"]""",
"n_string_leading_uescaped_thinspace": """[\u0020"asd"]""",
"n_string_lone_utf8_continuation_byte": """["<EFBFBD>"]""",
"n_string_no_quotes_with_bad_escape": """[\n]""",
"n_string_overlong_sequence_2_bytes": """["<EFBFBD><EFBFBD>"]""",
"n_string_overlong_sequence_6_bytes": """["<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"]""",
"n_string_overlong_sequence_6_bytes_null": """["<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"]""",
"n_string_single_doublequote": """"""",
"n_string_single_quote": """['single quote']""",
"n_string_single_string_no_double_quotes": """abc""",
"n_string_start_escape_unclosed": """["\""",
"n_string_unescaped_ctrl_char": """["a\x00a"]""",
"n_string_unescaped_newline": """["new
line"]""",
"n_string_unescaped_tab": """[" "]""",
"n_string_unicode_CapitalU": """"\UA66D"""",
"n_string_UTF-16_incomplete_surrogate": """["\uD834\uDd"]""",
"n_string_UTF8_surrogate_U+D800": """["<EFBFBD><EFBFBD><EFBFBD>"]""",
"n_string_with_trailing_garbage": """""x""",
"n_structure_array_trailing_garbage": """[1]x""",
"n_structure_array_with_extra_array_close": """[1]]""",
"n_structure_array_with_unclosed_string": """["asd]""",
"n_structure_ascii-unicode-identifier": """""",
"n_structure_capitalized_True": """[True]""",
"n_structure_close_unopened_array": """1]""",
"n_structure_comma_instead_of_closing_brace": """{"x": true,""",
"n_structure_double_array": """[][]""",
"n_structure_end_array": """]""",
"n_structure_incomplete_UTF8_BOM": """<EFBFBD><EFBFBD>{}""",
"n_structure_<.>": """<.>""",
"n_structure_lone-invalid-utf-8": """<EFBFBD>""",
"n_structure_lone-open-bracket": """[""",
"n_structure_null-byte-outside-string": """[\00]""",
"n_structure_<null>": """[<null>]""",
"n_structure_number_with_trailing_garbage": """2@""",
"n_structure_object_followed_by_closing_object": """{}}""",
"n_structure_object_unclosed_no_value": """{"":""",
"n_structure_object_with_comment": """{"a":/*comment*/"b"}""",
"n_structure_object_with_trailing_garbage": """{"a": true} "x"""",
"n_structure_open_array_apostrophe": """['""",
"n_structure_open_array_comma": """[,""",
"n_structure_open_array_open_object": """[{""",
"n_structure_open_array_open_string": """["a""",
"n_structure_open_array_string": """["a"""",
"n_structure_open_object_close_array": """{]""",
"n_structure_open_object_comma": """{,""",
"n_structure_open_object": """{""",
"n_structure_open_object_open_array": """{[""",
"n_structure_open_object_open_string": """{"a""",
"n_structure_open_object_string_with_apostrophes": """{'a'""",
"n_structure_open_open": """["\{["\{["\{["\{""",
"n_structure_single_point": """<EFBFBD>""",
"n_structure_single_star": """*""",
"n_structure_trailing_#": """{"a":"b"}#{}""",
"n_structure_U+2060_word_joined": """[]""",
"n_structure_uescaped_LF_before_string": """[\u000A""]""",
"n_structure_unclosed_array": """[1""",
"n_structure_unclosed_array_partial_null": """[ false, nul""",
"n_structure_unclosed_array_unfinished_false": """[ true, fals""",
"n_structure_unclosed_array_unfinished_true": """[ false, tru""",
"n_structure_unclosed_object": """{"asd":"asd"""",
"n_structure_unicode-identifier": """å""",
"n_structure_UTF8_BOM_no_data": """""",
"n_structure_whitespace_formfeed": """[ ]""",
"n_structure_whitespace_U+2060_word_joiner": """[]""",
"y_array_arraysWithSpaces": """[[] ]""",
"y_array_empty": """[]""",
"y_array_empty-string": """[""]""",
"y_array_ending_with_newline": """["a"]""",
"y_array_false": """[false]""",
"y_array_heterogeneous": """[null, 1, "1", {}]""",
"y_array_null": """[null]""",
"y_array_with_1_and_newline": """[1
]""",
"y_array_with_leading_space": """ [1]""",
"y_array_with_several_null": """[1,null,null,null,2]""",
"y_array_with_trailing_space": """[2] """,
"y_number_0e+1": """[0e+1]""",
"y_number_0e1": """[0e1]""",
"y_number_after_space": """[ 4]""",
"y_number_double_close_to_zero": """[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]""",
"y_number_double_huge_neg_exp": """[123.456e-789]""",
"y_number_huge_exp": """[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]""",
"y_number_int_with_exp": """[20e1]""",
"y_number": """[123e65]""",
"y_number_minus_zero": """[-0]""",
"y_number_negative_int": """[-123]""",
"y_number_negative_one": """[-1]""",
"y_number_negative_zero": """[-0]""",
"y_number_real_capital_e": """[1E22]""",
"y_number_real_capital_e_neg_exp": """[1E-2]""",
"y_number_real_capital_e_pos_exp": """[1E+2]""",
"y_number_real_exponent": """[123e45]""",
"y_number_real_fraction_exponent": """[123.456e78]""",
"y_number_real_neg_exp": """[1e-2]""",
"y_number_real_neg_overflow": """[-123123e100000]""",
"y_number_real_pos_exponent": """[1e+2]""",
"y_number_real_pos_overflow": """[123123e100000]""",
"y_number_real_underflow": """[123e-10000000]""",
"y_number_simple_int": """[123]""",
"y_number_simple_real": """[123.456789]""",
"y_number_too_big_neg_int": """[-123123123123123123123123123123]""",
"y_number_too_big_pos_int": """[100000000000000000000]""",
"y_number_very_big_negative_int": """[-237462374673276894279832749832423479823246327846]""",
"y_object_basic": """{"asd":"sdf"}""",
"y_object_duplicated_key_and_value": """{"a":"b","a":"b"}""",
"y_object_duplicated_key": """{"a":"b","a":"c"}""",
"y_object_empty": """{}""",
"y_object_empty_key": """{"":0}""",
"y_object_escaped_null_in_key": """{"foo\u0000bar": 42}""",
"y_object_extreme_numbers": """{ "min": -1.0e+28, "max": 1.0e+28 }""",
"y_object": """{"asd":"sdf", "dfg":"fgh"}""",
"y_object_long_strings": """{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}""",
"y_object_simple": """{"a":[]}""",
"y_object_string_unicode": """{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" }""",
"y_object_with_newlines": """{
"a": "b"
}""",
"y_string_1_2_3_bytes_UTF-8_sequences": """["\u0060\u012a\u12AB"]""",
"y_string_accepted_surrogate_pair": """["\uD801\udc37"]""",
"y_string_accepted_surrogate_pairs": """["\ud83d\ude39\ud83d\udc8d"]""",
"y_string_allowed_escapes": """["\"\\\/\b\f\n\r\t"]""",
"y_string_backslash_and_u_escaped_zero": """["\\u0000"]""",
"y_string_backslash_doublequotes": """["\""]""",
"y_string_comments": """["a/*b*/c/*d//e"]""",
"y_string_double_escape_a": """["\\a"]""",
"y_string_double_escape_n": """["\\n"]""",
"y_string_escaped_control_character": """["\u0012"]""",
"y_string_escaped_noncharacter": """["\uFFFF"]""",
"y_string_in_array": """["asd"]""",
"y_string_in_array_with_leading_space": """[ "asd"]""",
"y_string_last_surrogates_1_and_2": """["\uDBFF\uDFFF"]""",
"y_string_newline_uescaped": """["new\u00A0line"]""",
"y_string_nonCharacterInUTF-8_U+10FFFF": """["􏿿"]""",
"y_string_nonCharacterInUTF-8_U+1FFFF": """["𛿿"]""",
"y_string_nonCharacterInUTF-8_U+FFFF": """["￿"]""",
"y_string_null_escape": """["\u0000"]""",
"y_string_one-byte-utf-8": """["\u002c"]""",
"y_string_pi": """["π"]""",
"y_string_simple_ascii": """["asd "]""",
"y_string_space": """" """",
"y_string_three-byte-utf-8": """["\u0821"]""",
"y_string_two-byte-utf-8": """["\u0123"]""",
"y_string_u+2028_line_sep": """[""]""",
"y_string_u+2029_par_sep": """[""]""",
"y_string_uEscape": """["\u0061\u30af\u30EA\u30b9"]""",
"y_string_unescaped_char_delete": """[""]""",
"y_string_unicode_2": """["⍂㈴⍂"]""",
"y_string_unicodeEscapedBackslash": """["\u005C"]""",
"y_string_unicode_escaped_double_quote": """["\u0022"]""",
"y_string_unicode": """["\uA66D"]""",
"y_string_unicode_U+200B_ZERO_WIDTH_SPACE": """["\u200B"]""",
"y_string_unicode_U+2064_invisible_plus": """["\u2064"]""",
"y_string_UTF-16_Surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF": """["\uD834\uDd1e"]""",
"y_string_utf8": """["€𝄞"]""",
"y_string_with_del_character": """["aa"]""",
"y_structure_lonely_false": """false""",
"y_structure_lonely_int": """42""",
"y_structure_lonely_negative_real": """-0.1""",
"y_structure_lonely_null": """null""",
"y_structure_lonely_string": """"asd"""",
"y_structure_lonely_true": """true""",
"y_structure_string_empty": """""""",
"y_structure_trailing_newline": """["a"]""",
"y_structure_true_in_array": """[true]""",
"y_structure_whitespace_array": """ [] """,
}
suite "JSON":
test "Multiple parsing tests":
var test_is_failed = false
for test_item in parsing_testdata:
let name = test_item[0]
let data = test_item[1]
var
parsed_successfully = false
parsed: JsonNode
exception_while_parsing = ""
exception_while_rendering = ""
try:
parsed = parseJson(data)
parsed_successfully = true
except:
exception_while_parsing = getCurrentExceptionMsg()
proc echo_summary(msg: string) =
var rendered = ""
var render_successfully = false
if parsed_successfully:
try:
rendered = $parsed
render_successfully = true
except:
rendered = "[Fail to render:<$#>]" % getCurrentExceptionMsg()
else:
rendered = "<$#>" % exception_while_parsing
echo name, repeat(' ', 60 - name.len), "[$#]" % msg, " ", rendered
case name[0]
of 'y':
# Tests starting with y_ must parse
if not parsed_successfully:
echo_summary "Failed to parse"
test_is_failed = true
of 'n':
# Tests starting with n_ should not parse
if parsed_successfully:
echo_summary "Failed to raise exception"
of 'i':
if parsed_successfully:
echo_summary "OK"
else:
echo_summary "Not parsed"
else: discard
# FIXME: temporarily disabled until "y_" tests will succeed
# if test_is_failed: fail()

View File

@@ -9,8 +9,11 @@
import parseutils, strutils, os, osproc, streams, parsecfg
const
cmdTemplate* = r"compiler" / "nim $target --lib:lib --hints:on -d:testing $options $file"
var compilerPrefix* = "compiler" / "nim "
proc cmdTemplate*(): string =
compilerPrefix & "$target --lib:lib --hints:on -d:testing $options $file"
type
TTestAction* = enum
@@ -100,7 +103,7 @@ proc specDefaults*(result: var TSpec) =
result.outp = ""
result.nimout = ""
result.ccodeCheck = ""
result.cmd = cmdTemplate
result.cmd = cmdTemplate()
result.line = 0
result.column = 0
result.tfile = ""
@@ -173,7 +176,7 @@ proc parseSpec*(filename: string): TSpec =
raise newException(ValueError, "cannot interpret as a bool: " & e.value)
of "cmd":
if e.value.startsWith("nim "):
result.cmd = "compiler" / e.value
result.cmd = compilerPrefix & e.value[4..^1]
else:
result.cmd = e.value
of "ccodecheck": result.ccodeCheck = e.value

View File

@@ -34,6 +34,7 @@ Options:
--failing only show failing/ignored tests
--pedantic return non-zero status code if there are failures
--targets:"c c++ js objc" run tests for specified targets (default: all)
--nim:path use a particular nim executable (default: compiler/nim)
""" % resultsFile
type
@@ -367,7 +368,7 @@ proc testNoSpec(r: var TResults, test: TTest) =
# does not extract the spec because the file is not supposed to have any
#let tname = test.name.addFileExt(".nim")
inc(r.total)
let given = callCompiler(cmdTemplate, test.name, test.options, test.target)
let given = callCompiler(cmdTemplate(), test.name, test.options, test.target)
r.addResult(test, "", given.msg, given.err)
if given.err == reSuccess: inc(r.passed)
@@ -376,7 +377,7 @@ proc testC(r: var TResults, test: TTest) =
let tname = test.name.addFileExt(".c")
inc(r.total)
styledEcho "Processing ", fgCyan, extractFilename(tname)
var given = callCCompiler(cmdTemplate, test.name & ".c", test.options, test.target)
var given = callCCompiler(cmdTemplate(), test.name & ".c", test.options, test.target)
if given.err != reSuccess:
r.addResult(test, "", given.msg, given.err)
elif test.action == actionRun:
@@ -424,6 +425,7 @@ proc main() =
of "failing": optFailing = true
of "pedantic": optPedantic = true
of "targets": targets = parseTargets(p.val.string)
of "nim": compilerPrefix = p.val.string
else: quit Usage
p.next()
if p.kind != cmdArgument: quit Usage

View File

@@ -119,10 +119,14 @@ proc v(name: string, typ = "cint", no_other = false) =
addf(tl,
"#ifdef $3\n fprintf(f, \"const $1* = $2(%ld)\\n\", $3);\n#endif\n",
n, t, name)
else:
of "cint", "cshort", "InAddrScalar", "TSa_Family":
addf(tl,
"#ifdef $3\n fprintf(f, \"const $1* = $2(%d)\\n\", $3);\n#endif\n",
n, t, name)
else:
addf(tl,
"#ifdef $3\n fprintf(f, \"const $1* = cast[$2](%d)\\n\", $3);\n#endif\n",
n, t, name)
header("<aio.h>")
@@ -544,6 +548,11 @@ v("SS_DISABLE")
v("MINSIGSTKSZ")
v("SIGSTKSZ")
v("SIG_HOLD", "Sighandler")
v("SIG_DFL", "Sighandler")
v("SIG_ERR", "Sighandler")
v("SIG_IGN", "Sighandler")
header("<sys/ipc.h>")
v("IPC_CREAT")
v("IPC_EXCL")

View File

@@ -45,6 +45,8 @@ Changes affecting backwards compatibility
AST that is the same as what is used to define an enum. Previously the AST
returned had a repeated ``EnumTy`` node and was missing the initial pragma
node (which is currently empty for an enum).
- ``macros.getTypeImpl`` now correctly returns the implementation for a symbol
of type ``tyGenericBody``.
- If the dispatcher parameter's value used in multi method is ``nil``,
a ``NilError`` exception is raised. The old behavior was that the method
would be a ``nop`` then.
@@ -61,6 +63,10 @@ Changes affecting backwards compatibility
compile-time value.
- On posix, the results of `waitForExit`, `peekExitCode`, `execCmd` will return
128 + signal number if the application terminates via signal.
- ``ospaths.getConfigDir`` now conforms to the XDG Base Directory specification
on non-Windows OSs. It returns the value of the XDG_CONFIG_DIR environment
variable if it is set, and returns the default configuration directory,
"~/.config/", otherwise.
Library Additions
-----------------
@@ -198,3 +204,122 @@ via a commit, for a full list see
- Fixed "await inside array/dict literal produces invalid code"
(`#5314 <https://github.com/nim-lang/Nim/issues/5314>`_)
- Fixed "asyncdispatch.accept() can raise exception inside poll() instead of failing future on Windows"
(`#5279 <https://github.com/nim-lang/Nim/issues/5279>`_)
- Fixed "VM: A crash report should be more informative"
(`#5352 <https://github.com/nim-lang/Nim/issues/5352>`_)
- Fixed "IO routines are poor at handling errors"
(`#5349 <https://github.com/nim-lang/Nim/issues/5349>`_)
- Fixed "new import syntax doesn't work?"
(`#5185 <https://github.com/nim-lang/Nim/issues/5185>`_)
- Fixed "Seq of object literals skips unmentioned fields"
(`#5339 <https://github.com/nim-lang/Nim/issues/5339>`_)
- Fixed "``sym is not accessible`` in compile time"
(`#5354 <https://github.com/nim-lang/Nim/issues/5354>`_)
- Fixed "the matching is broken in re.nim"
(`#5382 <https://github.com/nim-lang/Nim/issues/5382>`_)
- Fixed "development branch breaks in my c wrapper"
(`#5392 <https://github.com/nim-lang/Nim/issues/5392>`_)
- Fixed "Bad codegen: toSeq + tuples + generics"
(`#5383 <https://github.com/nim-lang/Nim/issues/5383>`_)
- Fixed "Bad codegen: toSeq + tuples + generics"
(`#5383 <https://github.com/nim-lang/Nim/issues/5383>`_)
- Fixed "Codegen error when using container of containers"
(`#5402 <https://github.com/nim-lang/Nim/issues/5402>`_)
- Fixed "sizeof(RangeType) is not available in static context"
(`#5399 <https://github.com/nim-lang/Nim/issues/5399>`_)
- Fixed "Regression: ICE: expr: var not init ex_263713"
(`#5405 <https://github.com/nim-lang/Nim/issues/5405>`_)
- Fixed "Stack trace is wrong when assignment operator fails with template"
(`#5400 <https://github.com/nim-lang/Nim/issues/5400>`_)
- Fixed "SIGSEGV in compiler"
(`#5391 <https://github.com/nim-lang/Nim/issues/5391>`_)
- Fixed "Compiler regression with struct member names"
(`#5404 <https://github.com/nim-lang/Nim/issues/5404>`_)
- Fixed "Regression: compiler segfault"
(`#5419 <https://github.com/nim-lang/Nim/issues/5419>`_)
- Fixed "The compilation of jester routes is broken on devel"
(`#5417 <https://github.com/nim-lang/Nim/issues/5417>`_)
- Fixed "Non-generic return type produces "method is not a base""
(`#5432 <https://github.com/nim-lang/Nim/issues/5432>`_)
- Fixed "Confusing error behavior when calling slice[T].random"
(`#5430 <https://github.com/nim-lang/Nim/issues/5430>`_)
- Fixed "Wrong method called"
(`#5439 <https://github.com/nim-lang/Nim/issues/5439>`_)
- Fixed "Attempt to document the strscans.scansp macro"
(`#5154 <https://github.com/nim-lang/Nim/issues/5154>`_)
- Fixed "[Regression] Invalid C code for _ symbol inside jester routes"
(`#5452 <https://github.com/nim-lang/Nim/issues/5452>`_)
- Fixed "StdLib base64 encodeInternal crashes with out of bound exception"
(`#5457 <https://github.com/nim-lang/Nim/issues/5457>`_)
- Fixed "Nim hangs forever in infinite loop in nre library"
(`#5444 <https://github.com/nim-lang/Nim/issues/5444>`_)
- Fixed "Tester passes test although individual test in suite fails"
(`#5472 <https://github.com/nim-lang/Nim/issues/5472>`_)
- Fixed "terminal.nim documentation"
(`#5483 <https://github.com/nim-lang/Nim/issues/5483>`_)
- Fixed "Codegen error - expected identifier before ')' token (probably regression)"
(`#5481 <https://github.com/nim-lang/Nim/issues/5481>`_)
- Fixed "mixin not works inside generic proc generated by template"
(`#5478 <https://github.com/nim-lang/Nim/issues/5478>`_)
- Fixed "var not init (converter + template + macro)"
(`#5467 <https://github.com/nim-lang/Nim/issues/5467>`_)
- Fixed "`==` for OrderedTable should consider equal content but different size as equal."
(`#5487 <https://github.com/nim-lang/Nim/issues/5487>`_)
- Fixed "Fixed tests/tester.nim"
(`#45 <https://github.com/nim-lang/Nim/issues/45>`_)
- Fixed "template instanciation crashes compiler"
(`#5428 <https://github.com/nim-lang/Nim/issues/5428>`_)
- Fixed "Internal compiler error in handleGenericInvocation"
(`#5167 <https://github.com/nim-lang/Nim/issues/5167>`_)
- Fixed "compiler crash in forwarding template"
(`#5455 <https://github.com/nim-lang/Nim/issues/5455>`_)
- Fixed "Doc query re public/private + suggestion re deprecated"
(`#5529 <https://github.com/nim-lang/Nim/issues/5529>`_)
- Fixed "inheritance not work for generic object whose parent is parameterized"
(`#5264 <https://github.com/nim-lang/Nim/issues/5264>`_)
- Fixed "weird inheritance rule restriction"
(`#5231 <https://github.com/nim-lang/Nim/issues/5231>`_)
- Fixed "Enum with holes broken in JS"
(`#5062 <https://github.com/nim-lang/Nim/issues/5062>`_)
- Fixed "enum type and aliased enum type inequality when tested with operator `is` involving template"
(`#5360 <https://github.com/nim-lang/Nim/issues/5360>`_)
- Fixed "logging: problem with console logger caused by the latest changes in sysio"
(`#5546 <https://github.com/nim-lang/Nim/issues/5546>`_)
- Fixed "Crash if proc and caller doesn't define seq type - HEAD"
(`#4756 <https://github.com/nim-lang/Nim/issues/4756>`_)
- Fixed "`path` config option doesn't work when compilation is invoked from a different directory"
(`#5228 <https://github.com/nim-lang/Nim/issues/5228>`_)
- Fixed "segfaults module doesn't compile with C++ backend"
(`#5550 <https://github.com/nim-lang/Nim/issues/5550>`_)
- Fixed "Improve `joinThreads` for windows"
(`#4972 <https://github.com/nim-lang/Nim/issues/4972>`_)
- Fixed "Compiling in release mode prevents valid code execution."
(`#5296 <https://github.com/nim-lang/Nim/issues/5296>`_)
- Fixed "Forward declaration of generic procs or iterators doesn't work"
(`#4104 <https://github.com/nim-lang/Nim/issues/4104>`_)
- Fixed "cant create thread after join"
(`#4719 <https://github.com/nim-lang/Nim/issues/4719>`_)
- Fixed "can't compile with var name "near" and --threads:on"
(`#5598 <https://github.com/nim-lang/Nim/issues/5598>`_)
- Fixed "inconsistent behavior when calling parent's proc of generic object"
(`#5241 <https://github.com/nim-lang/Nim/issues/5241>`_)
- Fixed "The problem with import order of asyncdispatch and unittest modules"
(`#5597 <https://github.com/nim-lang/Nim/issues/5597>`_)
- Fixed "Generic code fails to compile in unexpected ways"
(`#976 <https://github.com/nim-lang/Nim/issues/976>`_)
- Fixed "Another 'User defined type class' issue"
(`#1128 <https://github.com/nim-lang/Nim/issues/1128>`_)
- Fixed "compiler fails to compile user defined typeclass"
(`#1147 <https://github.com/nim-lang/Nim/issues/1147>`_)
- Fixed "Type class membership testing doesn't work on instances of generic object types"
(`#1570 <https://github.com/nim-lang/Nim/issues/1570>`_)
- Fixed "Strange overload resolution behavior for procedures with typeclass arguments"
(`#1991 <https://github.com/nim-lang/Nim/issues/1991>`_)
- Fixed "The same UDTC can't constrain two type parameters in the same procedure"
(`#2018 <https://github.com/nim-lang/Nim/issues/2018>`_)
- Fixed "More trait/concept issues"
(`#2423 <https://github.com/nim-lang/Nim/issues/2423>`_)
- Fixed "Bugs with concepts?"
(`#2882 <https://github.com/nim-lang/Nim/issues/2882>`_)