mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-31 02:43:41 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5935c3bfa9 | ||
|
|
2114414099 | ||
|
|
3788aa0a99 | ||
|
|
e98c98b46c | ||
|
|
51723bace8 | ||
|
|
a90e687d26 | ||
|
|
4b42170022 | ||
|
|
2eff34f08a | ||
|
|
ba51e7c4d8 | ||
|
|
d259099ef0 | ||
|
|
915cd5b28b | ||
|
|
16bbffcb77 | ||
|
|
73af7c60a1 | ||
|
|
7bdcaada13 | ||
|
|
e77e129a05 | ||
|
|
d0b3b7e1a7 | ||
|
|
2735fd2bf5 | ||
|
|
8d1f03e1da | ||
|
|
d83eb88eb9 | ||
|
|
10907cc4a7 |
@@ -231,7 +231,7 @@ type
|
||||
TNodeKinds* = set[TNodeKind]
|
||||
|
||||
type
|
||||
TSymFlag* = enum # 51 flags!
|
||||
TSymFlag* = enum # 52 flags!
|
||||
sfUsed, # read access of sym (for warnings) or simply used
|
||||
sfExported, # symbol is exported from module
|
||||
sfFromGeneric, # symbol is instantiation of a generic; this is needed
|
||||
@@ -315,6 +315,7 @@ type
|
||||
sfVirtual # proc is a C++ virtual function
|
||||
sfByCopy # param is marked as pass bycopy
|
||||
sfCodegenDecl # type, proc, global or proc param is marked as codegenDecl
|
||||
sfWasGenSym # symbol was 'gensym'ed
|
||||
|
||||
TSymFlags* = set[TSymFlag]
|
||||
|
||||
|
||||
@@ -309,7 +309,16 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode; result: var Rope; need
|
||||
addAddrLoc(p.config, withTmpIfNeeded(p, a, needsTmp), result)
|
||||
elif p.module.compileToCpp and param.typ.kind in {tyVar} and
|
||||
n.kind == nkHiddenAddr:
|
||||
initLocExprSingleUse(p, n[0], a)
|
||||
# bug #23748: we need to introduce a temporary here. The expression type
|
||||
# will be a reference in C++ and we cannot create a temporary reference
|
||||
# variable. Thus, we create a temporary pointer variable instead.
|
||||
let needsIndirect = mapType(p.config, n[0].typ, mapTypeChooser(n[0]) == skParam) != ctArray
|
||||
if needsIndirect:
|
||||
n.typ = n.typ.exactReplica
|
||||
n.typ.flags.incl tfVarIsPtr
|
||||
initLocExprSingleUse(p, n, a)
|
||||
a = withTmpIfNeeded(p, a, needsTmp)
|
||||
if needsIndirect: a.flags.incl lfIndirect
|
||||
# if the proc is 'importc'ed but not 'importcpp'ed then 'var T' still
|
||||
# means '*T'. See posix.nim for lots of examples that do that in the wild.
|
||||
let callee = call[0]
|
||||
@@ -407,9 +416,11 @@ proc genParams(p: BProc, ri: PNode, typ: PType; result: var Rope) =
|
||||
if not needTmp[i - 1]:
|
||||
needTmp[i - 1] = potentialAlias(n, potentialWrites)
|
||||
getPotentialWrites(ri[i], false, potentialWrites)
|
||||
if ri[i].kind in {nkHiddenAddr, nkAddr}:
|
||||
# Optimization: don't use a temp, if we would only take the address anyway
|
||||
needTmp[i - 1] = false
|
||||
when false:
|
||||
# this optimization is wrong, see bug #23748
|
||||
if ri[i].kind in {nkHiddenAddr, nkAddr}:
|
||||
# Optimization: don't use a temp, if we would only take the address anyway
|
||||
needTmp[i - 1] = false
|
||||
|
||||
var oldLen = result.len
|
||||
for i in 1..<ri.len:
|
||||
|
||||
@@ -344,7 +344,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
of tyString:
|
||||
if optSeqDestructors in p.config.globalOptions:
|
||||
genGenericAsgn(p, dest, src, flags)
|
||||
elif (needToCopy notin flags and src.storage != OnStatic) or canMove(p, src.lode, dest):
|
||||
elif ({needToCopy, needToCopySinkParam} * flags == {} and src.storage != OnStatic) or canMove(p, src.lode, dest):
|
||||
genRefAssign(p, dest, src)
|
||||
else:
|
||||
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
|
||||
@@ -832,6 +832,8 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) =
|
||||
#Message(e.info, warnUser, "HERE NEW &")
|
||||
elif mapType(p.config, e[0].typ, mapTypeChooser(e[0]) == skParam) == ctArray or isCppRef(p, e.typ):
|
||||
expr(p, e[0], d)
|
||||
# bug #19497
|
||||
d.lode = e
|
||||
else:
|
||||
var a: TLoc
|
||||
initLocExpr(p, e[0], a)
|
||||
@@ -2393,8 +2395,14 @@ proc genMove(p: BProc; n: PNode; d: var TLoc) =
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1($2);$n", [rdLoc(b), byRefLoc(p, a)])
|
||||
else:
|
||||
let flags = if not canMove(p, n[1], d): {needToCopy} else: {}
|
||||
genAssignment(p, d, a, flags)
|
||||
if n[1].kind == nkSym and isSinkParam(n[1].sym):
|
||||
var tmp: TLoc
|
||||
getTemp(p, n[1].typ.skipTypes({tySink}), tmp)
|
||||
genAssignment(p, tmp, a, {needToCopySinkParam})
|
||||
genAssignment(p, d, tmp, {})
|
||||
resetLoc(p, tmp)
|
||||
else:
|
||||
genAssignment(p, d, a, {})
|
||||
resetLoc(p, a)
|
||||
|
||||
proc genDestroy(p: BProc; n: PNode) =
|
||||
|
||||
@@ -273,9 +273,12 @@ proc isInvalidReturnType(conf: ConfigRef; typ: PType, isProc = true): bool =
|
||||
if rettype.isImportedCppType or t.isImportedCppType or
|
||||
(typ.callConv == ccCDecl and conf.selectedGC in {gcArc, gcAtomicArc, gcOrc}):
|
||||
# prevents nrvo for cdecl procs; # bug #23401
|
||||
return false
|
||||
result = containsGarbageCollectedRef(t) or
|
||||
(t.kind == tyObject and not isObjLackingTypeField(t))
|
||||
result = false
|
||||
else:
|
||||
result = containsGarbageCollectedRef(t) or
|
||||
(t.kind == tyObject and not isObjLackingTypeField(t)) or
|
||||
(getSize(conf, rettype) == szUnknownSize and (t.sym == nil or sfImportc notin t.sym.flags))
|
||||
|
||||
else: result = false
|
||||
|
||||
const
|
||||
@@ -1432,7 +1435,7 @@ proc genObjectInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo
|
||||
else:
|
||||
genTypeInfoAuxBase(m, typ, origType, name, rope("0"), info)
|
||||
var tmp = getNimNode(m)
|
||||
if not isImportedType(typ):
|
||||
if (not isImportedType(typ)) or tfCompleteStruct in typ.flags:
|
||||
genObjectFields(m, typ, origType, typ.n, tmp, info)
|
||||
m.s[cfsTypeInit3].addf("$1.node = &$2;$n", [tiNameForHcr(m, name), tmp])
|
||||
var t = typ[0]
|
||||
|
||||
@@ -406,6 +406,7 @@ proc rdCharLoc(a: TLoc): Rope =
|
||||
type
|
||||
TAssignmentFlag = enum
|
||||
needToCopy
|
||||
needToCopySinkParam
|
||||
needTempForOpenArray
|
||||
TAssignmentFlags = set[TAssignmentFlag]
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
|
||||
# internalAssert c.config, false
|
||||
idTablePut(c.mapping, s, x)
|
||||
if sfGenSym in s.flags:
|
||||
# TODO: getIdent(c.ic, "`" & x.name.s & "`gensym" & $c.instID)
|
||||
result.add newIdentNode(getIdent(c.ic, x.name.s & "`gensym" & $c.instID),
|
||||
if c.instLines: actual.info else: templ.info)
|
||||
else:
|
||||
|
||||
@@ -311,6 +311,8 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||
result.owner = getCurrOwner(c)
|
||||
else:
|
||||
result = newSym(kind, considerQuotedIdent(c, n), c.idgen, getCurrOwner(c), n.info)
|
||||
if find(result.name.s, '`') >= 0:
|
||||
result.flags.incl sfWasGenSym
|
||||
#if kind in {skForVar, skLet, skVar} and result.owner.kind == skModule:
|
||||
# incl(result.flags, sfGlobal)
|
||||
when defined(nimsuggest):
|
||||
@@ -320,7 +322,7 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||
allowed: TSymFlags): PSym
|
||||
# identifier with visibility
|
||||
proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
|
||||
allowed: TSymFlags): PSym
|
||||
allowed: TSymFlags, fromTopLevel = false): PSym
|
||||
|
||||
proc typeAllowedCheck(c: PContext; info: TLineInfo; typ: PType; kind: TSymKind;
|
||||
flags: TTypeAllowedFlags = {}) =
|
||||
|
||||
@@ -60,8 +60,11 @@ iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym
|
||||
elif t.kind in {tyGenericParam, tyConcept}:
|
||||
localError(c.config, a.info, errCannotInstantiateX % q.name.s)
|
||||
t = errorType(c)
|
||||
elif isUnresolvedStatic(t) and c.inGenericContext == 0 and
|
||||
c.matchedConcept == nil:
|
||||
elif isUnresolvedStatic(t) and (q.typ.kind == tyStatic or
|
||||
(q.typ.kind == tyGenericParam and
|
||||
q.typ.sons.len > 0 and
|
||||
q.typ.sons[0].kind == tyStatic)) and
|
||||
c.inGenericContext == 0 and c.matchedConcept == nil:
|
||||
# generic/concept type bodies will try to instantiate static values but
|
||||
# won't actually use them
|
||||
localError(c.config, a.info, errCannotInstantiateX % q.name.s)
|
||||
|
||||
@@ -357,7 +357,7 @@ proc identWithin(n: PNode, s: PIdent): bool =
|
||||
|
||||
proc semIdentDef(c: PContext, n: PNode, kind: TSymKind, reportToNimsuggest = true): PSym =
|
||||
if isTopLevel(c):
|
||||
result = semIdentWithPragma(c, kind, n, {sfExported})
|
||||
result = semIdentWithPragma(c, kind, n, {sfExported}, fromTopLevel = true)
|
||||
incl(result.flags, sfGlobal)
|
||||
#if kind in {skVar, skLet}:
|
||||
# echo "global variable here ", n.info, " ", result.name.s
|
||||
|
||||
@@ -521,7 +521,7 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||
result = newSymG(kind, n, c)
|
||||
|
||||
proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
|
||||
allowed: TSymFlags): PSym =
|
||||
allowed: TSymFlags, fromTopLevel = false): PSym =
|
||||
if n.kind == nkPragmaExpr:
|
||||
checkSonsLen(n, 2, c.config)
|
||||
result = semIdentVis(c, kind, n[0], allowed)
|
||||
@@ -536,11 +536,15 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
|
||||
else: discard
|
||||
else:
|
||||
result = semIdentVis(c, kind, n, allowed)
|
||||
let invalidPragmasForPush = if fromTopLevel and sfWasGenSym notin result.flags:
|
||||
{}
|
||||
else:
|
||||
{wExportc, wExportCpp, wDynlib}
|
||||
case kind
|
||||
of skField: implicitPragmas(c, result, n.info, fieldPragmas)
|
||||
of skVar: implicitPragmas(c, result, n.info, varPragmas)
|
||||
of skLet: implicitPragmas(c, result, n.info, letPragmas)
|
||||
of skConst: implicitPragmas(c, result, n.info, constPragmas)
|
||||
of skVar: implicitPragmas(c, result, n.info, varPragmas-invalidPragmasForPush)
|
||||
of skLet: implicitPragmas(c, result, n.info, letPragmas-invalidPragmasForPush)
|
||||
of skConst: implicitPragmas(c, result, n.info, constPragmas-invalidPragmasForPush)
|
||||
else: discard
|
||||
|
||||
proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) =
|
||||
|
||||
@@ -2455,7 +2455,7 @@ proc arrayConstr(c: PContext, n: PNode): PType =
|
||||
result = newTypeS(tyArray, c)
|
||||
rawAddSon(result, makeRangeType(c, 0, 0, n.info))
|
||||
addSonSkipIntLit(result, skipTypes(n.typ,
|
||||
{tyGenericInst, tyVar, tyLent, tyOrdinal}), c.idgen)
|
||||
{tyVar, tyLent, tyOrdinal}), c.idgen)
|
||||
|
||||
proc arrayConstr(c: PContext, info: TLineInfo): PType =
|
||||
result = newTypeS(tyArray, c)
|
||||
|
||||
@@ -472,7 +472,8 @@ proc transformYield(c: PTransf, n: PNode): PNode =
|
||||
|
||||
proc transformAddrDeref(c: PTransf, n: PNode, kinds: TNodeKinds): PNode =
|
||||
result = transformSons(c, n)
|
||||
if c.graph.config.backend == backendCpp or sfCompileToCpp in c.module.flags: return
|
||||
# inlining of 'var openarray' iterators; bug #19977
|
||||
if n.typ.kind != tyOpenArray and (c.graph.config.backend == backendCpp or sfCompileToCpp in c.module.flags): return
|
||||
var n = result
|
||||
case n[0].kind
|
||||
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
|
||||
|
||||
@@ -52,6 +52,7 @@ where code size matters and you know that your code does not produce cycles, you
|
||||
use `--mm:arc`. Notice that the default `async`:idx: implementation produces cycles
|
||||
and leaks memory with `--mm:arc`, in other words, for `async` you need to use `--mm:orc`.
|
||||
|
||||
Only ARC/ORC support move semantics, destructors, `sink`, `cursor`, `acyclic`.
|
||||
|
||||
|
||||
Other MM modes
|
||||
|
||||
10
koch.nim
10
koch.nim
@@ -11,9 +11,9 @@
|
||||
|
||||
const
|
||||
# examples of possible values for repos: Head, ea82b54
|
||||
NimbleStableCommit = "f8bd7b5fa6ea7a583b411b5959b06e6b5eb23667" # master
|
||||
AtlasStableCommit = "7b780811a168f3f32bff4822369dda46a7f87f9a"
|
||||
ChecksumsStableCommit = "b4c73320253f78e3a265aec6d9e8feb83f97c77b"
|
||||
NimbleStableCommit = "be2f1309b35a6189ff5eb34a007793e6d3f94157" # master
|
||||
AtlasStableCommit = "5faec3e9a33afe99a7d22377dd1b45a5391f5504"
|
||||
ChecksumsStableCommit = "025bcca3915a1b9f19878cea12ad68f9884648fc"
|
||||
SatStableCommit = "faf1617f44d7632ee9601ebc13887644925dcc01"
|
||||
|
||||
# examples of possible values for fusion: #head, #ea82b54, 1.2.3
|
||||
@@ -167,9 +167,11 @@ proc bundleAtlasExe(latest: bool, args: string) =
|
||||
let commit = if latest: "HEAD" else: AtlasStableCommit
|
||||
cloneDependency(distDir, "https://github.com/nim-lang/atlas.git",
|
||||
commit = commit, allowBundled = true)
|
||||
cloneDependency(distDir / "atlas" / distDir, "https://github.com/nim-lang/sat.git",
|
||||
commit = SatStableCommit, allowBundled = true)
|
||||
# installer.ini expects it under $nim/bin
|
||||
nimCompile("dist/atlas/src/atlas.nim",
|
||||
options = "-d:release --noNimblePath " & args)
|
||||
options = "-d:release --noNimblePath -d:nimAtlasBootstrap " & args)
|
||||
|
||||
proc bundleNimsuggest(args: string) =
|
||||
nimCompileFold("Compile nimsuggest", "nimsuggest/nimsuggest.nim",
|
||||
|
||||
@@ -785,20 +785,13 @@ when defined(gcDestructors):
|
||||
# Well, not for the entire list, but for `max` elements of the list because
|
||||
# we split the list in order to achieve bounded response times.
|
||||
var it = c.freeList
|
||||
var x = 0
|
||||
var maxIters = 20 # make it time-bounded
|
||||
var total = 0
|
||||
while it != nil:
|
||||
if maxIters == 0:
|
||||
let rest = it.next.loada
|
||||
if rest != nil:
|
||||
it.next.storea nil
|
||||
addToSharedFreeList(c, rest)
|
||||
break
|
||||
inc x, size
|
||||
it = it.next.loada
|
||||
dec maxIters
|
||||
inc(c.free, x)
|
||||
dec(a.occ, x)
|
||||
inc total, size
|
||||
let chunk = cast[PSmallChunk](pageAddr(it))
|
||||
inc(chunk.free, size)
|
||||
it = it.next
|
||||
dec(a.occ, total)
|
||||
|
||||
proc freeDeferredObjects(a: var MemRegion; root: PBigChunk) =
|
||||
var it = root
|
||||
@@ -905,7 +898,7 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
|
||||
trackSize(c.size)
|
||||
sysAssert(isAccessible(a, result), "rawAlloc 14")
|
||||
sysAssert(allocInv(a), "rawAlloc: end")
|
||||
when logAlloc: cprintf("var pointer_%p = alloc(%ld)\n", result, requestedSize)
|
||||
when logAlloc: cprintf("var pointer_%p = alloc(%ld) # %p\n", result, requestedSize, addr a)
|
||||
|
||||
proc rawAlloc0(a: var MemRegion, requestedSize: int): pointer =
|
||||
result = rawAlloc(a, requestedSize)
|
||||
@@ -954,6 +947,8 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
|
||||
c.size = SmallChunkSize
|
||||
freeBigChunk(a, cast[PBigChunk](c))
|
||||
else:
|
||||
when logAlloc: cprintf("dealloc(pointer_%p) # SMALL FROM %p CALLER %p\n", p, c.owner, addr(a))
|
||||
|
||||
when defined(gcDestructors):
|
||||
addToSharedFreeList(c, f)
|
||||
sysAssert(((cast[int](p) and PageMask) - smallChunkOverhead()) %%
|
||||
@@ -961,6 +956,7 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
|
||||
else:
|
||||
# set to 0xff to check for usage after free bugs:
|
||||
when overwriteFree: nimSetMem(p, -1'i32, c.size -% bigChunkOverhead())
|
||||
when logAlloc: cprintf("dealloc(pointer_%p) # BIG %p\n", p, c.owner)
|
||||
when defined(gcDestructors):
|
||||
if c.owner == addr(a):
|
||||
deallocBigChunk(a, cast[PBigChunk](c))
|
||||
@@ -968,8 +964,9 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
|
||||
addToSharedFreeListBigChunks(c.owner[], cast[PBigChunk](c))
|
||||
else:
|
||||
deallocBigChunk(a, cast[PBigChunk](c))
|
||||
|
||||
sysAssert(allocInv(a), "rawDealloc: end")
|
||||
when logAlloc: cprintf("dealloc(pointer_%p)\n", p)
|
||||
#when logAlloc: cprintf("dealloc(pointer_%p)\n", p)
|
||||
|
||||
when not defined(gcDestructors):
|
||||
proc isAllocatedPtr(a: MemRegion, p: pointer): bool =
|
||||
|
||||
@@ -10,7 +10,7 @@ const
|
||||
## is the minor number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
NimPatch* {.intdefine.}: int = 6
|
||||
NimPatch* {.intdefine.}: int = 8
|
||||
## is the patch number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
|
||||
@@ -220,7 +220,10 @@ proc appendChar(dest: NimString, c: char) {.compilerproc, inline.} =
|
||||
proc setLengthStr(s: NimString, newLen: int): NimString {.compilerRtl.} =
|
||||
let n = max(newLen, 0)
|
||||
if s == nil:
|
||||
result = mnewString(n)
|
||||
if n == 0:
|
||||
return s
|
||||
else:
|
||||
result = mnewString(n)
|
||||
elif n <= s.space:
|
||||
result = s
|
||||
else:
|
||||
@@ -301,7 +304,10 @@ proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
||||
compilerRtl.} =
|
||||
sysAssert typ.kind == tySequence, "setLengthSeqV2: type is not a seq"
|
||||
if s == nil:
|
||||
result = cast[PGenericSeq](newSeq(typ, newLen))
|
||||
if newLen == 0:
|
||||
result = s
|
||||
else:
|
||||
result = cast[PGenericSeq](newSeq(typ, newLen))
|
||||
else:
|
||||
let elemSize = typ.base.size
|
||||
let elemAlign = typ.base.align
|
||||
|
||||
@@ -63,7 +63,7 @@ pkg "criterion", allowFailure = true # needs testing binary
|
||||
pkg "datamancer"
|
||||
pkg "dashing", "nim c tests/functional.nim"
|
||||
pkg "delaunay"
|
||||
pkg "dnsclient"
|
||||
pkg "dnsclient", allowFailure = true # super fragile
|
||||
pkg "docopt"
|
||||
pkg "dotenv"
|
||||
# when defined(linux): pkg "drchaos"
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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
|
||||
|
||||
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
|
||||
@@ -140,3 +140,8 @@ 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
discard """
|
||||
output: "123"
|
||||
targets: "c"
|
||||
targets: "c cpp"
|
||||
"""
|
||||
# Try to break the transformation pass:
|
||||
iterator iterAndZero(a: var openArray[int]): int =
|
||||
|
||||
@@ -38,3 +38,29 @@ proc main(): void =
|
||||
{.push staticBoundChecks: on.}
|
||||
|
||||
main()
|
||||
|
||||
|
||||
{.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.}
|
||||
|
||||
@@ -15,3 +15,12 @@ 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)
|
||||
|
||||
@@ -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/")
|
||||
|
||||
Reference in New Issue
Block a user