From 91ad6a740bad84f76ecfba253d12f07d6abbd3eb Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 15 Dec 2023 10:20:57 +0100 Subject: [PATCH] type refactor: part 4 (#23077) --- compiler/aliases.nim | 4 +-- compiler/ast.nim | 9 +++++- compiler/ccgcalls.nim | 16 ++++------- compiler/ccgexprs.nim | 11 ++++---- compiler/ccgreset.nim | 11 ++++---- compiler/ccgstmts.nim | 3 +- compiler/ccgtrav.nim | 15 +++++----- compiler/ccgtypes.nim | 37 ++++++++++++------------- compiler/cgmeth.nim | 22 ++++++++------- compiler/concepts.nim | 50 ++++++++++++++++++---------------- compiler/dfa.nim | 2 +- compiler/evaltempl.nim | 4 +-- compiler/expanddefaults.nim | 2 +- compiler/injectdestructors.nim | 4 +-- compiler/liftdestructors.nim | 18 ++++++------ compiler/semmacrosanity.nim | 2 +- compiler/sempass2.nim | 12 ++++---- compiler/semtypinst.nim | 35 ++++++++++++------------ compiler/sighashes.nim | 32 ++++++++++++---------- compiler/sigmatch.nim | 44 +++++++++++++++--------------- compiler/varpartitions.nim | 4 +-- compiler/vm.nim | 17 ++++++------ compiler/vmdeps.nim | 22 +++++++-------- compiler/vmgen.nim | 8 +++--- compiler/vmmarshal.nim | 7 +++-- 25 files changed, 197 insertions(+), 194 deletions(-) diff --git a/compiler/aliases.nim b/compiler/aliases.nim index 3910ecb9dc..fa1167753f 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.. 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..= 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 28f75f9948..8cb9e208a4 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.. 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 da7f373988..e4abcfc8c6 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.. 0: result.add "," diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index a7470c44f3..3fd269bc66 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: + 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.. 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.. 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 6bfa6d7892..6c3db7ad68 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.. 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..= a.len + result = covered >= a.kidsLen if not result: m.inferred.setLen oldLen else: result = false - for i in 0.. 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 b8d6d5f636..a6620de2a8 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 2987a04a84..a3ca88dd50 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.. 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 01b79c1bc6..4aab216c7f 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..= 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 9b386cf5ca..e2d45a3884 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.. 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 ca1b74604f..a058ffee99 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.. 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.. 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.. 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.. 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.. 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 6d0e038139..e293ab7b20 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.. 0: t.n[0][pragmasEffects].copyTree diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 9667daa3d0..9bbea2b08e 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..= 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.. 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