type refactor: part 4 (#23077)

This commit is contained in:
Andreas Rumpf
2023-12-15 10:20:57 +01:00
committed by GitHub
parent cca5684a17
commit 91ad6a740b
25 changed files with 197 additions and 194 deletions

View File

@@ -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

View File

@@ -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 =

View File

@@ -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

View File

@@ -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 "{"

View File

@@ -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])

View File

@@ -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 ","

View File

@@ -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)])

View File

@@ -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 =

View File

@@ -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

View File

@@ -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])

View File

@@ -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:

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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):

View File

@@ -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

View File

@@ -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):

View File

@@ -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

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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