Compare commits
3 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
dcdddec674 |
|||
|
7e7fdcd914 |
|||
|
344e3cbc05 |
25 changed files with 46 additions and 409 deletions
|
|
@ -1085,7 +1085,13 @@ proc inst(g: ModuleGraph; c: PContext; t: PType; kind: TTypeAttachedOp; idgen: I
|
|||
let op = getAttachedOp(g, t, kind)
|
||||
if op != nil and op.ast != nil and op.ast.isGenericRoutine:
|
||||
if t.typeInst != nil:
|
||||
var a = TLiftCtx(info: info, g: g, kind: kind, c: c, idgen: idgen)
|
||||
var a: TLiftCtx
|
||||
a.info = info
|
||||
a.g = g
|
||||
a.kind = kind
|
||||
a.c = c
|
||||
a.idgen = idgen
|
||||
|
||||
let opInst = instantiateGeneric(a, op, t, t.typeInst)
|
||||
if opInst.ast != nil:
|
||||
patchBody(g, c, opInst.ast, info, a.idgen)
|
||||
|
|
|
|||
|
|
@ -343,8 +343,7 @@ proc addDeclAt*(c: PContext; scope: PScope, sym: PSym, info: TLineInfo) =
|
|||
if sym.name.s == "_": return
|
||||
let conflict = scope.addUniqueSym(sym)
|
||||
if conflict != nil:
|
||||
if sym.kind == skModule and conflict.kind == skModule and
|
||||
sym.position == conflict.position:
|
||||
if sym.kind == skModule and conflict.kind == skModule and sym.owner == conflict.owner:
|
||||
# e.g.: import foo; import foo
|
||||
# xxx we could refine this by issuing a different hint for the case
|
||||
# where a duplicate import happens inside an include.
|
||||
|
|
|
|||
|
|
@ -71,13 +71,6 @@ proc commandGenDepend(graph: ModuleGraph) =
|
|||
let project = graph.config.projectFull
|
||||
writeDepsFile(graph)
|
||||
generateDot(graph, project)
|
||||
|
||||
# dot in graphivz tool kit is required
|
||||
let graphvizDotPath = findExe("dot")
|
||||
if graphvizDotPath.len == 0:
|
||||
quit("gendepend: Graphviz's tool dot is required," &
|
||||
"see https://graphviz.org/download for downloading")
|
||||
|
||||
execExternalProgram(graph.config, "dot -Tpng -o" &
|
||||
changeFileExt(project, "png").string &
|
||||
' ' & changeFileExt(project, "dot").string)
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ proc findNodeJs*(): string {.inline.} =
|
|||
result = findExe("node")
|
||||
if result.len == 0:
|
||||
echo "Please install NodeJS first, see https://nodejs.org/en/download"
|
||||
raise newException(IOError, "NodeJS not found in PATH")
|
||||
raise newException(IOError, "NodeJS not found in PATH: " & result)
|
||||
|
|
|
|||
|
|
@ -998,7 +998,7 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags; expectedTy
|
|||
fixAbstractType(c, result)
|
||||
analyseIfAddressTakenInCall(c, result)
|
||||
if callee.magic != mNone:
|
||||
result = magicsAfterOverloadResolution(c, result, flags, expectedType)
|
||||
result = magicsAfterOverloadResolution(c, result, flags)
|
||||
when false:
|
||||
if result.typ != nil and
|
||||
not (result.typ.kind == tySequence and result.typ[0].kind == tyEmpty):
|
||||
|
|
@ -2206,7 +2206,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
|
|||
dummyTemplate[paramsPos].add newTreeI(nkIdentDefs, n.info, ids[0], getSysSym(c.graph, n.info, "typed").newSymNode, c.graph.emptyNode)
|
||||
for i in 1..<ids.len:
|
||||
let typ = semExprWithType(c, quotes[i+1], {}).typ
|
||||
if tfTriggersCompileTime notin typ.flags and typ.kind != tyTypeDesc:
|
||||
if tfTriggersCompileTime notin typ.flags:
|
||||
dummyTemplate[paramsPos].add newTreeI(nkIdentDefs, n.info, ids[i], newNodeIT(nkType, n.info, typ), c.graph.emptyNode)
|
||||
else:
|
||||
dummyTemplate[paramsPos].add newTreeI(nkIdentDefs, n.info, ids[i], getSysSym(c.graph, n.info, "typed").newSymNode, c.graph.emptyNode)
|
||||
|
|
|
|||
|
|
@ -127,18 +127,11 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) =
|
|||
if sfGenSym in param.flags:
|
||||
idTablePut(symMap, params[i].sym, result.typ.n[param.position+1].sym)
|
||||
freshGenSyms(c, b, result, orig, symMap)
|
||||
|
||||
|
||||
if sfBorrow notin orig.flags:
|
||||
# We do not want to generate a body for generic borrowed procs.
|
||||
# As body is a sym to the borrowed proc.
|
||||
let resultType = # todo probably refactor it into a function
|
||||
if result.kind == skMacro:
|
||||
sysTypeFromName(c.graph, n.info, "NimNode")
|
||||
elif not isInlineIterator(result.typ):
|
||||
result.typ[0]
|
||||
else:
|
||||
nil
|
||||
b = semProcBody(c, b, resultType)
|
||||
b = semProcBody(c, b)
|
||||
result.ast[bodyPos] = hloBody(c, b)
|
||||
excl(result.flags, sfForward)
|
||||
trackProc(c, result, result.ast[bodyPos])
|
||||
|
|
|
|||
|
|
@ -526,7 +526,7 @@ proc checkDefault(c: PContext, n: PNode): PNode =
|
|||
message(c.config, n.info, warnUnsafeDefault, typeToString(constructed))
|
||||
|
||||
proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||
flags: TExprFlags; expectedType: PType = nil): PNode =
|
||||
flags: TExprFlags): PNode =
|
||||
## This is the preferred code point to implement magics.
|
||||
## ``c`` the current module, a symbol table to a very good approximation
|
||||
## ``n`` the ast like it would be passed to a real macro
|
||||
|
|
@ -635,9 +635,5 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
|||
result = n
|
||||
of mPrivateAccess:
|
||||
result = semPrivateAccess(c, n)
|
||||
of mArrToSeq:
|
||||
result = n
|
||||
if result.typ != nil and expectedType != nil and result.typ.kind == tySequence and expectedType.kind == tySequence and result.typ[0].kind == tyEmpty:
|
||||
result.typ = expectedType # type inference for empty sequence # bug #21377
|
||||
else:
|
||||
result = n
|
||||
|
|
|
|||
|
|
@ -142,45 +142,15 @@ proc fieldsPresentInInitExpr(c: PContext, fieldsRecList, initExpr: PNode): strin
|
|||
if result.len != 0: result.add ", "
|
||||
result.add field.sym.name.s.quoteStr
|
||||
|
||||
proc locateFieldInDefaults(sym: PSym, defaults: seq[PNode]): bool =
|
||||
result = false
|
||||
for d in defaults:
|
||||
if sym.id == d[0].sym.id:
|
||||
return true
|
||||
|
||||
proc collectMissingFields(c: PContext, fieldsRecList: PNode,
|
||||
constrCtx: var ObjConstrContext, defaults: seq[PNode]
|
||||
): seq[PSym] =
|
||||
for r in directFieldsInRecList(fieldsRecList):
|
||||
constrCtx: var ObjConstrContext) =
|
||||
for r in directFieldsInRecList(fieldsRecList):
|
||||
if constrCtx.needsFullInit or
|
||||
sfRequiresInit in r.sym.flags or
|
||||
r.sym.typ.requiresInit:
|
||||
let assignment = locateFieldInInitExpr(c, r.sym, constrCtx.initExpr)
|
||||
if assignment == nil and not locateFieldInDefaults(r.sym, defaults):
|
||||
if constrCtx.needsFullInit or
|
||||
sfRequiresInit in r.sym.flags or
|
||||
r.sym.typ.requiresInit:
|
||||
constrCtx.missingFields.add r.sym
|
||||
else:
|
||||
result.add r.sym
|
||||
|
||||
proc collectMissingCaseFields(c: PContext, branchNode: PNode,
|
||||
constrCtx: var ObjConstrContext, defaults: seq[PNode]): seq[PSym] =
|
||||
if branchNode != nil:
|
||||
let fieldsRecList = branchNode[^1]
|
||||
result = collectMissingFields(c, fieldsRecList, constrCtx, defaults)
|
||||
|
||||
proc collectOrAddMissingCaseFields(c: PContext, branchNode: PNode,
|
||||
constrCtx: var ObjConstrContext, defaults: var seq[PNode]) =
|
||||
let res = collectMissingCaseFields(c, branchNode, constrCtx, defaults)
|
||||
for sym in res:
|
||||
let asgnType = newType(tyTypeDesc, nextTypeId(c.idgen), sym.typ.owner)
|
||||
let recTyp = sym.typ.skipTypes(defaultFieldsSkipTypes)
|
||||
rawAddSon(asgnType, recTyp)
|
||||
let asgnExpr = newTree(nkCall,
|
||||
newSymNode(getSysMagic(c.graph, constrCtx.initExpr.info, "zeroDefault", mZeroDefault)),
|
||||
newNodeIT(nkType, constrCtx.initExpr.info, asgnType)
|
||||
)
|
||||
asgnExpr.flags.incl nfUseDefaultField
|
||||
asgnExpr.typ = recTyp
|
||||
defaults.add newTree(nkExprColonExpr, newSymNode(sym), asgnExpr)
|
||||
if assignment == nil:
|
||||
constrCtx.missingFields.add r.sym
|
||||
|
||||
proc semConstructFields(c: PContext, n: PNode, constrCtx: var ObjConstrContext,
|
||||
flags: TExprFlags): tuple[status: InitStatus, defaults: seq[PNode]] =
|
||||
|
|
@ -196,6 +166,11 @@ proc semConstructFields(c: PContext, n: PNode, constrCtx: var ObjConstrContext,
|
|||
let fields = branch[^1]
|
||||
fieldsPresentInInitExpr(c, fields, constrCtx.initExpr)
|
||||
|
||||
template collectMissingFields(branchNode: PNode) =
|
||||
if branchNode != nil:
|
||||
let fields = branchNode[^1]
|
||||
collectMissingFields(c, fields, constrCtx)
|
||||
|
||||
let discriminator = n[0]
|
||||
internalAssert c.config, discriminator.kind == nkSym
|
||||
var selectedBranch = -1
|
||||
|
|
@ -313,7 +288,8 @@ proc semConstructFields(c: PContext, n: PNode, constrCtx: var ObjConstrContext,
|
|||
# When a branch is selected with a partial match, some of the fields
|
||||
# that were not initialized may be mandatory. We must check for this:
|
||||
if result.status == initPartial:
|
||||
collectOrAddMissingCaseFields(c, branchNode, constrCtx, result.defaults)
|
||||
collectMissingFields branchNode
|
||||
|
||||
else:
|
||||
result.status = initNone
|
||||
let discriminatorVal = semConstrField(c, flags + {efPreferStatic},
|
||||
|
|
@ -326,7 +302,7 @@ proc semConstructFields(c: PContext, n: PNode, constrCtx: var ObjConstrContext,
|
|||
# a result:
|
||||
let defaultValue = newIntLit(c.graph, constrCtx.initExpr.info, 0)
|
||||
let matchedBranch = n.pickCaseBranch defaultValue
|
||||
discard collectMissingCaseFields(c, matchedBranch, constrCtx, @[])
|
||||
collectMissingFields matchedBranch
|
||||
else:
|
||||
result.status = initPartial
|
||||
if discriminatorVal.kind == nkIntLit:
|
||||
|
|
@ -336,12 +312,11 @@ proc semConstructFields(c: PContext, n: PNode, constrCtx: var ObjConstrContext,
|
|||
if matchedBranch != nil:
|
||||
let (_, defaults) = semConstructFields(c, matchedBranch[^1], constrCtx, flags)
|
||||
result.defaults.add defaults
|
||||
collectOrAddMissingCaseFields(c, matchedBranch, constrCtx, result.defaults)
|
||||
collectMissingFields matchedBranch
|
||||
else:
|
||||
# All bets are off. If any of the branches has a mandatory
|
||||
# fields we must produce an error:
|
||||
for i in 1..<n.len:
|
||||
discard collectMissingCaseFields(c, n[i], constrCtx, @[])
|
||||
for i in 1..<n.len: collectMissingFields n[i]
|
||||
of nkSym:
|
||||
let field = n.sym
|
||||
let e = semConstrField(c, flags, field, constrCtx.initExpr)
|
||||
|
|
@ -373,7 +348,7 @@ proc semConstructTypeAux(c: PContext,
|
|||
result.status.mergeInitStatus status
|
||||
result.defaults.add defaults
|
||||
if status in {initPartial, initNone, initUnknown}:
|
||||
discard collectMissingFields(c, t.n, constrCtx, result.defaults)
|
||||
collectMissingFields c, t.n, constrCtx
|
||||
let base = t[0]
|
||||
if base == nil: break
|
||||
t = skipTypes(base, skipPtrs)
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ type
|
|||
module: PSym
|
||||
transCon: PTransCon # top of a TransCon stack
|
||||
inlining: int # > 0 if we are in inlining context (copy vars)
|
||||
isIntroducingNewLocalVars: bool # true if we are in `introducingNewLocalVars` (don't transform yields)
|
||||
contSyms, breakSyms: seq[PSym] # to transform 'continue' and 'break'
|
||||
deferDetected, tooEarly: bool
|
||||
graph: ModuleGraph
|
||||
|
|
@ -451,9 +450,7 @@ proc transformYield(c: PTransf, n: PNode): PNode =
|
|||
result.add(c.transCon.forLoopBody)
|
||||
else:
|
||||
# we need to introduce new local variables:
|
||||
c.isIntroducingNewLocalVars = true # don't transform yields when introducing new local vars
|
||||
result.add(introduceNewLocalVars(c, c.transCon.forLoopBody))
|
||||
c.isIntroducingNewLocalVars = false
|
||||
|
||||
for idx in 0 ..< result.len:
|
||||
var changeNode = result[idx]
|
||||
|
|
@ -1039,7 +1036,7 @@ proc transform(c: PTransf, n: PNode): PNode =
|
|||
else:
|
||||
result = transformSons(c, n)
|
||||
of nkYieldStmt:
|
||||
if c.inlining > 0 and not c.isIntroducingNewLocalVars:
|
||||
if c.inlining > 0:
|
||||
result = transformYield(c, n)
|
||||
else:
|
||||
result = transformSons(c, n)
|
||||
|
|
|
|||
|
|
@ -1909,8 +1909,7 @@ proc genVarSection(c: PCtx; n: PNode) =
|
|||
c.genAdditionalCopy(a[2], opcWrDeref, tmp, 0, val)
|
||||
c.freeTemp(val)
|
||||
c.freeTemp(tmp)
|
||||
elif not importcCondVar(s) and not (s.typ.kind == tyProc and s.typ.callConv == ccClosure) and
|
||||
sfPure notin s.flags: # fixes #10938
|
||||
elif not importcCondVar(s) and not (s.typ.kind == tyProc and s.typ.callConv == ccClosure): # fixes #10938
|
||||
# there is a pre-existing issue with closure types in VM
|
||||
# if `(var s: proc () = default(proc ()); doAssert s == nil)` works for you;
|
||||
# you might remove the second condition.
|
||||
|
|
|
|||
|
|
@ -172,6 +172,6 @@ Advanced options:
|
|||
--useVersion:1.0|1.2|1.6 emulate Nim version X of the Nim compiler, for testing
|
||||
--benchmarkVM:on|off turn benchmarking of VM code with cpuTime() on|off
|
||||
--profileVM:on|off turn compile time VM profiler on|off
|
||||
--sinkInference:on|off turn sink parameter inference on|off (default: off)
|
||||
--sinkInference:on|off turn sink parameter inference on|off (default: on)
|
||||
--panics:on|off turn panics into process terminations (default: off)
|
||||
--deepcopy:on|off enable 'system.deepCopy' for ``--mm:arc|orc``
|
||||
|
|
|
|||
|
|
@ -408,16 +408,6 @@ const unitWeights: array[FixedTimeUnit, int64] = [
|
|||
7 * secondsInDay * 1e9.int64,
|
||||
]
|
||||
|
||||
when (NimMajor, NimMinor) >= (1, 4):
|
||||
# Newer versions of Nim don't track defects
|
||||
{.pragma: parseFormatRaises, raises: [TimeParseError, TimeFormatParseError].}
|
||||
{.pragma: parseRaises, raises: [TimeParseError].}
|
||||
else:
|
||||
# Still track when using older versions
|
||||
{.pragma: parseFormatRaises, raises: [TimeParseError, TimeFormatParseError, Defect].}
|
||||
{.pragma: parseRaises, raises: [TimeParseError, Defect].}
|
||||
|
||||
|
||||
#
|
||||
# Helper procs
|
||||
#
|
||||
|
|
@ -2144,7 +2134,8 @@ proc format*(time: Time, f: static[string], zone: Timezone = local()): string
|
|||
result = time.inZone(zone).format(f2)
|
||||
|
||||
proc parse*(input: string, f: TimeFormat, zone: Timezone = local(),
|
||||
loc: DateTimeLocale = DefaultLocale): DateTime {.parseRaises.} =
|
||||
loc: DateTimeLocale = DefaultLocale): DateTime
|
||||
{.raises: [TimeParseError, Defect].} =
|
||||
## Parses `input` as a `DateTime` using the format specified by `f`.
|
||||
## If no UTC offset was parsed, then `input` is assumed to be specified in
|
||||
## the `zone` timezone. If a UTC offset was parsed, the result will be
|
||||
|
|
@ -2187,7 +2178,8 @@ proc parse*(input: string, f: TimeFormat, zone: Timezone = local(),
|
|||
result = toDateTime(parsed, zone, f, input)
|
||||
|
||||
proc parse*(input, f: string, tz: Timezone = local(),
|
||||
loc: DateTimeLocale = DefaultLocale): DateTime {.parseFormatRaises.} =
|
||||
loc: DateTimeLocale = DefaultLocale): DateTime
|
||||
{.raises: [TimeParseError, TimeFormatParseError, Defect].} =
|
||||
## Shorthand for constructing a `TimeFormat` and using it to parse
|
||||
## `input` as a `DateTime`.
|
||||
##
|
||||
|
|
@ -2200,12 +2192,14 @@ proc parse*(input, f: string, tz: Timezone = local(),
|
|||
result = input.parse(dtFormat, tz, loc = loc)
|
||||
|
||||
proc parse*(input: string, f: static[string], zone: Timezone = local(),
|
||||
loc: DateTimeLocale = DefaultLocale): DateTime {.parseRaises.} =
|
||||
loc: DateTimeLocale = DefaultLocale):
|
||||
DateTime {.raises: [TimeParseError, Defect].} =
|
||||
## Overload that validates `f` at compile time.
|
||||
const f2 = initTimeFormat(f)
|
||||
result = input.parse(f2, zone, loc = loc)
|
||||
|
||||
proc parseTime*(input, f: string, zone: Timezone): Time {.parseFormatRaises.} =
|
||||
proc parseTime*(input, f: string, zone: Timezone): Time
|
||||
{.raises: [TimeParseError, TimeFormatParseError, Defect].} =
|
||||
## Shorthand for constructing a `TimeFormat` and using it to parse
|
||||
## `input` as a `DateTime`, then converting it a `Time`.
|
||||
##
|
||||
|
|
@ -2217,7 +2211,7 @@ proc parseTime*(input, f: string, zone: Timezone): Time {.parseFormatRaises.} =
|
|||
parse(input, f, zone).toTime()
|
||||
|
||||
proc parseTime*(input: string, f: static[string], zone: Timezone): Time
|
||||
{.parseRaises.} =
|
||||
{.raises: [TimeParseError, Defect].} =
|
||||
## Overload that validates `format` at compile time.
|
||||
const f2 = initTimeFormat(f)
|
||||
result = input.parse(f2, zone).toTime()
|
||||
|
|
|
|||
|
|
@ -269,64 +269,3 @@ proc bug20305 =
|
|||
echo x.pChildren
|
||||
|
||||
bug20305()
|
||||
|
||||
# bug #21023
|
||||
block:
|
||||
block:
|
||||
type
|
||||
MGErrorKind = enum
|
||||
mgeUnexpected, mgeNotFound
|
||||
|
||||
type Foo = object
|
||||
kind: MGErrorKind
|
||||
ex: Exception
|
||||
|
||||
type Boo = object
|
||||
a: seq[int]
|
||||
|
||||
type
|
||||
Result2 = object
|
||||
case o: bool
|
||||
of false:
|
||||
e: Foo
|
||||
of true:
|
||||
v: Boo
|
||||
|
||||
proc startSessionSync(): Result2 =
|
||||
return Result2(o: true)
|
||||
|
||||
proc mainSync =
|
||||
let ff = startSessionSync()
|
||||
doAssert ff.o == true
|
||||
|
||||
mainSync()
|
||||
|
||||
block:
|
||||
type
|
||||
MGErrorKind = enum
|
||||
mgeUnexpected, mgeNotFound
|
||||
|
||||
type Foo = object
|
||||
kind: MGErrorKind
|
||||
ex: Exception
|
||||
|
||||
type Boo = object
|
||||
a: seq[int]
|
||||
|
||||
type
|
||||
Result2 = object
|
||||
case o: bool
|
||||
of false:
|
||||
e: Foo
|
||||
of true:
|
||||
v: Boo
|
||||
s: int
|
||||
|
||||
proc startSessionSync(): Result2 =
|
||||
return Result2(o: true, s: 12)
|
||||
|
||||
proc mainSync =
|
||||
let ff = startSessionSync()
|
||||
doAssert ff.s == 12
|
||||
|
||||
mainSync()
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
discard """
|
||||
cmd: "nim check $options $file"
|
||||
errormsg: "type mismatch: got <int> but expected 'float'"
|
||||
"""
|
||||
|
||||
when true: # bug #16654
|
||||
func fn[T](a: T, op: proc(a: T): float) = discard
|
||||
proc main() =
|
||||
let v = 1
|
||||
proc bar(r: auto): auto = v
|
||||
fn(1, bar)
|
||||
main()
|
||||
|
|
@ -153,16 +153,3 @@ proc unzip*[T,U](xs: List[tuple[t: T, u: U]]): (List[T], List[U]) = discard
|
|||
|
||||
proc unzip2*[T,U](xs: List[(T,U)]): (List[T], List[U]) = discard
|
||||
|
||||
type
|
||||
AtomicType = pointer|ptr|int
|
||||
|
||||
Atomic[T: AtomicType] = distinct T
|
||||
|
||||
Block[T: AtomicType] = object
|
||||
|
||||
AtomicContainer[T: AtomicType] = object
|
||||
b: Atomic[ptr Block[T]]
|
||||
|
||||
# bug #8295
|
||||
var x = AtomicContainer[int]()
|
||||
doAssert (ptr Block[int])(x.b) == nil
|
||||
|
|
|
|||
|
|
@ -262,8 +262,3 @@ proc doSomething[A, B](t: tuple[a: A, b: B]) = discard
|
|||
|
||||
discard identity((c: 1, d: 2))
|
||||
doSomething(identity((1, 2)))
|
||||
|
||||
# bug #6231
|
||||
proc myProc[T, U](x: T or U) = discard
|
||||
|
||||
myProc[int, string](x = 2)
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
proc fb* = echo "buzz!"
|
||||
|
|
@ -1 +0,0 @@
|
|||
proc fb* = echo "fizz!"
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
discard """
|
||||
errormsg: "redefinition of 'm21496'; previous declaration here: t21496.nim(5, 12)"
|
||||
"""
|
||||
|
||||
import fizz/m21496, buzz/m21496
|
||||
|
||||
# bug #21496
|
||||
|
||||
m21496.fb()
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
# bug #21306
|
||||
type
|
||||
FutureState {.pure.} = enum
|
||||
Pending, Finished, Cancelled, Failed
|
||||
|
||||
FutureBase = ref object of RootObj
|
||||
state: FutureState
|
||||
error: ref CatchableError
|
||||
id: uint
|
||||
|
||||
Future[T] = ref object of FutureBase
|
||||
closure: iterator(f: Future[T]): FutureBase {.raises: [Defect, CatchableError, Exception], gcsafe.}
|
||||
value: T
|
||||
|
||||
template setupFutureBase() =
|
||||
new(result)
|
||||
result.state = FutureState.Pending
|
||||
|
||||
proc newFutureImpl[T](): Future[T] =
|
||||
setupFutureBase()
|
||||
|
||||
template newFuture[T](fromProc: static[string] = ""): Future[T] =
|
||||
newFutureImpl[T]()
|
||||
|
||||
proc internalRead[T](fut: Future[T]): T =
|
||||
when T isnot void:
|
||||
return fut.value
|
||||
|
||||
template await[T](f: Future[T]): untyped =
|
||||
when declared(chronosInternalRetFuture):
|
||||
when not declaredInScope(chronosInternalTmpFuture):
|
||||
var chronosInternalTmpFuture {.inject.}: FutureBase = f
|
||||
else:
|
||||
chronosInternalTmpFuture = f
|
||||
|
||||
yield chronosInternalTmpFuture
|
||||
|
||||
when T isnot void:
|
||||
cast[type(f)](chronosInternalTmpFuture).internalRead()
|
||||
|
||||
type
|
||||
VerifierError {.pure.} = enum
|
||||
Invalid
|
||||
MissingParent
|
||||
UnviableFork
|
||||
Duplicate
|
||||
ProcessingCallback = proc() {.gcsafe, raises: [Defect].}
|
||||
BlockVerifier =
|
||||
proc(signedBlock: int):
|
||||
Future[VerifierError] {.gcsafe, raises: [Defect].}
|
||||
|
||||
SyncQueueKind {.pure.} = enum
|
||||
Forward, Backward
|
||||
|
||||
SyncRequest[T] = object
|
||||
kind: SyncQueueKind
|
||||
index: uint64
|
||||
slot: uint64
|
||||
count: uint64
|
||||
item: T
|
||||
|
||||
SyncResult[T] = object
|
||||
request: SyncRequest[T]
|
||||
data: seq[ref int]
|
||||
|
||||
SyncQueue[T] = ref object
|
||||
kind: SyncQueueKind
|
||||
readyQueue: seq[SyncResult[T]]
|
||||
blockVerifier: BlockVerifier
|
||||
|
||||
iterator blocks[T](sq: SyncQueue[T],
|
||||
sr: SyncResult[T]): ref int =
|
||||
case sq.kind
|
||||
of SyncQueueKind.Forward:
|
||||
for i in countup(0, len(sr.data) - 1):
|
||||
yield sr.data[i]
|
||||
of SyncQueueKind.Backward:
|
||||
for i in countdown(len(sr.data) - 1, 0):
|
||||
yield sr.data[i]
|
||||
|
||||
proc push[T](sq: SyncQueue[T]; sr: SyncRequest[T]; data: seq[ref int];
|
||||
processingCb: ProcessingCallback = nil): Future[void] {.
|
||||
stackTrace: off, gcsafe.} =
|
||||
iterator push_436208182(chronosInternalRetFuture: Future[void]): FutureBase {.
|
||||
closure, gcsafe, raises: [Defect, CatchableError, Exception].} =
|
||||
block:
|
||||
template result(): auto {.used.} =
|
||||
{.fatal: "You should not reference the `result` variable inside" &
|
||||
" a void async proc".}
|
||||
|
||||
let item = default(SyncResult[T])
|
||||
for blk in sq.blocks(item):
|
||||
let res = await sq.blockVerifier(blk[])
|
||||
|
||||
var resultFuture = newFuture[void]("push")
|
||||
resultFuture.closure = push_436208182
|
||||
return resultFuture
|
||||
|
||||
type
|
||||
SomeTPeer = ref object
|
||||
score: int
|
||||
|
||||
proc getSlice(): seq[ref int] =
|
||||
discard
|
||||
|
||||
template smokeTest(kkind: SyncQueueKind, start, finish: uint64,
|
||||
chunkSize: uint64) =
|
||||
var queue: SyncQueue[SomeTPeer]
|
||||
var request: SyncRequest[SomeTPeer]
|
||||
discard queue.push(request, getSlice())
|
||||
|
||||
for k in {SyncQueueKind.Forward}:
|
||||
for item in [(uint64(1181), uint64(1399), 41'u64)]:
|
||||
smokeTest(k, item[0], item[1], item[2])
|
||||
|
|
@ -559,38 +559,6 @@ template main {.dirty.} =
|
|||
let x = default(Default)
|
||||
doAssert x.data is DjangoDateTime
|
||||
|
||||
block:
|
||||
type
|
||||
Result2 = object
|
||||
case o: bool
|
||||
of false:
|
||||
e: float
|
||||
of true:
|
||||
v {.requiresInit.} : int = 1
|
||||
|
||||
proc startSessionSync(): Result2 =
|
||||
return Result2(o: true)
|
||||
|
||||
proc mainSync =
|
||||
let ff = startSessionSync()
|
||||
doAssert ff.v == 1
|
||||
|
||||
mainSync()
|
||||
|
||||
block:
|
||||
type
|
||||
Result2 = object
|
||||
v {.requiresInit.} : int = 1
|
||||
|
||||
proc startSessionSync(): Result2 =
|
||||
return Result2()
|
||||
|
||||
proc mainSync =
|
||||
let ff = startSessionSync()
|
||||
doAssert ff.v == 1
|
||||
|
||||
mainSync()
|
||||
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -311,11 +311,3 @@ block: # bug #9607
|
|||
|
||||
doAssert echoL() == "bar"
|
||||
doAssert echoM() == "bar"
|
||||
|
||||
block:
|
||||
macro hello[T](x: T): untyped =
|
||||
result = quote do:
|
||||
let m: `T` = `x`
|
||||
discard m
|
||||
|
||||
hello(12)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ discard """
|
|||
x + y = 30
|
||||
'''
|
||||
"""
|
||||
import std/[sugar, algorithm, random, sets, tables, strutils, sequtils]
|
||||
import std/[sugar, algorithm, random, sets, tables, strutils]
|
||||
import std/[syncio, assertions]
|
||||
|
||||
type # for capture test, ref #20679
|
||||
|
|
@ -287,17 +287,6 @@ proc mainProc() =
|
|||
doAssertRaises(AssertionDefect): doAssert false
|
||||
doAssert "except AssertionDefect" in s2
|
||||
|
||||
block: # bug #20704
|
||||
proc test() =
|
||||
var xs, ys: seq[int]
|
||||
for i in 0..5:
|
||||
xs.add(i)
|
||||
|
||||
xs.apply(d => ys.add(d))
|
||||
doAssert ys == @[0, 1, 2, 3, 4, 5]
|
||||
|
||||
test()
|
||||
|
||||
static:
|
||||
main()
|
||||
mainProc()
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ block: # bug #11777
|
|||
var s: S = {1, 2}
|
||||
doAssert 1 in s
|
||||
|
||||
block: # bug #20807
|
||||
block: # regression #20807
|
||||
var s: seq[string]
|
||||
template fail =
|
||||
s = @[]
|
||||
|
|
@ -255,38 +255,3 @@ block: # bug #20807
|
|||
test: fail()
|
||||
doAssert not (compiles do:
|
||||
let x: seq[int] = `@`[string]([]))
|
||||
|
||||
block: # bug #21377
|
||||
proc b[T](v: T): seq[int] =
|
||||
let x = 0
|
||||
@[]
|
||||
|
||||
doAssert b(0) == @[]
|
||||
|
||||
block: # bug #21377
|
||||
proc b[T](v: T): seq[T] =
|
||||
let x = 0
|
||||
@[]
|
||||
|
||||
doAssert b(0) == @[]
|
||||
|
||||
block: # bug #21377
|
||||
proc b[T](v: T): set[bool] =
|
||||
let x = 0
|
||||
{}
|
||||
|
||||
doAssert b(0) == {}
|
||||
|
||||
block: # bug #21377
|
||||
proc b[T](v: T): array[0, int] =
|
||||
let x = 0
|
||||
[]
|
||||
|
||||
doAssert b(0) == []
|
||||
|
||||
block: # bug #21377
|
||||
proc b[T](v: T): array[0, (string, string)] =
|
||||
let x = 0
|
||||
{:}
|
||||
|
||||
doAssert b(0) == {:}
|
||||
|
|
|
|||
|
|
@ -643,16 +643,3 @@ const b = block:
|
|||
|
||||
doAssert a == @[@[0, 1, 2], @[0, 1, 2], @[0, 1, 2]]
|
||||
doAssert b == @[@[0, 1, 2], @[0, 1, 2], @[0, 1, 2]]
|
||||
|
||||
macro m1(s: string): int =
|
||||
var ProcID {.global, compileTime.}: int
|
||||
inc(ProcID)
|
||||
result = newLit(ProcID)
|
||||
|
||||
proc macroGlobal =
|
||||
doAssert m1("Macro argument") == 1
|
||||
doAssert m1("Macro argument") == 2
|
||||
doAssert m1("Macro argument") == 3
|
||||
|
||||
static: macroGlobal()
|
||||
macroGlobal()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue