mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
type refactor: part 4 (#23077)
This commit is contained in:
@@ -59,8 +59,8 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
|
||||
of tySet, tyArray:
|
||||
result = isPartOfAux(a.elementType, b, marker)
|
||||
of tyTuple:
|
||||
for i in 0..<a.len:
|
||||
result = isPartOfAux(a[i], b, marker)
|
||||
for aa in a.kids:
|
||||
result = isPartOfAux(aa, b, marker)
|
||||
if result == arYes: return
|
||||
else: discard
|
||||
|
||||
|
||||
@@ -1593,12 +1593,15 @@ iterator tupleTypePairs*(a, b: PType): (int, PType, PType) =
|
||||
|
||||
iterator underspecifiedPairs*(a, b: PType; start = 0; without = 0): (PType, PType) =
|
||||
# XXX Figure out with what typekinds this is called.
|
||||
for i in start ..< a.sons.len + without:
|
||||
for i in start ..< min(a.sons.len, b.sons.len) + without:
|
||||
yield (a.sons[i], b.sons[i])
|
||||
|
||||
proc signatureLen*(t: PType): int {.inline.} =
|
||||
result = t.sons.len
|
||||
|
||||
proc paramsLen*(t: PType): int {.inline.} =
|
||||
result = t.sons.len - 1
|
||||
|
||||
proc kidsLen*(t: PType): int {.inline.} =
|
||||
result = t.sons.len
|
||||
|
||||
@@ -1629,10 +1632,14 @@ iterator ikids*(t: PType): (int, PType) =
|
||||
|
||||
const
|
||||
FirstParamAt* = 1
|
||||
FirstGenericParamAt* = 1
|
||||
|
||||
iterator paramTypes*(t: PType): (int, PType) =
|
||||
for i in FirstParamAt..<t.sons.len: yield (i, t.sons[i])
|
||||
|
||||
iterator paramTypePairs*(a, b: PType): (PType, PType) =
|
||||
for i in FirstParamAt..<a.sons.len: yield (a.sons[i], b.sons[i])
|
||||
|
||||
template paramTypeToNodeIndex*(x: int): int = x
|
||||
|
||||
iterator kids*(t: PType): PType =
|
||||
|
||||
@@ -394,7 +394,7 @@ proc genParams(p: BProc, ri: PNode, typ: PType; result: var Rope) =
|
||||
|
||||
var oldLen = result.len
|
||||
for i in 1..<ri.len:
|
||||
if i < typ.len:
|
||||
if i < typ.n.len:
|
||||
assert(typ.n[i].kind == nkSym)
|
||||
let paramType = typ.n[i]
|
||||
if not paramType.typ.isCompileTimeOnly:
|
||||
@@ -419,7 +419,6 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||
# getUniqueType() is too expensive here:
|
||||
var typ = skipTypes(ri[0].typ, abstractInstOwned)
|
||||
assert(typ.kind == tyProc)
|
||||
assert(typ.len == typ.n.len)
|
||||
|
||||
var params = newRopeAppender()
|
||||
genParams(p, ri, typ, params)
|
||||
@@ -442,7 +441,6 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||
# getUniqueType() is too expensive here:
|
||||
var typ = skipTypes(ri[0].typ, abstractInstOwned)
|
||||
assert(typ.kind == tyProc)
|
||||
assert(typ.len == typ.n.len)
|
||||
|
||||
var pl = newRopeAppender()
|
||||
genParams(p, ri, typ, pl)
|
||||
@@ -502,14 +500,14 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||
|
||||
proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType; result: var Rope;
|
||||
argsCounter: var int) =
|
||||
if i < typ.len:
|
||||
if i < typ.n.len:
|
||||
# 'var T' is 'T&' in C++. This means we ignore the request of
|
||||
# any nkHiddenAddr when it's a 'var T'.
|
||||
let paramType = typ.n[i]
|
||||
assert(paramType.kind == nkSym)
|
||||
if paramType.typ.isCompileTimeOnly:
|
||||
discard
|
||||
elif typ[i].kind in {tyVar} and ri[i].kind == nkHiddenAddr:
|
||||
elif paramType.typ.kind in {tyVar} and ri[i].kind == nkHiddenAddr:
|
||||
if argsCounter > 0: result.add ", "
|
||||
genArgNoParam(p, ri[i][0], result)
|
||||
inc argsCounter
|
||||
@@ -584,7 +582,7 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType; result: var Rope) =
|
||||
# for better or worse c2nim translates the 'this' argument to a 'var T'.
|
||||
# However manual wrappers may also use 'ptr T'. In any case we support both
|
||||
# for convenience.
|
||||
internalAssert p.config, i < typ.len
|
||||
internalAssert p.config, i < typ.n.len
|
||||
assert(typ.n[i].kind == nkSym)
|
||||
# if the parameter is lying (tyVar) and thus we required an additional deref,
|
||||
# skip the deref:
|
||||
@@ -674,7 +672,6 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||
# getUniqueType() is too expensive here:
|
||||
var typ = skipTypes(ri[0].typ, abstractInst)
|
||||
assert(typ.kind == tyProc)
|
||||
assert(typ.len == typ.n.len)
|
||||
# don't call '$' here for efficiency:
|
||||
let pat = $ri[0].sym.loc.r
|
||||
internalAssert p.config, pat.len > 0
|
||||
@@ -708,7 +705,6 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||
pl.add(op.r)
|
||||
var params = newRopeAppender()
|
||||
for i in 2..<ri.len:
|
||||
assert(typ.len == typ.n.len)
|
||||
genOtherArg(p, ri, i, typ, params, argsCounter)
|
||||
fixupCall(p, le, ri, d, pl, params)
|
||||
|
||||
@@ -719,7 +715,6 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
|
||||
# getUniqueType() is too expensive here:
|
||||
var typ = skipTypes(ri[0].typ, abstractInst)
|
||||
assert(typ.kind == tyProc)
|
||||
assert(typ.len == typ.n.len)
|
||||
|
||||
# don't call '$' here for efficiency:
|
||||
let pat = $ri[0].sym.loc.r
|
||||
@@ -741,8 +736,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
|
||||
pl.add(": ")
|
||||
genArg(p, ri[2], typ.n[2].sym, ri, pl)
|
||||
for i in start..<ri.len:
|
||||
assert(typ.len == typ.n.len)
|
||||
if i >= typ.len:
|
||||
if i >= typ.n.len:
|
||||
internalError(p.config, ri.info, "varargs for objective C method?")
|
||||
assert(typ.n[i].kind == nkSym)
|
||||
var param = typ.n[i].sym
|
||||
|
||||
@@ -236,8 +236,7 @@ proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
else:
|
||||
flags
|
||||
let t = skipTypes(dest.t, abstractInst).getUniqueType()
|
||||
for i in 0..<t.len:
|
||||
let t = t[i]
|
||||
for i, t in t.ikids:
|
||||
let field = "Field$1" % [i.rope]
|
||||
genAssignment(p, optAsgnLoc(dest, t, field),
|
||||
optAsgnLoc(src, t, field), newflags)
|
||||
@@ -362,7 +361,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||
of tyTuple:
|
||||
if containsGarbageCollectedRef(dest.t):
|
||||
if dest.t.len <= 4: genOptAsgnTuple(p, dest, src, flags)
|
||||
if dest.t.kidsLen <= 4: genOptAsgnTuple(p, dest, src, flags)
|
||||
else: genGenericAsgn(p, dest, src, flags)
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||
@@ -3193,11 +3192,11 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo; result: var Rope) =
|
||||
result.add "}"
|
||||
of tyTuple:
|
||||
result.add "{"
|
||||
if p.vccAndC and t.len == 0:
|
||||
if p.vccAndC and t.isEmptyTupleType:
|
||||
result.add "0"
|
||||
for i in 0..<t.len:
|
||||
for i, a in t.ikids:
|
||||
if i > 0: result.add ", "
|
||||
getDefaultValue(p, t[i], info, result)
|
||||
getDefaultValue(p, a, info, result)
|
||||
result.add "}"
|
||||
of tyArray:
|
||||
result.add "{"
|
||||
|
||||
@@ -63,15 +63,14 @@ proc specializeResetT(p: BProc, accessor: Rope, typ: PType) =
|
||||
specializeResetT(p, ropecg(p.module, "$1[$2]", [accessor, i.r]), typ.elementType)
|
||||
lineF(p, cpsStmts, "}$n", [])
|
||||
of tyObject:
|
||||
for i in 0..<typ.len:
|
||||
var x = typ[i]
|
||||
if x != nil: x = x.skipTypes(skipPtrs)
|
||||
specializeResetT(p, accessor.parentObj(p.module), x)
|
||||
var x = typ.baseClass
|
||||
if x != nil: x = x.skipTypes(skipPtrs)
|
||||
specializeResetT(p, accessor.parentObj(p.module), x)
|
||||
if typ.n != nil: specializeResetN(p, accessor, typ.n, typ)
|
||||
of tyTuple:
|
||||
let typ = getUniqueType(typ)
|
||||
for i in 0..<typ.len:
|
||||
specializeResetT(p, ropecg(p.module, "$1.Field$2", [accessor, i]), typ[i])
|
||||
for i, a in typ.ikids:
|
||||
specializeResetT(p, ropecg(p.module, "$1.Field$2", [accessor, i]), a)
|
||||
|
||||
of tyString, tyRef, tySequence:
|
||||
lineCg(p, cpsStmts, "#unsureAsgnRef((void**)&$1, NIM_NIL);$n", [accessor])
|
||||
|
||||
@@ -289,13 +289,12 @@ proc potentialValueInit(p: BProc; v: PSym; value: PNode; result: var Rope) =
|
||||
#echo "New code produced for ", v.name.s, " ", p.config $ value.info
|
||||
genBracedInit(p, value, isConst = false, v.typ, result)
|
||||
|
||||
proc genCppParamsForCtor(p: BProc; call: PNode): string =
|
||||
proc genCppParamsForCtor(p: BProc; call: PNode): string =
|
||||
result = ""
|
||||
var argsCounter = 0
|
||||
let typ = skipTypes(call[0].typ, abstractInst)
|
||||
assert(typ.kind == tyProc)
|
||||
for i in 1..<call.len:
|
||||
assert(typ.len == typ.n.len)
|
||||
#if it's a type we can just generate here another initializer as we are in an initializer context
|
||||
if call[i].kind == nkCall and call[i][0].kind == nkSym and call[i][0].sym.kind == skType:
|
||||
if argsCounter > 0: result.add ","
|
||||
|
||||
@@ -87,15 +87,14 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) =
|
||||
else:
|
||||
lineF(p, cpsStmts, "}$n", [])
|
||||
of tyObject:
|
||||
for i in 0..<typ.len:
|
||||
var x = typ[i]
|
||||
if x != nil: x = x.skipTypes(skipPtrs)
|
||||
genTraverseProc(c, accessor.parentObj(c.p.module), x)
|
||||
var x = typ.baseClass
|
||||
if x != nil: x = x.skipTypes(skipPtrs)
|
||||
genTraverseProc(c, accessor.parentObj(c.p.module), x)
|
||||
if typ.n != nil: genTraverseProc(c, accessor, typ.n, typ)
|
||||
of tyTuple:
|
||||
let typ = getUniqueType(typ)
|
||||
for i in 0..<typ.len:
|
||||
genTraverseProc(c, ropecg(c.p.module, "$1.Field$2", [accessor, i]), typ[i])
|
||||
for i, a in typ.ikids:
|
||||
genTraverseProc(c, ropecg(c.p.module, "$1.Field$2", [accessor, i]), a)
|
||||
of tyRef:
|
||||
lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt])
|
||||
of tySequence:
|
||||
@@ -118,10 +117,10 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) =
|
||||
proc genTraverseProcSeq(c: TTraversalClosure, accessor: Rope, typ: PType) =
|
||||
var p = c.p
|
||||
assert typ.kind == tySequence
|
||||
var i: TLoc = getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo, tyInt))
|
||||
var i = getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo, tyInt))
|
||||
var oldCode = p.s(cpsStmts)
|
||||
freeze oldCode
|
||||
var a: TLoc = TLoc(r: accessor)
|
||||
var a = TLoc(r: accessor)
|
||||
|
||||
lineF(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
|
||||
[i.r, lenExpr(c.p, a)])
|
||||
|
||||
@@ -826,7 +826,7 @@ proc getRecordDesc(m: BModule; typ: PType, name: Rope,
|
||||
if not hasField and typ.itemId notin m.g.graph.memberProcsPerType:
|
||||
if desc == "":
|
||||
result.add("\tchar dummy;\n")
|
||||
elif typ.len == 1 and typ.n[0].kind == nkSym:
|
||||
elif typ.n.len == 1 and typ.n[0].kind == nkSym:
|
||||
let field = typ.n[0].sym
|
||||
let fieldType = field.typ.skipTypes(abstractInst)
|
||||
if fieldType.kind == tyUncheckedArray:
|
||||
@@ -845,9 +845,9 @@ proc getTupleDesc(m: BModule; typ: PType, name: Rope,
|
||||
check: var IntSet): Rope =
|
||||
result = "$1 $2 {$n" % [structOrUnion(typ), name]
|
||||
var desc: Rope = ""
|
||||
for i in 0..<typ.len:
|
||||
for i, a in typ.ikids:
|
||||
desc.addf("$1 Field$2;$n",
|
||||
[getTypeDescAux(m, typ[i], check, dkField), rope(i)])
|
||||
[getTypeDescAux(m, a, check, dkField), rope(i)])
|
||||
if desc == "": result.add("char dummy;\L")
|
||||
else: result.add(desc)
|
||||
result.add("};\L")
|
||||
@@ -872,13 +872,13 @@ proc scanCppGenericSlot(pat: string, cursor, outIdx, outStars: var int): bool =
|
||||
proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
|
||||
# Make sure the index refers to one of the generic params of the type.
|
||||
# XXX: we should catch this earlier and report it as a semantic error.
|
||||
if idx >= typ.len:
|
||||
if idx >= typ.kidsLen:
|
||||
raiseAssert "invalid apostrophe type parameter index"
|
||||
|
||||
result = typ[idx]
|
||||
for i in 1..stars:
|
||||
if result != nil and result.len > 0:
|
||||
result = if result.kind == tyGenericInst: result[1]
|
||||
if result != nil and result.kidsLen > 0:
|
||||
result = if result.kind == tyGenericInst: result[FirstGenericParamAt]
|
||||
else: result.elemType
|
||||
|
||||
proc getOpenArrayDesc(m: BModule; t: PType, check: var IntSet; kind: TypeDescKind): Rope =
|
||||
@@ -1079,9 +1079,9 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes
|
||||
result.add cppName.substr(chunkStart)
|
||||
else:
|
||||
result = cppNameAsRope & "<"
|
||||
for i in 1..<tt.len-1:
|
||||
if i > 1: result.add(" COMMA ")
|
||||
addResultType(tt[i])
|
||||
for needsComma, a in tt.genericInstParams:
|
||||
if needsComma: result.add(" COMMA ")
|
||||
addResultType(a)
|
||||
result.add("> ")
|
||||
# always call for sideeffects:
|
||||
assert t.kind != tyTuple
|
||||
@@ -1333,7 +1333,7 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType;
|
||||
proc genTypeInfoAux(m: BModule; typ, origType: PType, name: Rope;
|
||||
info: TLineInfo) =
|
||||
var base: Rope
|
||||
if typ.len > 0 and typ.last != nil:
|
||||
if typ.hasElementType and typ.last != nil:
|
||||
var x = typ.last
|
||||
if typ.kind == tyObject: x = x.skipTypes(skipPtrs)
|
||||
if typ.kind == tyPtr and x.kind == tyObject and incompleteType(x):
|
||||
@@ -1457,11 +1457,10 @@ proc genObjectInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo
|
||||
proc genTupleInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo) =
|
||||
genTypeInfoAuxBase(m, typ, typ, name, rope("0"), info)
|
||||
var expr = getNimNode(m)
|
||||
if typ.len > 0:
|
||||
var tmp = getTempName(m) & "_" & $typ.len
|
||||
genTNimNodeArray(m, tmp, rope(typ.len))
|
||||
for i in 0..<typ.len:
|
||||
var a = typ[i]
|
||||
if not typ.isEmptyTupleType:
|
||||
var tmp = getTempName(m) & "_" & $typ.kidsLen
|
||||
genTNimNodeArray(m, tmp, rope(typ.kidsLen))
|
||||
for i, a in typ.ikids:
|
||||
var tmp2 = getNimNode(m)
|
||||
m.s[cfsTypeInit3].addf("$1[$2] = &$3;$n", [tmp, rope(i), tmp2])
|
||||
m.s[cfsTypeInit3].addf("$1.kind = 1;$n" &
|
||||
@@ -1470,10 +1469,10 @@ proc genTupleInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo)
|
||||
"$1.name = \"Field$3\";$n",
|
||||
[tmp2, getTypeDesc(m, origType, dkVar), rope(i), genTypeInfoV1(m, a, info)])
|
||||
m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
|
||||
[expr, rope(typ.len), tmp])
|
||||
[expr, rope(typ.kidsLen), tmp])
|
||||
else:
|
||||
m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2;$n",
|
||||
[expr, rope(typ.len)])
|
||||
[expr, rope(typ.kidsLen)])
|
||||
m.s[cfsTypeInit3].addf("$1.node = &$2;$n", [tiNameForHcr(m, name), expr])
|
||||
|
||||
proc genEnumInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) =
|
||||
@@ -1729,7 +1728,7 @@ proc genTypeInfoV2OldImpl(m: BModule; t, origType: PType, name: Rope; info: TLin
|
||||
|
||||
m.s[cfsTypeInit3].add typeEntry
|
||||
|
||||
if t.kind == tyObject and t.len > 0 and t.baseClass != nil and optEnableDeepCopy in m.config.globalOptions:
|
||||
if t.kind == tyObject and t.baseClass != nil and optEnableDeepCopy in m.config.globalOptions:
|
||||
discard genTypeInfoV1(m, t, info)
|
||||
|
||||
proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineInfo) =
|
||||
@@ -1779,7 +1778,7 @@ proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineIn
|
||||
addf(typeEntry, ", .flags = $1};$n", [rope(flags)])
|
||||
m.s[cfsVars].add typeEntry
|
||||
|
||||
if t.kind == tyObject and t.len > 0 and t.baseClass != nil and optEnableDeepCopy in m.config.globalOptions:
|
||||
if t.kind == tyObject and t.baseClass != nil and optEnableDeepCopy in m.config.globalOptions:
|
||||
discard genTypeInfoV1(m, t, info)
|
||||
|
||||
proc genTypeInfoV2(m: BModule; t: PType; info: TLineInfo): Rope =
|
||||
|
||||
@@ -69,12 +69,14 @@ type
|
||||
proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
|
||||
result = No
|
||||
if a.name.id != b.name.id: return
|
||||
if a.typ.len != b.typ.len:
|
||||
if a.typ.signatureLen != b.typ.signatureLen:
|
||||
return
|
||||
|
||||
for i in 1..<a.typ.len:
|
||||
var aa = a.typ[i]
|
||||
var bb = b.typ[i]
|
||||
var i = 0
|
||||
for x, y in paramTypePairs(a.typ, b.typ):
|
||||
inc i
|
||||
var aa = x
|
||||
var bb = y
|
||||
while true:
|
||||
aa = skipTypes(aa, {tyGenericInst, tyAlias})
|
||||
bb = skipTypes(bb, {tyGenericInst, tyAlias})
|
||||
@@ -83,7 +85,7 @@ proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
|
||||
bb = bb.elementType
|
||||
else:
|
||||
break
|
||||
if sameType(a.typ[i], b.typ[i]):
|
||||
if sameType(x, y):
|
||||
if aa.kind == tyObject and result != Invalid:
|
||||
result = Yes
|
||||
elif aa.kind == tyObject and bb.kind == tyObject and (i == 1 or multiMethods):
|
||||
@@ -204,7 +206,7 @@ proc relevantCol*(methods: seq[PSym], col: int): bool =
|
||||
|
||||
proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int =
|
||||
result = 0
|
||||
for col in 1..<a.typ.len:
|
||||
for col in FirstParamAt..<a.typ.signatureLen:
|
||||
if contains(relevantCols, col):
|
||||
var aa = skipTypes(a.typ[col], skipPtrs)
|
||||
var bb = skipTypes(b.typ[col], skipPtrs)
|
||||
@@ -234,13 +236,13 @@ proc sortBucket*(a: var seq[PSym], relevantCols: IntSet) =
|
||||
proc genIfDispatcher*(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet; idgen: IdGenerator): PSym =
|
||||
var base = methods[0].ast[dispatcherPos].sym
|
||||
result = base
|
||||
var paramLen = base.typ.len
|
||||
var paramLen = base.typ.signatureLen
|
||||
var nilchecks = newNodeI(nkStmtList, base.info)
|
||||
var disp = newNodeI(nkIfStmt, base.info)
|
||||
var ands = getSysMagic(g, unknownLineInfo, "and", mAnd)
|
||||
var iss = getSysMagic(g, unknownLineInfo, "of", mOf)
|
||||
let boolType = getSysType(g, unknownLineInfo, tyBool)
|
||||
for col in 1..<paramLen:
|
||||
for col in FirstParamAt..<paramLen:
|
||||
if contains(relevantCols, col):
|
||||
let param = base.typ.n[col].sym
|
||||
if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
|
||||
@@ -249,7 +251,7 @@ proc genIfDispatcher*(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet;
|
||||
for meth in 0..high(methods):
|
||||
var curr = methods[meth] # generate condition:
|
||||
var cond: PNode = nil
|
||||
for col in 1..<paramLen:
|
||||
for col in FirstParamAt..<paramLen:
|
||||
if contains(relevantCols, col):
|
||||
var isn = newNodeIT(nkCall, base.info, boolType)
|
||||
isn.add newSymNode(iss)
|
||||
@@ -293,7 +295,7 @@ proc genIfDispatcher*(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet;
|
||||
proc generateIfMethodDispatchers*(g: ModuleGraph, idgen: IdGenerator) =
|
||||
for bucket in 0..<g.methods.len:
|
||||
var relevantCols = initIntSet()
|
||||
for col in 1..<g.methods[bucket].methods[0].typ.len:
|
||||
for col in FirstParamAt..<g.methods[bucket].methods[0].typ.signatureLen:
|
||||
if relevantCol(g.methods[bucket].methods, col): incl(relevantCols, col)
|
||||
if optMultiMethods notin g.config.globalOptions:
|
||||
# if multi-methods are not enabled, we are interested only in the first field
|
||||
|
||||
@@ -105,18 +105,19 @@ proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool =
|
||||
#m.inferred.setLen oldLen
|
||||
#echo "A for ", result, " to ", typeToString(a), " to ", typeToString(m.potentialImplementation)
|
||||
else:
|
||||
if a.kind == tyTypeDesc and f.len == a.len:
|
||||
for i in 0..<a.len:
|
||||
if not matchType(c, f[i], a[i], m): return false
|
||||
return true
|
||||
if a.kind == tyTypeDesc and f.hasElementType == a.hasElementType:
|
||||
if f.hasElementType:
|
||||
result = matchType(c, f.elementType, a.elementType, m)
|
||||
else:
|
||||
result = true # both lack it
|
||||
else:
|
||||
result = false
|
||||
|
||||
of tyGenericInvocation:
|
||||
result = false
|
||||
if a.kind == tyGenericInst and a[0].kind == tyGenericBody:
|
||||
if sameType(f[0], a[0]) and f.len == a.len-1:
|
||||
for i in 1 ..< f.len:
|
||||
if a.kind == tyGenericInst and a.genericHead.kind == tyGenericBody:
|
||||
if sameType(f.genericHead, a.genericHead) and f.kidsLen == a.kidsLen-1:
|
||||
for i in FirstGenericParamAt ..< f.kidsLen:
|
||||
if not matchType(c, f[i], a[i], m): return false
|
||||
return true
|
||||
of tyGenericParam:
|
||||
@@ -126,10 +127,10 @@ proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool =
|
||||
else:
|
||||
let old = existingBinding(m, f)
|
||||
if old == nil:
|
||||
if f.len > 0 and f[0].kind != tyNone:
|
||||
if f.hasElementType and f.elementType.kind != tyNone:
|
||||
# also check the generic's constraints:
|
||||
let oldLen = m.inferred.len
|
||||
result = matchType(c, f[0], a, m)
|
||||
result = matchType(c, f.elementType, a, m)
|
||||
m.inferred.setLen oldLen
|
||||
if result:
|
||||
when logBindings: echo "A adding ", f, " ", ak
|
||||
@@ -155,9 +156,9 @@ proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool =
|
||||
# modifiers in the concept must be there in the actual implementation
|
||||
# too but not vice versa.
|
||||
if a.kind == f.kind:
|
||||
result = matchType(c, f[0], a[0], m)
|
||||
result = matchType(c, f.elementType, a.elementType, m)
|
||||
elif m.magic == mArrPut:
|
||||
result = matchType(c, f[0], a, m)
|
||||
result = matchType(c, f.elementType, a, m)
|
||||
else:
|
||||
result = false
|
||||
of tyEnum, tyObject, tyDistinct:
|
||||
@@ -167,7 +168,7 @@ proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool =
|
||||
of tyBool, tyChar, tyInt..tyUInt64:
|
||||
let ak = a.skipTypes(ignorableForArgType)
|
||||
result = ak.kind == f.kind or ak.kind == tyOrdinal or
|
||||
(ak.kind == tyGenericParam and ak.len > 0 and ak[0].kind == tyOrdinal)
|
||||
(ak.kind == tyGenericParam and ak.hasElementType and ak.elementType.kind == tyOrdinal)
|
||||
of tyConcept:
|
||||
let oldLen = m.inferred.len
|
||||
let oldPotentialImplementation = m.potentialImplementation
|
||||
@@ -178,10 +179,11 @@ proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool =
|
||||
m.inferred.setLen oldLen
|
||||
of tyArray, tyTuple, tyVarargs, tyOpenArray, tyRange, tySequence, tyRef, tyPtr,
|
||||
tyGenericInst:
|
||||
# ^ XXX Rewrite this logic, it's more complex than it needs to be.
|
||||
result = false
|
||||
let ak = a.skipTypes(ignorableForArgType - {f.kind})
|
||||
if ak.kind == f.kind and f.len == ak.len:
|
||||
for i in 0..<ak.len:
|
||||
if ak.kind == f.kind and f.kidsLen == ak.kidsLen:
|
||||
for i in 0..<ak.kidsLen:
|
||||
if not matchType(c, f[i], ak[i], m): return false
|
||||
return true
|
||||
of tyOr:
|
||||
@@ -190,30 +192,30 @@ proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool =
|
||||
# say the concept requires 'int|float|string' if the potentialImplementation
|
||||
# says 'int|string' that is good enough.
|
||||
var covered = 0
|
||||
for i in 0..<f.len:
|
||||
for j in 0..<a.len:
|
||||
for ff in f.kids:
|
||||
for aa in a.kids:
|
||||
let oldLenB = m.inferred.len
|
||||
let r = matchType(c, f[i], a[j], m)
|
||||
let r = matchType(c, ff, aa, m)
|
||||
if r:
|
||||
inc covered
|
||||
break
|
||||
m.inferred.setLen oldLenB
|
||||
|
||||
result = covered >= a.len
|
||||
result = covered >= a.kidsLen
|
||||
if not result:
|
||||
m.inferred.setLen oldLen
|
||||
else:
|
||||
result = false
|
||||
for i in 0..<f.len:
|
||||
result = matchType(c, f[i], a, m)
|
||||
for ff in f.kids:
|
||||
result = matchType(c, ff, a, m)
|
||||
if result: break # and remember the binding!
|
||||
m.inferred.setLen oldLen
|
||||
of tyNot:
|
||||
if a.kind == tyNot:
|
||||
result = matchType(c, f[0], a[0], m)
|
||||
result = matchType(c, f.elementType, a.elementType, m)
|
||||
else:
|
||||
let oldLen = m.inferred.len
|
||||
result = not matchType(c, f[0], a, m)
|
||||
result = not matchType(c, f.elementType, a, m)
|
||||
m.inferred.setLen oldLen
|
||||
of tyAnything:
|
||||
result = true
|
||||
@@ -334,8 +336,8 @@ proc conceptMatch*(c: PContext; concpt, arg: PType; bindings: var TIdTable; invo
|
||||
# we have a match, so bind 'arg' itself to 'concpt':
|
||||
bindings.idTablePut(concpt, arg)
|
||||
# invocation != nil means we have a non-atomic concept:
|
||||
if invocation != nil and arg.kind == tyGenericInst and invocation.len == arg.len-1:
|
||||
if invocation != nil and arg.kind == tyGenericInst and invocation.kidsLen == arg.kidsLen-1:
|
||||
# bind even more generic parameters
|
||||
assert invocation.kind == tyGenericInvocation
|
||||
for i in 1 ..< invocation.len:
|
||||
for i in FirstGenericParamAt ..< invocation.kidsLen:
|
||||
bindings.idTablePut(invocation[i], arg[i])
|
||||
|
||||
@@ -380,7 +380,7 @@ proc genCall(c: var Con; n: PNode) =
|
||||
if t != nil: t = t.skipTypes(abstractInst)
|
||||
for i in 1..<n.len:
|
||||
gen(c, n[i])
|
||||
if t != nil and i < t.len and isOutParam(t[i]):
|
||||
if t != nil and i < t.signatureLen and isOutParam(t[i]):
|
||||
# Pass by 'out' is a 'must def'. Good enough for a move optimizer.
|
||||
genDef(c, n[i])
|
||||
# every call can potentially raise:
|
||||
|
||||
@@ -44,7 +44,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
|
||||
handleParam actual[s.position]
|
||||
elif (s.owner != nil) and (s.kind == skGenericParam or
|
||||
s.kind == skType and s.typ != nil and s.typ.kind == tyGenericParam):
|
||||
handleParam actual[s.owner.typ.len + s.position - 1]
|
||||
handleParam actual[s.owner.typ.signatureLen + s.position - 1]
|
||||
else:
|
||||
internalAssert c.config, sfGenSym in s.flags or s.kind == skType
|
||||
var x = PSym(idTableGet(c.mapping, s))
|
||||
@@ -116,7 +116,7 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode
|
||||
# now that we have working untyped parameters.
|
||||
genericParams = if fromHlo: 0
|
||||
else: s.ast[genericParamsPos].len
|
||||
expectedRegularParams = s.typ.len-1
|
||||
expectedRegularParams = s.typ.paramsLen
|
||||
givenRegularParams = totalParams - genericParams
|
||||
if givenRegularParams < 0: givenRegularParams = 0
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ proc expandDefault(t: PType; info: TLineInfo): PNode =
|
||||
of tySink, tyGenericInst, tyDistinct, tyAlias, tyOwned:
|
||||
result = expandDefault(t.skipModifier, info)
|
||||
of tyOrdinal, tyGenericBody, tyGenericParam, tyInferred, tyStatic:
|
||||
if t.len > 0:
|
||||
if t.hasElementType:
|
||||
result = expandDefault(t.skipModifier, info)
|
||||
else:
|
||||
result = newZero(t, info, nkEmpty)
|
||||
|
||||
@@ -221,7 +221,7 @@ proc makePtrType(c: var Con, baseType: PType): PType =
|
||||
|
||||
proc genOp(c: var Con; op: PSym; dest: PNode): PNode =
|
||||
var addrExp: PNode
|
||||
if op.typ != nil and op.typ.len > 1 and op.typ.firstParamType.kind != tyVar:
|
||||
if op.typ != nil and op.typ.signatureLen > 1 and op.typ.firstParamType.kind != tyVar:
|
||||
addrExp = dest
|
||||
else:
|
||||
addrExp = newNodeIT(nkHiddenAddr, dest.info, makePtrType(c, dest.typ))
|
||||
@@ -877,7 +877,7 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSing
|
||||
c.inSpawn.dec
|
||||
|
||||
let parameters = n[0].typ
|
||||
let L = if parameters != nil: parameters.len else: 0
|
||||
let L = if parameters != nil: parameters.signatureLen else: 0
|
||||
|
||||
when false:
|
||||
var isDangerous = false
|
||||
|
||||
@@ -56,10 +56,10 @@ proc destructorOverridden(g: ModuleGraph; t: PType): bool =
|
||||
op != nil and sfOverridden in op.flags
|
||||
|
||||
proc fillBodyTup(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
for i in 0..<t.len:
|
||||
for i, a in t.ikids:
|
||||
let lit = lowerings.newIntLit(c.g, x.info, i)
|
||||
let b = if c.kind == attachedTrace: y else: y.at(lit, t[i])
|
||||
fillBody(c, t[i], body, x.at(lit, t[i]), b)
|
||||
let b = if c.kind == attachedTrace: y else: y.at(lit, a)
|
||||
fillBody(c, a, body, x.at(lit, a), b)
|
||||
|
||||
proc dotField(x: PNode, f: PSym): PNode =
|
||||
result = newNodeI(nkDotExpr, x.info, 2)
|
||||
@@ -221,15 +221,15 @@ proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode; enforceDefaultOp: bool)
|
||||
illFormedAstLocal(n, c.g.config)
|
||||
|
||||
proc fillBodyObjTImpl(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||
if t.len > 0 and t.baseClass != nil:
|
||||
if t.baseClass != nil:
|
||||
fillBody(c, skipTypes(t.baseClass, abstractPtrs), body, x, y)
|
||||
fillBodyObj(c, t.n, body, x, y, enforceDefaultOp = false)
|
||||
|
||||
proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||
var hasCase = isCaseObj(t.n)
|
||||
var obj = t
|
||||
while obj.len > 0 and obj[0] != nil:
|
||||
obj = skipTypes(obj[0], abstractPtrs)
|
||||
while obj.baseClass != nil:
|
||||
obj = skipTypes(obj.baseClass, abstractPtrs)
|
||||
hasCase = hasCase or isCaseObj(obj.n)
|
||||
|
||||
if hasCase and c.kind in {attachedAsgn, attachedDeepCopy}:
|
||||
@@ -288,7 +288,7 @@ proc boolLit*(g: ModuleGraph; info: TLineInfo; value: bool): PNode =
|
||||
|
||||
proc getCycleParam(c: TLiftCtx): PNode =
|
||||
assert c.kind in {attachedAsgn, attachedDup}
|
||||
if c.fn.typ.len == 4:
|
||||
if c.fn.typ.signatureLen == 4:
|
||||
result = c.fn.typ.n.lastSon
|
||||
assert result.kind == nkSym
|
||||
assert result.sym.name.s == "cyclic"
|
||||
@@ -308,9 +308,9 @@ proc newHookCall(c: var TLiftCtx; op: PSym; x, y: PNode): PNode =
|
||||
result.add x
|
||||
if y != nil:
|
||||
result.add y
|
||||
if op.typ.len == 4:
|
||||
if op.typ.signatureLen == 4:
|
||||
assert y != nil
|
||||
if c.fn.typ.len == 4:
|
||||
if c.fn.typ.signatureLen == 4:
|
||||
result.add getCycleParam(c)
|
||||
else:
|
||||
# assume the worst: A cycle is created:
|
||||
|
||||
@@ -63,7 +63,7 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
|
||||
if x.kind == tyTuple:
|
||||
n.typ = t
|
||||
for i in 0..<n.len:
|
||||
if i >= x.len: globalError conf, n.info, "invalid field at index " & $i
|
||||
if i >= x.kidsLen: globalError conf, n.info, "invalid field at index " & $i
|
||||
else: annotateType(n[i], x[i], conf)
|
||||
elif x.kind == tyProc and x.callConv == ccClosure:
|
||||
n.typ = t
|
||||
|
||||
@@ -660,7 +660,7 @@ proc isTrival(caller: PNode): bool {.inline.} =
|
||||
proc trackOperandForIndirectCall(tracked: PEffects, n: PNode, formals: PType; argIndex: int; caller: PNode) =
|
||||
let a = skipConvCastAndClosure(n)
|
||||
let op = a.typ
|
||||
let param = if formals != nil and argIndex < formals.len and formals.n != nil: formals.n[argIndex].sym else: nil
|
||||
let param = if formals != nil and formals.n != nil and argIndex < formals.n.len: formals.n[argIndex].sym else: nil
|
||||
# assume indirect calls are taken here:
|
||||
if op != nil and op.kind == tyProc and n.skipConv.kind != nkNilLit and
|
||||
not isTrival(caller) and
|
||||
@@ -695,7 +695,7 @@ proc trackOperandForIndirectCall(tracked: PEffects, n: PNode, formals: PType; ar
|
||||
markGcUnsafe(tracked, a)
|
||||
elif tfNoSideEffect notin op.flags:
|
||||
markSideEffect(tracked, a, n.info)
|
||||
let paramType = if formals != nil and argIndex < formals.len: formals[argIndex] else: nil
|
||||
let paramType = if formals != nil and argIndex < formals.signatureLen: formals[argIndex] else: nil
|
||||
if paramType != nil and paramType.kind in {tyVar}:
|
||||
invalidateFacts(tracked.guards, n)
|
||||
if n.kind == nkSym and isLocalSym(tracked, n.sym):
|
||||
@@ -979,7 +979,7 @@ proc trackCall(tracked: PEffects; n: PNode) =
|
||||
# may not look like an assignment, but it is:
|
||||
let arg = n[1]
|
||||
initVarViaNew(tracked, arg)
|
||||
if arg.typ.len != 0 and {tfRequiresInit} * arg.typ.elementType.flags != {}:
|
||||
if arg.typ.hasElementType and {tfRequiresInit} * arg.typ.elementType.flags != {}:
|
||||
if a.sym.magic == mNewSeq and n[2].kind in {nkCharLit..nkUInt64Lit} and
|
||||
n[2].intVal == 0:
|
||||
# var s: seq[notnil]; newSeq(s, 0) is a special case!
|
||||
@@ -988,7 +988,7 @@ proc trackCall(tracked: PEffects; n: PNode) =
|
||||
message(tracked.config, arg.info, warnProveInit, $arg)
|
||||
|
||||
# check required for 'nim check':
|
||||
if n[1].typ.len > 0:
|
||||
if n[1].typ.hasElementType:
|
||||
createTypeBoundOps(tracked, n[1].typ.elementType, n.info)
|
||||
createTypeBoundOps(tracked, n[1].typ, n.info)
|
||||
# new(x, finalizer): Problem: how to move finalizer into 'createTypeBoundOps'?
|
||||
@@ -1012,11 +1012,11 @@ proc trackCall(tracked: PEffects; n: PNode) =
|
||||
n[0].sym = op
|
||||
|
||||
if op != nil and op.kind == tyProc:
|
||||
for i in 1..<min(n.safeLen, op.len):
|
||||
for i in 1..<min(n.safeLen, op.signatureLen):
|
||||
let paramType = op[i]
|
||||
case paramType.kind
|
||||
of tySink:
|
||||
createTypeBoundOps(tracked, paramType[0], n.info)
|
||||
createTypeBoundOps(tracked, paramType.elementType, n.info)
|
||||
checkForSink(tracked, n[i])
|
||||
of tyVar:
|
||||
if isOutParam(paramType):
|
||||
|
||||
@@ -37,7 +37,7 @@ proc searchInstTypes*(g: ModuleGraph; key: PType): PType =
|
||||
|
||||
for inst in typeInstCacheItems(g, genericTyp.sym):
|
||||
if inst.id == key.id: return inst
|
||||
if inst.len < key.len:
|
||||
if inst.kidsLen < key.kidsLen:
|
||||
# XXX: This happens for prematurely cached
|
||||
# types such as Channel[empty]. Why?
|
||||
# See the notes for PActor in handleGenericInvocation
|
||||
@@ -47,7 +47,7 @@ proc searchInstTypes*(g: ModuleGraph; key: PType): PType =
|
||||
continue
|
||||
|
||||
block matchType:
|
||||
for j in 1..<len(key):
|
||||
for j in FirstGenericParamAt..<key.kidsLen:
|
||||
# XXX sameType is not really correct for nested generics?
|
||||
if not compareTypes(inst[j], key[j],
|
||||
flags = {ExactGenericParams, PickyCAliases}):
|
||||
@@ -366,7 +366,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
||||
when defined(reportCacheHits):
|
||||
echo "Generic instantiation cached ", typeToString(result), " for ", typeToString(t)
|
||||
return
|
||||
for i in 1..<t.len:
|
||||
for i in FirstGenericParamAt..<t.kidsLen:
|
||||
var x = t[i]
|
||||
if x.kind in {tyGenericParam}:
|
||||
x = lookupTypeVar(cl, x)
|
||||
@@ -404,7 +404,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
||||
|
||||
cl.typeMap = newTypeMapLayer(cl)
|
||||
|
||||
for i in 1..<t.len:
|
||||
for i in FirstGenericParamAt..<t.kidsLen:
|
||||
var x = replaceTypeVarsT(cl):
|
||||
if header[i].kind == tyGenericInst:
|
||||
t[i]
|
||||
@@ -415,7 +415,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
||||
propagateToOwner(header, x)
|
||||
cl.typeMap.put(body[i-1], x)
|
||||
|
||||
for i in 1..<t.len:
|
||||
for i in FirstGenericParamAt..<t.kidsLen:
|
||||
# if one of the params is not concrete, we cannot do anything
|
||||
# but we already raised an error!
|
||||
rawAddSon(result, header[i], propagateHasAsgn = false)
|
||||
@@ -481,11 +481,11 @@ proc eraseVoidParams*(t: PType) =
|
||||
if t.returnType != nil and t.returnType.kind == tyVoid:
|
||||
t.setReturnType nil
|
||||
|
||||
for i in 1..<t.len:
|
||||
for i in FirstParamAt..<t.signatureLen:
|
||||
# don't touch any memory unless necessary
|
||||
if t[i].kind == tyVoid:
|
||||
var pos = i
|
||||
for j in i+1..<t.len:
|
||||
for j in i+1..<t.signatureLen:
|
||||
if t[j].kind != tyVoid:
|
||||
t[pos] = t[j]
|
||||
t.n[pos] = t.n[j]
|
||||
@@ -495,8 +495,7 @@ proc eraseVoidParams*(t: PType) =
|
||||
break
|
||||
|
||||
proc skipIntLiteralParams*(t: PType; idgen: IdGenerator) =
|
||||
for i in 0..<t.len:
|
||||
let p = t[i]
|
||||
for i, p in t.ikids:
|
||||
if p == nil: continue
|
||||
let skipped = p.skipIntLit(idgen)
|
||||
if skipped != p:
|
||||
@@ -620,7 +619,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
bailout()
|
||||
result = instCopyType(cl, t)
|
||||
idTablePut(cl.localCache, t, result)
|
||||
for i in 1..<result.len:
|
||||
for i in FirstGenericParamAt..<result.kidsLen:
|
||||
result[i] = replaceTypeVarsT(cl, result[i])
|
||||
propagateToOwner(result, result.last)
|
||||
|
||||
@@ -633,15 +632,15 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
#if not cl.allowMetaTypes:
|
||||
idTablePut(cl.localCache, t, result)
|
||||
|
||||
for i in 0..<result.len:
|
||||
if result[i] != nil:
|
||||
if result[i].kind == tyGenericBody:
|
||||
for i, resulti in result.ikids:
|
||||
if resulti != nil:
|
||||
if resulti.kind == tyGenericBody:
|
||||
localError(cl.c.config, if t.sym != nil: t.sym.info else: cl.info,
|
||||
"cannot instantiate '" &
|
||||
typeToString(result[i], preferDesc) &
|
||||
"' inside of type definition: '" &
|
||||
t.owner.name.s & "'; Maybe generic arguments are missing?")
|
||||
var r = replaceTypeVarsT(cl, result[i])
|
||||
var r = replaceTypeVarsT(cl, resulti)
|
||||
if result.kind == tyObject:
|
||||
# carefully coded to not skip the precious tyGenericInst:
|
||||
let r2 = r.skipTypes({tyAlias, tySink, tyOwned})
|
||||
@@ -654,7 +653,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
result.n = replaceTypeVarsN(cl, result.n, ord(result.kind==tyProc))
|
||||
case result.kind
|
||||
of tyArray:
|
||||
let idx = result[0]
|
||||
let idx = result.indexType
|
||||
internalAssert cl.c.config, idx.kind != tyStatic
|
||||
|
||||
of tyObject, tyTuple:
|
||||
@@ -667,7 +666,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
skipIntLiteralParams(result, cl.c.idgen)
|
||||
|
||||
of tyRange:
|
||||
result[0] = result[0].skipTypes({tyStatic, tyDistinct})
|
||||
result.setIndexType result.indexType.skipTypes({tyStatic, tyDistinct})
|
||||
|
||||
else: discard
|
||||
else:
|
||||
@@ -676,7 +675,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
result = t
|
||||
|
||||
# Slow path, we have some work to do
|
||||
if t.kind == tyRef and t.len > 0 and t.elementType.kind == tyObject and t.elementType.n != nil:
|
||||
if t.kind == tyRef and t.hasElementType and t.elementType.kind == tyObject and t.elementType.n != nil:
|
||||
discard replaceObjBranches(cl, t.elementType.n)
|
||||
|
||||
elif result.n != nil and t.kind == tyObject:
|
||||
@@ -712,7 +711,7 @@ when false:
|
||||
popInfoContext(p.config)
|
||||
|
||||
proc recomputeFieldPositions*(t: PType; obj: PNode; currPosition: var int) =
|
||||
if t != nil and t.len > 0 and t.baseClass != nil:
|
||||
if t != nil and t.baseClass != nil:
|
||||
let b = skipTypes(t.baseClass, skipPtrs)
|
||||
recomputeFieldPositions(b, b.n, currPosition)
|
||||
case obj.kind
|
||||
|
||||
@@ -104,8 +104,8 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi
|
||||
|
||||
case t.kind
|
||||
of tyGenericInvocation:
|
||||
for i in 0..<t.len:
|
||||
c.hashType t[i], flags, conf
|
||||
for a in t.kids:
|
||||
c.hashType a, flags, conf
|
||||
of tyDistinct:
|
||||
if CoDistinct in flags:
|
||||
if t.sym != nil: c.hashSym(t.sym)
|
||||
@@ -121,8 +121,9 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi
|
||||
# We cannot trust the `lastSon` to hold a properly populated and unique
|
||||
# value for each instantiation, so we hash the generic parameters here:
|
||||
let normalizedType = t.skipGenericAlias
|
||||
for i in 0..<normalizedType.len - 1:
|
||||
c.hashType t[i], flags, conf
|
||||
c.hashType normalizedType.genericHead, flags, conf
|
||||
for _, a in normalizedType.genericInstParams:
|
||||
c.hashType a, flags, conf
|
||||
else:
|
||||
c.hashType t.skipModifier, flags, conf
|
||||
of tyAlias, tySink, tyUserTypeClasses, tyInferred:
|
||||
@@ -143,8 +144,9 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi
|
||||
let inst = t.typeInst
|
||||
t.typeInst = nil
|
||||
assert inst.kind == tyGenericInst
|
||||
for i in 0..<inst.len - 1:
|
||||
c.hashType inst[i], flags, conf
|
||||
c.hashType inst.genericHead, flags, conf
|
||||
for _, a in inst.genericInstParams:
|
||||
c.hashType a, flags, conf
|
||||
t.typeInst = inst
|
||||
return
|
||||
c &= char(t.kind)
|
||||
@@ -184,16 +186,16 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi
|
||||
c &= ".empty"
|
||||
else:
|
||||
c &= t.id
|
||||
if t.len > 0 and t.baseClass != nil:
|
||||
if t.hasElementType and t.baseClass != nil:
|
||||
hashType c, t.baseClass, flags, conf
|
||||
of tyRef, tyPtr, tyVar:
|
||||
c &= char(t.kind)
|
||||
if t.len > 0:
|
||||
if t.hasElementType:
|
||||
c.hashType t.elementType, flags, conf
|
||||
if tfVarIsPtr in t.flags: c &= ".varisptr"
|
||||
of tyGenericBody:
|
||||
c &= char(t.kind)
|
||||
if t.len > 0:
|
||||
if t.hasElementType:
|
||||
c.hashType t.typeBodyImpl, flags, conf
|
||||
of tyFromExpr:
|
||||
c &= char(t.kind)
|
||||
@@ -201,15 +203,14 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi
|
||||
of tyTuple:
|
||||
c &= char(t.kind)
|
||||
if t.n != nil and CoType notin flags:
|
||||
assert(t.n.len == t.len)
|
||||
for i in 0..<t.n.len:
|
||||
assert(t.n[i].kind == nkSym)
|
||||
c &= t.n[i].sym.name.s
|
||||
c &= ':'
|
||||
c.hashType(t[i], flags+{CoIgnoreRange}, conf)
|
||||
c.hashType(t.n[i].sym.typ, flags+{CoIgnoreRange}, conf)
|
||||
c &= ','
|
||||
else:
|
||||
for i in 0..<t.len: c.hashType t[i], flags+{CoIgnoreRange}, conf
|
||||
for a in t.kids: c.hashType a, flags+{CoIgnoreRange}, conf
|
||||
of tyRange:
|
||||
if CoIgnoreRange notin flags:
|
||||
c &= char(t.kind)
|
||||
@@ -232,7 +233,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi
|
||||
c &= ','
|
||||
c.hashType(t.returnType, flags, conf)
|
||||
else:
|
||||
for i in 0..<t.len: c.hashType(t[i], flags, conf)
|
||||
for a in t.signature: c.hashType(a, flags, conf)
|
||||
c &= char(t.callConv)
|
||||
# purity of functions doesn't have to affect the mangling (which is in fact
|
||||
# problematic for HCR - someone could have cached a pointer to another
|
||||
@@ -244,10 +245,11 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi
|
||||
if tfVarargs in t.flags: c &= ".varargs"
|
||||
of tyArray:
|
||||
c &= char(t.kind)
|
||||
for i in 0..<t.len: c.hashType(t[i], flags-{CoIgnoreRange}, conf)
|
||||
c.hashType(t.indexType, flags-{CoIgnoreRange}, conf)
|
||||
c.hashType(t.elementType, flags-{CoIgnoreRange}, conf)
|
||||
else:
|
||||
c &= char(t.kind)
|
||||
for i in 0..<t.len: c.hashType(t[i], flags, conf)
|
||||
for a in t.kids: c.hashType(a, flags, conf)
|
||||
if tfNotNil in t.flags and CoType notin flags: c &= "not nil"
|
||||
|
||||
when defined(debugSigHashes):
|
||||
|
||||
@@ -184,11 +184,11 @@ proc checkGeneric(a, b: TCandidate): int =
|
||||
let aa = a.callee
|
||||
let bb = b.callee
|
||||
var winner = 0
|
||||
for i in 1..<min(aa.len, bb.len):
|
||||
var ma = newCandidate(c, bb[i])
|
||||
let tra = typeRel(ma, bb[i], aa[i], {trDontBind})
|
||||
var mb = newCandidate(c, aa[i])
|
||||
let trb = typeRel(mb, aa[i], bb[i], {trDontBind})
|
||||
for aai, bbi in underspecifiedPairs(aa, bb, 1):
|
||||
var ma = newCandidate(c, bbi)
|
||||
let tra = typeRel(ma, bbi, aai, {trDontBind})
|
||||
var mb = newCandidate(c, aai)
|
||||
let trb = typeRel(mb, aai, bbi, {trDontBind})
|
||||
if tra == isGeneric and trb == isNone:
|
||||
if winner == -1: return 0
|
||||
winner = 1
|
||||
@@ -259,9 +259,9 @@ proc sumGeneric(t: PType): int =
|
||||
proc complexDisambiguation(a, b: PType): int =
|
||||
# 'a' matches better if *every* argument matches better or equal than 'b'.
|
||||
var winner = 0
|
||||
for i in 1..<min(a.len, b.len):
|
||||
let x = a[i].sumGeneric
|
||||
let y = b[i].sumGeneric
|
||||
for ai, bi in underspecifiedPairs(a, b, 1):
|
||||
let x = ai.sumGeneric
|
||||
let y = bi.sumGeneric
|
||||
if x != y:
|
||||
if winner == 0:
|
||||
if x > y: winner = 1
|
||||
@@ -276,8 +276,8 @@ proc complexDisambiguation(a, b: PType): int =
|
||||
result = winner
|
||||
when false:
|
||||
var x, y: int
|
||||
for i in 1..<a.len: x += a[i].sumGeneric
|
||||
for i in 1..<b.len: y += b[i].sumGeneric
|
||||
for i in 1..<a.len: x += ai.sumGeneric
|
||||
for i in 1..<b.len: y += bi.sumGeneric
|
||||
result = x - y
|
||||
|
||||
proc writeMatches*(c: TCandidate) =
|
||||
@@ -375,7 +375,7 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
|
||||
of tyOwned:
|
||||
# bug #11257: the comparison system.`==`[T: proc](x, y: T) works
|
||||
# better without the 'owned' type:
|
||||
if f != nil and f.len > 0 and f[0].skipTypes({tyBuiltInTypeClass, tyOr}).kind == tyProc:
|
||||
if f != nil and f.hasElementType and f.elementType.skipTypes({tyBuiltInTypeClass, tyOr}).kind == tyProc:
|
||||
result = t.skipModifier
|
||||
else:
|
||||
result = t
|
||||
@@ -468,10 +468,10 @@ proc getObjectTypeOrNil(f: PType): PType =
|
||||
if f == nil: return nil
|
||||
case f.kind:
|
||||
of tyGenericInvocation, tyCompositeTypeClass, tyAlias:
|
||||
if f.len <= 0 or f[0] == nil:
|
||||
if not f.hasElementType or f.elementType == nil:
|
||||
result = nil
|
||||
else:
|
||||
result = getObjectTypeOrNil(f[0])
|
||||
result = getObjectTypeOrNil(f.elementType)
|
||||
of tyGenericInst:
|
||||
result = getObjectTypeOrNil(f.skipModifier)
|
||||
of tyGenericBody:
|
||||
@@ -496,8 +496,8 @@ proc getObjectTypeOrNil(f: PType): PType =
|
||||
|
||||
proc genericParamPut(c: var TCandidate; last, fGenericOrigin: PType) =
|
||||
if fGenericOrigin != nil and last.kind == tyGenericInst and
|
||||
last.len-1 == fGenericOrigin.len:
|
||||
for i in 1..<fGenericOrigin.len:
|
||||
last.kidsLen-1 == fGenericOrigin.kidsLen:
|
||||
for i in FirstGenericParamAt..<fGenericOrigin.kidsLen:
|
||||
let x = PType(idTableGet(c.bindings, fGenericOrigin[i]))
|
||||
if x == nil:
|
||||
put(c, fGenericOrigin[i], last[i])
|
||||
@@ -531,7 +531,7 @@ proc skipToObject(t: PType; skipped: var SkippedPtr): PType =
|
||||
while r != nil:
|
||||
case r.kind
|
||||
of tyGenericInvocation:
|
||||
r = r[0]
|
||||
r = r.genericHead
|
||||
of tyRef:
|
||||
inc ptrs
|
||||
skipped = skippedRef
|
||||
@@ -581,12 +581,12 @@ proc recordRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||
result = isNone
|
||||
if sameType(f, a):
|
||||
result = isEqual
|
||||
elif a.len == f.len:
|
||||
elif sameTupleLengths(a, f):
|
||||
result = isEqual
|
||||
let firstField = if f.kind == tyTuple: 0
|
||||
else: 1
|
||||
for i in firstField..<f.len:
|
||||
var m = typeRel(c, f[i], a[i])
|
||||
for _, ff, aa in tupleTypePairs(f, a):
|
||||
var m = typeRel(c, ff, aa)
|
||||
if m < isSubtype: return isNone
|
||||
result = minRel(result, m)
|
||||
if f.n != nil and a.n != nil:
|
||||
@@ -609,7 +609,7 @@ proc inconsistentVarTypes(f, a: PType): bool {.inline.} =
|
||||
(f.kind in {tyVar, tyLent, tySink} or a.kind in {tyVar, tyLent, tySink})) or
|
||||
isOutParam(f) != isOutParam(a)
|
||||
|
||||
proc procParamTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||
proc procParamTypeRel(c: var TCandidate; f, a: PType): TTypeRelation =
|
||||
## For example we have:
|
||||
## ```nim
|
||||
## proc myMap[T,S](sIn: seq[T], f: proc(x: T): S): seq[S] = ...
|
||||
@@ -669,7 +669,7 @@ proc procParamTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||
proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||
case a.kind
|
||||
of tyProc:
|
||||
if f.len != a.len: return
|
||||
if f.signatureLen != a.signatureLen: return
|
||||
result = isEqual # start with maximum; also correct for no
|
||||
# params at all
|
||||
|
||||
@@ -1193,7 +1193,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
# being passed as parameters
|
||||
return isNone
|
||||
else: discard
|
||||
|
||||
|
||||
case f.kind
|
||||
of tyEnum:
|
||||
if a.kind == f.kind and sameEnumTypes(f, a): result = isEqual
|
||||
|
||||
@@ -706,7 +706,7 @@ proc traverse(c: var Partitions; n: PNode) =
|
||||
for child in n: traverse(c, child)
|
||||
|
||||
let parameters = n[0].typ
|
||||
let L = if parameters != nil: parameters.len else: 0
|
||||
let L = if parameters != nil: parameters.signatureLen else: 0
|
||||
let m = getMagic(n)
|
||||
|
||||
if m == mEnsureMove and n[1].kind == nkSym:
|
||||
@@ -857,7 +857,7 @@ proc computeLiveRanges(c: var Partitions; n: PNode) =
|
||||
for child in n: computeLiveRanges(c, child)
|
||||
|
||||
let parameters = n[0].typ
|
||||
let L = if parameters != nil: parameters.len else: 0
|
||||
let L = if parameters != nil: parameters.signatureLen else: 0
|
||||
|
||||
for i in 1..<n.len:
|
||||
let it = n[i]
|
||||
|
||||
@@ -2264,7 +2264,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
decodeB(rkNode)
|
||||
var typ = regs[rb].node.typ
|
||||
internalAssert c.config, typ != nil
|
||||
while typ.kind == tyTypeDesc and typ.len > 0: typ = typ.skipModifier
|
||||
while typ.kind == tyTypeDesc and typ.hasElementType: typ = typ.skipModifier
|
||||
createStr regs[ra]
|
||||
regs[ra].node.strVal = typ.typeToString(preferExported)
|
||||
|
||||
@@ -2280,11 +2280,11 @@ proc execute(c: PCtx, start: int): PNode =
|
||||
proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
|
||||
c.loopIterations = c.config.maxLoopIterationsVM
|
||||
if sym.kind in routineKinds:
|
||||
if sym.typ.len-1 != args.len:
|
||||
if sym.typ.paramsLen != args.len:
|
||||
result = nil
|
||||
localError(c.config, sym.info,
|
||||
"NimScript: expected $# arguments, but got $#" % [
|
||||
$(sym.typ.len-1), $args.len])
|
||||
$(sym.typ.paramsLen), $args.len])
|
||||
else:
|
||||
let start = genProc(c, sym)
|
||||
|
||||
@@ -2296,8 +2296,8 @@ proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
|
||||
if not isEmptyType(sym.typ.returnType) or sym.kind == skMacro:
|
||||
putIntoReg(tos.slots[0], getNullValue(sym.typ.returnType, sym.info, c.config))
|
||||
# XXX We could perform some type checking here.
|
||||
for i in 1..<sym.typ.len:
|
||||
putIntoReg(tos.slots[i], args[i-1])
|
||||
for i in 0..<sym.typ.paramsLen:
|
||||
putIntoReg(tos.slots[i+1], args[i])
|
||||
|
||||
result = rawExecute(c, start, tos).regToNode
|
||||
else:
|
||||
@@ -2435,7 +2435,7 @@ iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) =
|
||||
let gp = macroSym.ast[genericParamsPos]
|
||||
for i in 0..<gp.len:
|
||||
let genericParam = gp[i].sym
|
||||
let posInCall = macroSym.typ.len + i
|
||||
let posInCall = macroSym.typ.signatureLen + i
|
||||
if posInCall < call.len:
|
||||
yield (genericParam, call[posInCall])
|
||||
|
||||
@@ -2458,9 +2458,10 @@ proc evalMacroCall*(module: PSym; idgen: IdGenerator; g: ModuleGraph; templInstC
|
||||
|
||||
# immediate macros can bypass any type and arity checking so we check the
|
||||
# arity here too:
|
||||
if sym.typ.len > n.safeLen and sym.typ.len > 1:
|
||||
let sl = sym.typ.signatureLen
|
||||
if sl > n.safeLen and sl > 1:
|
||||
globalError(g.config, n.info, "in call '$#' got $#, but expected $# argument(s)" % [
|
||||
n.renderTree, $(n.safeLen-1), $(sym.typ.len-1)])
|
||||
n.renderTree, $(n.safeLen-1), $(sym.typ.paramsLen)])
|
||||
|
||||
setupGlobalCtx(module, g, idgen)
|
||||
var c = PCtx g.vm
|
||||
|
||||
@@ -49,13 +49,13 @@ proc mapTypeToBracketX(cache: IdentCache; name: string; m: TMagic; t: PType; inf
|
||||
inst=false): PNode =
|
||||
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
|
||||
result.add atomicTypeX(cache, name, m, t, info, idgen)
|
||||
for i in 0..<t.len:
|
||||
if t[i] == nil:
|
||||
for a in t.kids:
|
||||
if a == nil:
|
||||
let voidt = atomicTypeX(cache, "void", mVoid, t, info, idgen)
|
||||
voidt.typ = newType(tyVoid, idgen, t.owner)
|
||||
result.add voidt
|
||||
else:
|
||||
result.add mapTypeToAstX(cache, t[i], info, idgen, inst)
|
||||
result.add mapTypeToAstX(cache, a, info, idgen, inst)
|
||||
|
||||
proc objectNode(cache: IdentCache; n: PNode; idgen: IdGenerator): PNode =
|
||||
if n.kind == nkSym:
|
||||
@@ -74,9 +74,9 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
var allowRecursion = allowRecursionX
|
||||
template atomicType(name, m): untyped = atomicTypeX(cache, name, m, t, info, idgen)
|
||||
template atomicType(s): untyped = atomicTypeX(s, info)
|
||||
template mapTypeToAst(t,info): untyped = mapTypeToAstX(cache, t, info, idgen, inst)
|
||||
template mapTypeToAstR(t,info): untyped = mapTypeToAstX(cache, t, info, idgen, inst, true)
|
||||
template mapTypeToAst(t,i,info): untyped =
|
||||
template mapTypeToAst(t, info): untyped = mapTypeToAstX(cache, t, info, idgen, inst)
|
||||
template mapTypeToAstR(t, info): untyped = mapTypeToAstX(cache, t, info, idgen, inst, true)
|
||||
template mapTypeToAst(t, i, info): untyped =
|
||||
if i<t.len and t[i]!=nil: mapTypeToAstX(cache, t[i], info, idgen, inst)
|
||||
else: newNodeI(nkEmpty, info)
|
||||
template mapTypeToBracket(name, m, t, info): untyped =
|
||||
@@ -129,8 +129,8 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
result = atomicType("typeDesc", mTypeDesc)
|
||||
of tyGenericInvocation:
|
||||
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
|
||||
for i in 0..<t.len:
|
||||
result.add mapTypeToAst(t[i], info)
|
||||
for a in t.kids:
|
||||
result.add mapTypeToAst(a, info)
|
||||
of tyGenericInst:
|
||||
if inst:
|
||||
if allowRecursion:
|
||||
@@ -141,8 +141,8 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
result = newNodeX(nkBracketExpr)
|
||||
#result.add mapTypeToAst(t.last, info)
|
||||
result.add mapTypeToAst(t.genericHead, info)
|
||||
for i in 1..<t.len-1:
|
||||
result.add mapTypeToAst(t[i], info)
|
||||
for _, a in t.genericInstParams:
|
||||
result.add mapTypeToAst(a, info)
|
||||
else:
|
||||
result = mapTypeToAstX(cache, t.skipModifier, info, idgen, inst, allowRecursion)
|
||||
# keep original type info for getType calls on the output node:
|
||||
@@ -243,7 +243,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
fp.add newNodeI(nkEmpty, info)
|
||||
else:
|
||||
fp.add mapTypeToAst(t.returnType, t.n[0].info)
|
||||
for i in 1..<t.len:
|
||||
for i in FirstParamAt..<t.kidsLen:
|
||||
fp.add newIdentDefs(t.n[i], t[i])
|
||||
result.add fp
|
||||
result.add if t.n[0].len > 0: t.n[0][pragmasEffects].copyTree
|
||||
|
||||
@@ -620,7 +620,7 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) =
|
||||
for i in 0..<n.len:
|
||||
var r: TRegister = x+i
|
||||
c.gen(n[i], r, {gfIsParam})
|
||||
if i >= fntyp.len:
|
||||
if i >= fntyp.signatureLen:
|
||||
internalAssert c.config, tfVarargs in fntyp.flags
|
||||
c.gABx(n, opcSetType, r, c.genType(n[i].typ))
|
||||
if dest < 0:
|
||||
@@ -1874,7 +1874,7 @@ proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
genArrAccessOpcode(c, n, dest, opc, flags)
|
||||
|
||||
proc getNullValueAux(t: PType; obj: PNode, result: PNode; conf: ConfigRef; currPosition: var int) =
|
||||
if t != nil and t.len > 0 and t.baseClass != nil:
|
||||
if t != nil and t.baseClass != nil:
|
||||
let b = skipTypes(t.baseClass, skipPtrs)
|
||||
getNullValueAux(b, b.n, result, conf, currPosition)
|
||||
case obj.kind
|
||||
@@ -1929,8 +1929,8 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
|
||||
result.add getNullValue(elemType(t), info, conf)
|
||||
of tyTuple:
|
||||
result = newNodeIT(nkTupleConstr, info, t)
|
||||
for i in 0..<t.len:
|
||||
result.add getNullValue(t[i], info, conf)
|
||||
for a in t.kids:
|
||||
result.add getNullValue(a, info, conf)
|
||||
of tySet:
|
||||
result = newNodeIT(nkCurly, info, t)
|
||||
of tySequence, tyOpenArray:
|
||||
|
||||
@@ -82,11 +82,11 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet;
|
||||
s.add("]")
|
||||
of tyTuple:
|
||||
s.add("{")
|
||||
for i in 0..<t.len:
|
||||
for i, ti in t.ikids:
|
||||
if i > 0: s.add(", ")
|
||||
s.add("\"Field" & $i)
|
||||
s.add("\": ")
|
||||
storeAny(s, t[i], a[i].skipColon, stored, conf)
|
||||
storeAny(s, ti, a[i].skipColon, stored, conf)
|
||||
s.add("}")
|
||||
of tyObject:
|
||||
s.add("{")
|
||||
@@ -208,11 +208,12 @@ proc loadAny(p: var JsonParser, t: PType,
|
||||
next(p)
|
||||
result = newNode(nkTupleConstr)
|
||||
var i = 0
|
||||
let tupleLen = t.kidsLen
|
||||
while p.kind != jsonObjectEnd and p.kind != jsonEof:
|
||||
if p.kind != jsonString:
|
||||
raiseParseErr(p, "string expected for a field name")
|
||||
next(p)
|
||||
if i >= t.len:
|
||||
if i >= tupleLen:
|
||||
raiseParseErr(p, "too many fields to tuple type " & typeToString(t))
|
||||
result.add loadAny(p, t[i], tab, cache, conf, idgen)
|
||||
inc i
|
||||
|
||||
Reference in New Issue
Block a user