diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2023-12-15 10:20:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-15 10:20:57 +0100 |
commit | 91ad6a740bad84f76ecfba253d12f07d6abbd3eb (patch) | |
tree | 6fdc8aad065e19e51fad7f996016feaae9b6280e | |
parent | cca5684a17e654a13ddac046f1e76873d8c19f55 (diff) | |
download | Nim-91ad6a740bad84f76ecfba253d12f07d6abbd3eb.tar.gz |
type refactor: part 4 (#23077)
-rw-r--r-- | compiler/aliases.nim | 4 | ||||
-rw-r--r-- | compiler/ast.nim | 9 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 16 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 11 | ||||
-rw-r--r-- | compiler/ccgreset.nim | 11 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 3 | ||||
-rw-r--r-- | compiler/ccgtrav.nim | 15 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 37 | ||||
-rw-r--r-- | compiler/cgmeth.nim | 22 | ||||
-rw-r--r-- | compiler/concepts.nim | 50 | ||||
-rw-r--r-- | compiler/dfa.nim | 2 | ||||
-rw-r--r-- | compiler/evaltempl.nim | 4 | ||||
-rw-r--r-- | compiler/expanddefaults.nim | 2 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 4 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 18 | ||||
-rw-r--r-- | compiler/semmacrosanity.nim | 2 | ||||
-rw-r--r-- | compiler/sempass2.nim | 12 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 35 | ||||
-rw-r--r-- | compiler/sighashes.nim | 32 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 44 | ||||
-rw-r--r-- | compiler/varpartitions.nim | 4 | ||||
-rw-r--r-- | compiler/vm.nim | 17 | ||||
-rw-r--r-- | compiler/vmdeps.nim | 22 | ||||
-rw-r--r-- | compiler/vmgen.nim | 8 | ||||
-rw-r--r-- | compiler/vmmarshal.nim | 7 |
25 files changed, 197 insertions, 194 deletions
diff --git a/compiler/aliases.nim b/compiler/aliases.nim index 3910ecb9d..fa1167753 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -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 diff --git a/compiler/ast.nim b/compiler/ast.nim index aa12c6421..ce86d7369 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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 = diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 53c147024..5dc6b39a6 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -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 diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 28f75f994..8cb9e208a 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -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 "{" diff --git a/compiler/ccgreset.nim b/compiler/ccgreset.nim index da7f37398..e4abcfc8c 100644 --- a/compiler/ccgreset.nim +++ b/compiler/ccgreset.nim @@ -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]) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index c3d44c1d3..7bbc40890 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -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 "," diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index a7470c44f..3fd269bc6 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -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)]) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 3d7aa3088..6a51fe3a0 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -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 = diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 6bfa6d789..6c3db7ad6 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -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 diff --git a/compiler/concepts.nim b/compiler/concepts.nim index 01bfc542d..e44b0d1cd 100644 --- a/compiler/concepts.nim +++ b/compiler/concepts.nim @@ -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]) diff --git a/compiler/dfa.nim b/compiler/dfa.nim index 1511628dd..8ee527952 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -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: diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index d87505102..98c6f4b82 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -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 diff --git a/compiler/expanddefaults.nim b/compiler/expanddefaults.nim index 86f87cd84..c121f5dea 100644 --- a/compiler/expanddefaults.nim +++ b/compiler/expanddefaults.nim @@ -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) diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index b8d6d5f63..a6620de2a 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -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 diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 2987a04a8..a3ca88dd5 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -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: diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim index 01b79c1bc..4aab216c7 100644 --- a/compiler/semmacrosanity.nim +++ b/compiler/semmacrosanity.nim @@ -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 diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 9b386cf5c..e2d45a388 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -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): diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 63941419c..1510a3f9c 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -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 diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index ca1b74604..a058ffee9 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -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): diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 94d775e9a..127ed4a68 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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 diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim index 2ba644658..9b5ad009d 100644 --- a/compiler/varpartitions.nim +++ b/compiler/varpartitions.nim @@ -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] diff --git a/compiler/vm.nim b/compiler/vm.nim index 6b00ff9d3..7063a7268 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -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 diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 6d0e03813..e293ab7b2 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -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 diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 9667daa3d..9bbea2b08 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -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: diff --git a/compiler/vmmarshal.nim b/compiler/vmmarshal.nim index d80010877..0391a5e7b 100644 --- a/compiler/vmmarshal.nim +++ b/compiler/vmmarshal.nim @@ -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 |