diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2023-12-12 16:54:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-12 16:54:50 +0100 |
commit | db603237c648a796ef7bff77641febd30b3999cd (patch) | |
tree | 13e693ac432b1542cab7f2b2bbe1b8c11ca258e0 | |
parent | 8cc3c774c8925c3d21626d09b41ad352bd898e4a (diff) | |
download | Nim-db603237c648a796ef7bff77641febd30b3999cd.tar.gz |
Types: Refactorings; step 1 (#23055)
57 files changed, 713 insertions, 658 deletions
diff --git a/compiler/aliases.nim b/compiler/aliases.nim index 40d6e272c..3910ecb9d 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -51,12 +51,14 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult = if compareTypes(a, b, dcEqIgnoreDistinct): return arYes case a.kind of tyObject: - if a[0] != nil: - result = isPartOfAux(a[0].skipTypes(skipPtrs), b, marker) + if a.baseClass != nil: + result = isPartOfAux(a.baseClass.skipTypes(skipPtrs), b, marker) if result == arNo: result = isPartOfAux(a.n, b, marker) of tyGenericInst, tyDistinct, tyAlias, tySink: - result = isPartOfAux(lastSon(a), b, marker) - of tyArray, tySet, tyTuple: + result = isPartOfAux(skipModifier(a), b, marker) + of tySet, tyArray: + result = isPartOfAux(a.elementType, b, marker) + of tyTuple: for i in 0..<a.len: result = isPartOfAux(a[i], b, marker) if result == arYes: return diff --git a/compiler/ast.nim b/compiler/ast.nim index e25ce42dd..ae38e55a5 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -434,9 +434,9 @@ type tyInferred # In the initial state `base` stores a type class constraining # the types that can be inferred. After a candidate type is - # selected, it's stored in `lastSon`. Between `base` and `lastSon` + # selected, it's stored in `last`. Between `base` and `last` # there may be 0, 2 or more types that were also considered as - # possible candidates in the inference process (i.e. lastSon will + # possible candidates in the inference process (i.e. last will # be updated to store a type best conforming to all candidates) tyAnd, tyOr, tyNot @@ -1196,9 +1196,10 @@ proc isCallExpr*(n: PNode): bool = proc discardSons*(father: PNode) -type Indexable = PNode | PType +proc len*(n: PNode): int {.inline.} = + result = n.sons.len -proc len*(n: Indexable): int {.inline.} = +proc len*(n: PType): int {.inline.} = result = n.sons.len proc safeLen*(n: PNode): int {.inline.} = @@ -1212,18 +1213,31 @@ proc safeArrLen*(n: PNode): int {.inline.} = elif n.kind in {nkNone..nkFloat128Lit}: result = 0 else: result = n.len -proc add*(father, son: Indexable) = +proc add*(father, son: PNode) = assert son != nil father.sons.add(son) -proc addAllowNil*(father, son: Indexable) {.inline.} = +proc addAllowNil*(father, son: PNode) {.inline.} = father.sons.add(son) -template `[]`*(n: Indexable, i: int): Indexable = n.sons[i] -template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x +template `[]`*(n: PNode, i: int): PNode = n.sons[i] +template `[]=`*(n: PNode, i: int; x: PNode) = n.sons[i] = x -template `[]`*(n: Indexable, i: BackwardsIndex): Indexable = n[n.len - i.int] -template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) = n[n.len - i.int] = x +template `[]`*(n: PNode, i: BackwardsIndex): PNode = n[n.len - i.int] +template `[]=`*(n: PNode, i: BackwardsIndex; x: PNode) = n[n.len - i.int] = x + +proc add*(father, son: PType) = + assert son != nil + father.sons.add(son) + +proc addAllowNil*(father, son: PType) {.inline.} = + father.sons.add(son) + +template `[]`*(n: PType, i: int): PType = n.sons[i] +template `[]=`*(n: PType, i: int; x: PType) = n.sons[i] = x + +template `[]`*(n: PType, i: BackwardsIndex): PType = n[n.len - i.int] +template `[]=`*(n: PType, i: BackwardsIndex; x: PType) = n[n.len - i.int] = x proc getDeclPragma*(n: PNode): PNode = ## return the `nkPragma` node for declaration `n`, or `nil` if no pragma was found. @@ -1354,7 +1368,7 @@ proc newTreeIT*(kind: TNodeKind; info: TLineInfo; typ: PType; children: varargs[ result.sons = @children template previouslyInferred*(t: PType): PType = - if t.sons.len > 1: t.lastSon else: nil + if t.sons.len > 1: t.last else: nil when false: import tables, strutils @@ -1474,7 +1488,25 @@ proc newIntNode*(kind: TNodeKind, intVal: Int128): PNode = result = newNode(kind) result.intVal = castToInt64(intVal) -proc lastSon*(n: Indexable): Indexable = n.sons[^1] +proc lastSon*(n: PNode): PNode {.inline.} = n.sons[^1] +proc last*(n: PType): PType {.inline.} = n.sons[^1] + +proc elementType*(n: PType): PType {.inline.} = n.sons[^1] +proc skipModifier*(n: PType): PType {.inline.} = n.sons[^1] + +proc indexType*(n: PType): PType {.inline.} = n.sons[0] +proc baseClass*(n: PType): PType {.inline.} = n.sons[0] + +proc base*(t: PType): PType {.inline.} = + result = t.sons[0] + +proc returnType*(n: PType): PType {.inline.} = n.sons[0] +proc setReturnType*(n, r: PType) {.inline.} = n.sons[0] = r +proc setIndexType*(n, idx: PType) {.inline.} = n.sons[0] = idx + +proc firstParamType*(n: PType): PType {.inline.} = n.sons[1] + +proc typeBodyImpl*(n: PType): PType {.inline.} = n.sons[^1] proc skipTypes*(t: PType, kinds: TTypeKinds): PType = ## Used throughout the compiler code to test whether a type tree contains or @@ -1482,7 +1514,7 @@ proc skipTypes*(t: PType, kinds: TTypeKinds): PType = ## last child nodes of a type tree need to be searched. This is a really hot ## path within the compiler! result = t - while result.kind in kinds: result = lastSon(result) + while result.kind in kinds: result = last(result) proc newIntTypeNode*(intVal: BiggestInt, typ: PType): PNode = let kind = skipTypes(typ, abstractVarRange).kind @@ -1557,8 +1589,9 @@ proc newType*(kind: TTypeKind, idgen: IdGenerator; owner: PSym, sons: seq[PType] echo "KNID ", kind writeStackTrace() -template newType*(kind: TTypeKind, id: IdGenerator; owner: PSym, parent: PType): PType = - newType(kind, id, owner, parent.sons) +when false: + template newType*(kind: TTypeKind, id: IdGenerator; owner: PSym, parent: PType): PType = + newType(kind, id, owner, parent.sons) proc setSons*(dest: PType; sons: seq[PType]) {.inline.} = dest.sons = sons @@ -1574,7 +1607,10 @@ proc mergeLoc(a: var TLoc, b: TLoc) = if a.lode == nil: a.lode = b.lode if a.r == "": a.r = b.r -proc newSons*(father: Indexable, length: int) = +proc newSons*(father: PNode, length: int) = + setLen(father.sons, length) + +proc newSons*(father: PType, length: int) = setLen(father.sons, length) proc assignType*(dest, src: PType) = @@ -1665,7 +1701,7 @@ proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType = result = t var i = maxIters while result.kind in kinds: - result = lastSon(result) + result = last(result) dec i if i == 0: return nil @@ -1674,7 +1710,7 @@ proc skipTypesOrNil*(t: PType, kinds: TTypeKinds): PType = result = t while result != nil and result.kind in kinds: if result.len == 0: return nil - result = lastSon(result) + result = last(result) proc isGCedMem*(t: PType): bool {.inline.} = result = t.kind in {tyString, tyRef, tySequence} or @@ -2009,7 +2045,7 @@ proc toObject*(typ: PType): PType = ## cases should be a ``tyObject``). ## Otherwise ``typ`` is simply returned as-is. let t = typ.skipTypes({tyAlias, tyGenericInst}) - if t.kind == tyRef: t.lastSon + if t.kind == tyRef: t.last else: typ proc toObjectFromRefPtrGeneric*(typ: PType): PType = @@ -2026,7 +2062,7 @@ proc toObjectFromRefPtrGeneric*(typ: PType): PType = result = typ while true: case result.kind - of tyGenericBody: result = result.lastSon + of tyGenericBody: result = result.last of tyRef, tyPtr, tyGenericInst, tyGenericInvocation, tyAlias: result = result[0] # automatic dereferencing is deep, refs #18298. else: break diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index cd772f0f1..9b3a42ebe 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -43,7 +43,7 @@ proc typekinds*(t: PType) {.deprecated.} = while t != nil and t.len > 0: s.add $t.kind s.add " " - t = t.lastSon + t = t.last echo s template debug*(x: PSym|PType|PNode) {.deprecated.} = diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index ad84be3f9..c2887f00a 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -83,13 +83,13 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, var pl = callee & "(" & params # getUniqueType() is too expensive here: var typ = skipTypes(ri[0].typ, abstractInst) - if typ[0] != nil: + if typ.returnType != nil: if isInvalidReturnType(p.config, typ): if params.len != 0: pl.add(", ") # beware of 'result = p(result)'. We may need to allocate a temporary: if d.k in {locTemp, locNone} or not preventNrvo(p, d.lode, le, ri): # Great, we can use 'd': - if d.k == locNone: d = getTemp(p, typ[0], needsInit=true) + if d.k == locNone: d = getTemp(p, typ.returnType, needsInit=true) elif d.k notin {locTemp} and not hasNoInit(ri): # reset before pass as 'result' var: discard "resetLoc(p, d)" @@ -97,7 +97,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, pl.add(");\n") line(p, cpsStmts, pl) else: - var tmp: TLoc = getTemp(p, typ[0], needsInit=true) + var tmp: TLoc = getTemp(p, typ.returnType, needsInit=true) pl.add(addrLoc(p.config, tmp)) pl.add(");\n") line(p, cpsStmts, pl) @@ -115,23 +115,23 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, excl d.flags, lfSingleUse else: if d.k == locNone and p.splitDecls == 0: - d = getTempCpp(p, typ[0], pl) + d = getTempCpp(p, typ.returnType, pl) else: - if d.k == locNone: d = getTemp(p, typ[0]) + if d.k == locNone: d = getTemp(p, typ.returnType) var list = initLoc(locCall, d.lode, OnUnknown) list.r = pl genAssignment(p, d, list, {}) # no need for deep copying if canRaise: raiseExit(p) elif isHarmlessStore(p, canRaise, d): - if d.k == locNone: d = getTemp(p, typ[0]) + if d.k == locNone: d = getTemp(p, typ.returnType) assert(d.t != nil) # generate an assignment to d: var list = initLoc(locCall, d.lode, OnUnknown) list.r = pl genAssignment(p, d, list, {}) # no need for deep copying if canRaise: raiseExit(p) else: - var tmp: TLoc = getTemp(p, typ[0], needsInit=true) + var tmp: TLoc = getTemp(p, typ.returnType, needsInit=true) var list = initLoc(locCall, d.lode, OnUnknown) list.r = pl genAssignment(p, tmp, list, {}) # no need for deep copying @@ -248,7 +248,7 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode; result: var Rope) = of tyArray: result.add "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, a.t))] of tyPtr, tyRef: - case lastSon(a.t).kind + case elementType(a.t).kind of tyString, tySequence: var t: TLoc t.r = "(*$1)" % [a.rdLoc] @@ -256,7 +256,7 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode; result: var Rope) = [a.rdLoc, lenExpr(p, t), dataField(p), dataFieldAccessor(p, "*" & a.rdLoc)] of tyArray: - result.add "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, lastSon(a.t)))] + result.add "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, elementType(a.t)))] else: internalError(p.config, "openArrayLoc: " & typeToString(a.t)) else: internalError(p.config, "openArrayLoc: " & typeToString(a.t)) @@ -287,7 +287,7 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode; result: var Rope; need elif skipTypes(param.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: var n = if n.kind != nkHiddenAddr: n else: n[0] openArrayLoc(p, param.typ, n, result) - elif ccgIntroducedPtr(p.config, param, call[0].typ[0]) and + elif ccgIntroducedPtr(p.config, param, call[0].typ.returnType) and (optByRef notin param.options or not p.module.compileToCpp): a = initLocExpr(p, n) if n.kind in {nkCharLit..nkNilLit}: @@ -457,14 +457,14 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = let rawProc = getClosureType(p.module, typ, clHalf) let canRaise = p.config.exc == excGoto and canRaiseDisp(p, ri[0]) - if typ[0] != nil: + if typ.returnType != nil: if isInvalidReturnType(p.config, typ): if ri.len > 1: pl.add(", ") # beware of 'result = p(result)'. We may need to allocate a temporary: if d.k in {locTemp, locNone} or not preventNrvo(p, d.lode, le, ri): # Great, we can use 'd': if d.k == locNone: - d = getTemp(p, typ[0], needsInit=true) + d = getTemp(p, typ.returnType, needsInit=true) elif d.k notin {locTemp} and not hasNoInit(ri): # reset before pass as 'result' var: discard "resetLoc(p, d)" @@ -472,13 +472,13 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = genCallPattern() if canRaise: raiseExit(p) else: - var tmp: TLoc = getTemp(p, typ[0], needsInit=true) + var tmp: TLoc = getTemp(p, typ.returnType, needsInit=true) pl.add(addrLoc(p.config, tmp)) genCallPattern() if canRaise: raiseExit(p) genAssignment(p, d, tmp, {}) # no need for deep copying elif isHarmlessStore(p, canRaise, d): - if d.k == locNone: d = getTemp(p, typ[0]) + if d.k == locNone: d = getTemp(p, typ.returnType) assert(d.t != nil) # generate an assignment to d: var list: TLoc = initLoc(locCall, d.lode, OnUnknown) if tfIterator in typ.flags: @@ -488,7 +488,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = genAssignment(p, d, list, {}) # no need for deep copying if canRaise: raiseExit(p) else: - var tmp: TLoc = getTemp(p, typ[0]) + var tmp: TLoc = getTemp(p, typ.returnType) assert(d.t != nil) # generate an assignment to d: var list: TLoc = initLoc(locCall, d.lode, OnUnknown) if tfIterator in typ.flags: @@ -685,7 +685,7 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) = genPatternCall(p, ri, pat, typ, pl) # simpler version of 'fixupCall' that works with the pl+params combination: var typ = skipTypes(ri[0].typ, abstractInst) - if typ[0] != nil: + if typ.returnType != nil: if p.module.compileToCpp and lfSingleUse in d.flags: # do not generate spurious temporaries for C++! For C we're better off # with them to prevent undefined behaviour and because the codegen @@ -694,7 +694,7 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) = d.r = pl excl d.flags, lfSingleUse else: - if d.k == locNone: d = getTemp(p, typ[0]) + if d.k == locNone: d = getTemp(p, typ.returnType) assert(d.t != nil) # generate an assignment to d: var list: TLoc = initLoc(locCall, d.lode, OnUnknown) list.r = pl @@ -752,26 +752,26 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = pl.add(param.name.s) pl.add(": ") genArg(p, ri[i], param, ri, pl) - if typ[0] != nil: + if typ.returnType != nil: if isInvalidReturnType(p.config, typ): if ri.len > 1: pl.add(" ") # beware of 'result = p(result)'. We always allocate a temporary: if d.k in {locTemp, locNone}: # We already got a temp. Great, special case it: - if d.k == locNone: d = getTemp(p, typ[0], needsInit=true) + if d.k == locNone: d = getTemp(p, typ.returnType, needsInit=true) pl.add("Result: ") pl.add(addrLoc(p.config, d)) pl.add("];\n") line(p, cpsStmts, pl) else: - var tmp: TLoc = getTemp(p, typ[0], needsInit=true) + var tmp: TLoc = getTemp(p, typ.returnType, needsInit=true) pl.add(addrLoc(p.config, tmp)) pl.add("];\n") line(p, cpsStmts, pl) genAssignment(p, d, tmp, {}) # no need for deep copying else: pl.add("]") - if d.k == locNone: d = getTemp(p, typ[0]) + if d.k == locNone: d = getTemp(p, typ.returnType) assert(d.t != nil) # generate an assignment to d: var list: TLoc = initLoc(locCall, ri, OnUnknown) list.r = pl diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 2612c5c12..750398092 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -748,7 +748,7 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc) = var a: TLoc var typ = e[0].typ if typ.kind in {tyUserTypeClass, tyUserTypeClassInst} and typ.isResolvedUserTypeClass: - typ = typ.lastSon + typ = typ.last typ = typ.skipTypes(abstractInstOwned) if typ.kind in {tyVar} and tfVarIsPtr notin typ.flags and p.module.compileToCpp and e[0].kind == nkHiddenAddr: d = initLocExprSingleUse(p, e[0][0]) @@ -853,7 +853,7 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) = var a: TLoc = default(TLoc) if p.module.compileToCpp and e.kind == nkDotExpr and e[1].kind == nkSym and e[1].typ.kind == tyPtr: # special case for C++: we need to pull the type of the field as member and friends require the complete type. - let typ = e[1].typ[0] + let typ = e[1].typ.elementType if typ.itemId in p.module.g.graph.memberProcsPerType: discard getTypeDesc(p.module, typ) @@ -1082,7 +1082,8 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) = var b = initLocExpr(p, y) var ty = skipTypes(a.t, abstractVarRange) if ty.kind in {tyRef, tyPtr}: - ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check: + ty = skipTypes(ty.elementType, abstractVarRange) + # emit range check: if optBoundsCheck in p.options: linefmt(p, cpsStmts, "if ($1 < 0 || $1 >= $2){ #raiseIndexError2($1,$2-1); ", @@ -1102,7 +1103,7 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) = proc genBracketExpr(p: BProc; n: PNode; d: var TLoc) = var ty = skipTypes(n[0].typ, abstractVarRange + tyUserTypeClasses) - if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange) + if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.elementType, abstractVarRange) case ty.kind of tyUncheckedArray: genUncheckedArrayElem(p, n, n[0], n[1], d) of tyArray: genArrayElem(p, n, n[0], n[1], d) @@ -1362,7 +1363,7 @@ proc rawGenNew(p: BProc, a: var TLoc, sizeExpr: Rope; needsInit: bool) = var b: TLoc = initLoc(locExpr, a.lode, OnHeap) let refType = typ.skipTypes(abstractInstOwned) assert refType.kind == tyRef - let bt = refType.lastSon + let bt = refType.elementType if sizeExpr == "": sizeExpr = "sizeof($1)" % [getTypeDesc(p.module, bt)] @@ -1452,7 +1453,7 @@ proc genNewSeq(p: BProc, e: PNode) = let seqtype = skipTypes(e[1].typ, abstractVarRange) linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3), NIM_ALIGNOF($3));$n", [a.rdLoc, b.rdLoc, - getTypeDesc(p.module, seqtype.lastSon), + getTypeDesc(p.module, seqtype.elementType), getSeqPayloadType(p.module, seqtype)]) else: let lenIsZero = e[2].kind == nkIntLit and e[2].intVal == 0 @@ -1465,7 +1466,7 @@ proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) = if optSeqDestructors in p.config.globalOptions: if d.k == locNone: d = getTemp(p, e.typ, needsInit=false) linefmt(p, cpsStmts, "$1.len = 0; $1.p = ($4*) #newSeqPayloadUninit($2, sizeof($3), NIM_ALIGNOF($3));$n", - [d.rdLoc, a.rdLoc, getTypeDesc(p.module, seqtype.lastSon), + [d.rdLoc, a.rdLoc, getTypeDesc(p.module, seqtype.elementType), getSeqPayloadType(p.module, seqtype), ]) else: @@ -1544,7 +1545,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = r = rdLoc(tmp) if isRef: rawGenNew(p, tmp, "", needsInit = nfAllFieldsSet notin e.flags) - t = t.lastSon.skipTypes(abstractInstOwned) + t = t.elementType.skipTypes(abstractInstOwned) r = "(*$1)" % [r] gcUsage(p.config, e) elif needsZeroMem: @@ -1590,7 +1591,7 @@ proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) = if optSeqDestructors in p.config.globalOptions: let seqtype = n.typ linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3), NIM_ALIGNOF($3));$n", - [rdLoc dest[], lit, getTypeDesc(p.module, seqtype.lastSon), + [rdLoc dest[], lit, getTypeDesc(p.module, seqtype.elementType), getSeqPayloadType(p.module, seqtype)]) else: # generate call to newSeq before adding the elements per hand: @@ -1623,7 +1624,7 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) = if optSeqDestructors in p.config.globalOptions: let seqtype = n.typ linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3), NIM_ALIGNOF($3));$n", - [rdLoc d, L, getTypeDesc(p.module, seqtype.lastSon), + [rdLoc d, L, getTypeDesc(p.module, seqtype.elementType), getSeqPayloadType(p.module, seqtype)]) else: var lit = newRopeAppender() @@ -1665,9 +1666,9 @@ proc genNewFinalize(p: BProc, e: PNode) = p.module.s[cfsTypeInit3].addf("$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)]) b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [ getTypeDesc(p.module, refType), - ti, getTypeDesc(p.module, skipTypes(refType.lastSon, abstractRange))]) + ti, getTypeDesc(p.module, skipTypes(refType.elementType, abstractRange))]) genAssignment(p, a, b, {}) # set the object type: - bt = skipTypes(refType.lastSon, abstractRange) + bt = skipTypes(refType.elementType, abstractRange) genObjectInit(p, cpsStmts, bt, a, constructRefObj) gcUsage(p.config, e) @@ -1699,12 +1700,12 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) = if t.kind notin {tyVar, tyLent}: nilCheck = r if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp: r = ropecg(p.module, "(*$1)", [r]) - t = skipTypes(t.lastSon, typedescInst+{tyOwned}) + t = skipTypes(t.elementType, typedescInst+{tyOwned}) discard getTypeDesc(p.module, t) if not p.module.compileToCpp: - while t.kind == tyObject and t[0] != nil: + while t.kind == tyObject and t.baseClass != nil: r.add(".Sup") - t = skipTypes(t[0], skipPtrs) + t = skipTypes(t.baseClass, skipPtrs) if isObjLackingTypeField(t): globalError(p.config, x.info, "no 'of' operator available for pure objects") @@ -1788,13 +1789,13 @@ proc rdMType(p: BProc; a: TLoc; nilCheck: var Rope; result: var Rope; enforceV1 if t.kind notin {tyVar, tyLent}: nilCheck = derefs if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp: derefs = "(*$1)" % [derefs] - t = skipTypes(t.lastSon, abstractInst) + t = skipTypes(t.elementType, abstractInst) result.add derefs discard getTypeDesc(p.module, t) if not p.module.compileToCpp: - while t.kind == tyObject and t[0] != nil: + while t.kind == tyObject and t.baseClass != nil: result.add(".Sup") - t = skipTypes(t[0], skipPtrs) + t = skipTypes(t.baseClass, skipPtrs) result.add ".m_type" if optTinyRtti in p.config.globalOptions and enforceV1: result.add "->typeInfoV1" @@ -2355,7 +2356,7 @@ proc genDestroy(p: BProc; n: PNode) = linefmt(p, cpsStmts, "if ($1.p && !($1.p->cap & NIM_STRLIT_FLAG)) {$n" & " #alignedDealloc($1.p, NIM_ALIGNOF($2));$n" & "}$n", - [rdLoc(a), getTypeDesc(p.module, t.lastSon)]) + [rdLoc(a), getTypeDesc(p.module, t.elementType)]) else: discard "nothing to do" else: let t = n[1].typ.skipTypes(abstractVar) @@ -2366,7 +2367,7 @@ proc genDestroy(p: BProc; n: PNode) = proc genDispose(p: BProc; n: PNode) = when false: - let elemType = n[1].typ.skipTypes(abstractVar).lastSon + let elemType = n[1].typ.skipTypes(abstractVar).elementType var a: TLoc = initLocExpr(p, n[1].skipAddr) @@ -2381,7 +2382,7 @@ proc genDispose(p: BProc; n: PNode) = lineCg(p, cpsStmts, ["#nimDestroyAndDispose($#)", rdLoc(a)]) proc genSlice(p: BProc; e: PNode; d: var TLoc) = - let (x, y) = genOpenArraySlice(p, e, e.typ, e.typ.lastSon, + let (x, y) = genOpenArraySlice(p, e, e.typ, e.typ.elementType, prepareForMutation = e[1].kind == nkHiddenDeref and e[1].typ.skipTypes(abstractInst).kind == tyString and p.config.selectedGC in {gcArc, gcAtomicArc, gcOrc}) @@ -3199,9 +3200,9 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo; result: var Rope) = result.add "}" of tyArray: result.add "{" - for i in 0..<toInt(lengthOrd(p.config, t[0])): + for i in 0..<toInt(lengthOrd(p.config, t.indexType)): if i > 0: result.add ", " - getDefaultValue(p, t[1], info, result) + getDefaultValue(p, t.elementType, info, result) result.add "}" #result = rope"{}" of tyOpenArray, tyVarargs: @@ -3308,7 +3309,7 @@ proc genConstObjConstr(p: BProc; n: PNode; isConst: bool; result: var Rope) = proc genConstSimpleList(p: BProc, n: PNode; isConst: bool; result: var Rope) = result.add "{" if p.vccAndC and n.len == 0 and n.typ.kind == tyArray: - getDefaultValue(p, n.typ[1], n.info, result) + getDefaultValue(p, n.typ.elementType, n.info, result) for i in 0..<n.len: let it = n[i] if i > 0: result.add ",\n" diff --git a/compiler/ccgreset.nim b/compiler/ccgreset.nim index 47b6a1e15..da7f37398 100644 --- a/compiler/ccgreset.nim +++ b/compiler/ccgreset.nim @@ -54,13 +54,13 @@ proc specializeResetT(p: BProc, accessor: Rope, typ: PType) = case typ.kind of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred, tySink, tyOwned: - specializeResetT(p, accessor, lastSon(typ)) + specializeResetT(p, accessor, skipModifier(typ)) of tyArray: - let arraySize = lengthOrd(p.config, typ[0]) + let arraySize = lengthOrd(p.config, typ.indexType) var i: TLoc = getTemp(p, getSysType(p.module.g.graph, unknownLineInfo, tyInt)) linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n", [i.r, arraySize]) - specializeResetT(p, ropecg(p.module, "$1[$2]", [accessor, i.r]), typ[1]) + specializeResetT(p, ropecg(p.module, "$1[$2]", [accessor, i.r]), typ.elementType) lineF(p, cpsStmts, "}$n", []) of tyObject: for i in 0..<typ.len: diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index adad9df3e..288398e32 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -71,16 +71,16 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) = case typ.kind of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred, tySink, tyOwned: - genTraverseProc(c, accessor, lastSon(typ)) + genTraverseProc(c, accessor, skipModifier(typ)) of tyArray: - let arraySize = lengthOrd(c.p.config, typ[0]) + let arraySize = lengthOrd(c.p.config, typ.indexType) var i: TLoc = getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo, tyInt)) var oldCode = p.s(cpsStmts) freeze oldCode linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n", [i.r, arraySize]) let oldLen = p.s(cpsStmts).len - genTraverseProc(c, ropecg(c.p.module, "$1[$2]", [accessor, i.r]), typ[1]) + genTraverseProc(c, ropecg(c.p.module, "$1[$2]", [accessor, i.r]), typ.elementType) if p.s(cpsStmts).len == oldLen: # do not emit dummy long loops for faster debug builds: p.s(cpsStmts) = oldCode @@ -101,7 +101,7 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) = of tySequence: if optSeqDestructors notin c.p.module.config.globalOptions: lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt]) - elif containsGarbageCollectedRef(typ.lastSon): + elif containsGarbageCollectedRef(typ.elementType): # destructor based seqs are themselves not traced but their data is, if # they contain a GC'ed type: lineCg(p, cpsStmts, "#nimGCvisitSeq((void*)$1, $2);$n", [accessor, c.visitorFrmt]) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 462b08a43..751a1fecb 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -136,10 +136,10 @@ proc getTypeName(m: BModule; typ: PType; sig: SigHash): Rope = return t.sym.loc.r if t.kind in irrelevantForBackend: - t = t.lastSon + t = t.skipModifier else: break - let typ = if typ.kind in {tyAlias, tySink, tyOwned}: typ.lastSon else: typ + let typ = if typ.kind in {tyAlias, tySink, tyOwned}: typ.elementType else: typ if typ.loc.r == "": typ.typeName(typ.loc.r) typ.loc.r.add $sig @@ -175,10 +175,10 @@ proc mapType(conf: ConfigRef; typ: PType; isParam: bool): TCTypeKind = of tyObject, tyTuple: result = ctStruct of tyUserTypeClasses: doAssert typ.isResolvedUserTypeClass - return mapType(conf, typ.lastSon, isParam) + return mapType(conf, typ.skipModifier, isParam) of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias, tySink, tyInferred, tyOwned: - result = mapType(conf, lastSon(typ), isParam) + result = mapType(conf, skipModifier(typ), isParam) of tyEnum: if firstOrd(conf, typ) < 0: result = ctInt32 @@ -189,9 +189,9 @@ proc mapType(conf: ConfigRef; typ: PType; isParam: bool): TCTypeKind = of 4: result = ctInt32 of 8: result = ctInt64 else: result = ctInt32 - of tyRange: result = mapType(conf, typ[0], isParam) + of tyRange: result = mapType(conf, typ.elementType, isParam) of tyPtr, tyVar, tyLent, tyRef: - var base = skipTypes(typ.lastSon, typedescInst) + var base = skipTypes(typ.elementType, typedescInst) case base.kind of tyOpenArray, tyArray, tyVarargs, tyUncheckedArray: result = ctPtrToArray of tySet: @@ -206,7 +206,7 @@ proc mapType(conf: ConfigRef; typ: PType; isParam: bool): TCTypeKind = of tyInt..tyUInt64: result = TCTypeKind(ord(typ.kind) - ord(tyInt) + ord(ctInt)) of tyStatic: - if typ.n != nil: result = mapType(conf, lastSon typ, isParam) + if typ.n != nil: result = mapType(conf, typ.skipModifier, isParam) else: result = ctVoid doAssert(false, "mapType: " & $typ.kind) @@ -235,7 +235,7 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes proc isObjLackingTypeField(typ: PType): bool {.inline.} = result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and - (typ[0] == nil) or isPureObject(typ)) + (typ.baseClass == nil) or isPureObject(typ)) proc isInvalidReturnType(conf: ConfigRef; typ: PType, isProc = true): bool = # Arrays and sets cannot be returned by a C procedure, because C is @@ -326,12 +326,12 @@ proc getSimpleTypeDesc(m: BModule; typ: PType): Rope = result = typeNameOrLiteral(m, typ, NumericalTypeToStr[typ.kind]) of tyDistinct, tyRange, tyOrdinal: result = getSimpleTypeDesc(m, typ[0]) of tyStatic: - if typ.n != nil: result = getSimpleTypeDesc(m, lastSon typ) + if typ.n != nil: result = getSimpleTypeDesc(m, skipModifier typ) else: result = "" internalError(m.config, "tyStatic for getSimpleTypeDesc") of tyGenericInst, tyAlias, tySink, tyOwned: - result = getSimpleTypeDesc(m, lastSon typ) + result = getSimpleTypeDesc(m, skipModifier typ) else: result = "" if result != "" and typ.isImportedType(): @@ -501,13 +501,13 @@ proc genMemberProcParams(m: BModule; prc: PSym, superCall, rettype, name, params let isCtor = sfConstructor in prc.flags if isCtor or (name[0] == '~' and sfMember in prc.flags): #destructors cant have void rettype = "" - elif t[0] == nil or isInvalidReturnType(m.config, t): + elif t.returnType == nil or isInvalidReturnType(m.config, t): rettype = "void" else: if rettype == "": - rettype = getTypeDescAux(m, t[0], check, dkResult) + rettype = getTypeDescAux(m, t.returnType, check, dkResult) else: - rettype = runtimeFormat(rettype.replace("'0", "$1"), [getTypeDescAux(m, t[0], check, dkResult)]) + rettype = runtimeFormat(rettype.replace("'0", "$1"), [getTypeDescAux(m, t.returnType, check, dkResult)]) var types, names, args: seq[string] = @[] if not isCtor: var this = t.n[1].sym @@ -535,7 +535,7 @@ proc genMemberProcParams(m: BModule; prc: PSym, superCall, rettype, name, params fillParamName(m, param) fillLoc(param.loc, locParam, t.n[i], param.paramStorageLoc) - if ccgIntroducedPtr(m.config, param, t[0]) and descKind == dkParam: + if ccgIntroducedPtr(m.config, param, t.returnType) and descKind == dkParam: typ = getTypeDescWeak(m, param.typ, check, descKind) & "*" incl(param.loc.flags, lfIndirect) param.loc.storage = OnUnknown @@ -573,10 +573,10 @@ proc genProcParams(m: BModule; t: PType, rettype, params: var Rope, check: var IntSet, declareEnvironment=true; weakDep=false;) = params = "(" - if t[0] == nil or isInvalidReturnType(m.config, t): + if t.returnType == nil or isInvalidReturnType(m.config, t): rettype = "void" else: - rettype = getTypeDescAux(m, t[0], check, dkResult) + rettype = getTypeDescAux(m, t.returnType, check, dkResult) for i in 1..<t.n.len: if t.n[i].kind != nkSym: internalError(m.config, t.n.info, "genProcParams") var param = t.n[i].sym @@ -592,7 +592,7 @@ proc genProcParams(m: BModule; t: PType, rettype, params: var Rope, fillLoc(param.loc, locParam, t.n[i], param.paramStorageLoc) var typ: Rope - if ccgIntroducedPtr(m.config, param, t[0]) and descKind == dkParam: + if ccgIntroducedPtr(m.config, param, t.returnType) and descKind == dkParam: typ = (getTypeDescWeak(m, param.typ, check, descKind)) typ.add("*") incl(param.loc.flags, lfIndirect) @@ -611,7 +611,7 @@ proc genProcParams(m: BModule; t: PType, rettype, params: var Rope, params.add runtimeFormat(param.cgDeclFrmt, [typ, param.loc.r]) # declare the len field for open arrays: var arr = param.typ.skipTypes({tyGenericInst}) - if arr.kind in {tyVar, tyLent, tySink}: arr = arr.lastSon + if arr.kind in {tyVar, tyLent, tySink}: arr = arr.elementType var j = 0 while arr.kind in {tyOpenArray, tyVarargs}: # this fixes the 'sort' bug: @@ -620,10 +620,10 @@ proc genProcParams(m: BModule; t: PType, rettype, params: var Rope, params.addf(", NI $1Len_$2", [param.loc.r, j.rope]) inc(j) arr = arr[0].skipTypes({tySink}) - if t[0] != nil and isInvalidReturnType(m.config, t): - var arr = t[0] + if t.returnType != nil and isInvalidReturnType(m.config, t): + var arr = t.returnType if params != "(": params.add(", ") - if mapReturnType(m.config, t[0]) != ctArray: + if mapReturnType(m.config, arr) != ctArray: if isHeaderFile in m.flags: # still generates types for `--header` params.add(getTypeDescAux(m, arr, check, dkResult)) @@ -777,7 +777,7 @@ proc getRecordDescAux(m: BModule; typ: PType, name, baseType: Rope, check: var IntSet, hasField:var bool): Rope = result = "" if typ.kind == tyObject: - if typ[0] == nil: + if typ.baseClass == nil: if lacksMTypeField(typ): appcg(m, result, " {$n", []) else: @@ -817,8 +817,8 @@ proc getRecordDesc(m: BModule; typ: PType, name: Rope, else: structOrUnion = structOrUnion(typ) var baseType: string = "" - if typ[0] != nil: - baseType = getTypeDescAux(m, typ[0].skipTypes(skipPtrs), check, dkField) + if typ.baseClass != nil: + baseType = getTypeDescAux(m, typ.baseClass.skipTypes(skipPtrs), check, dkField) if typ.sym == nil or sfCodegenDecl notin typ.sym.flags: result = structOrUnion & " " & name result.add(getRecordDescAux(m, typ, name, baseType, check, hasField)) @@ -922,7 +922,7 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes of tyRef, tyPtr, tyVar, tyLent: var star = if t.kind in {tyVar} and tfVarIsPtr notin origTyp.flags and compileToCpp(m): "&" else: "*" - var et = origTyp.skipTypes(abstractInst).lastSon + var et = origTyp.skipTypes(abstractInst).elementType var etB = et.skipTypes(abstractInst) if mapType(m.config, t, kind == dkParam) == ctPtrToArray and (etB.kind != tyOpenArray or kind == dkParam): if etB.kind == tySet: @@ -1014,7 +1014,7 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes assert(cacheGetType(m.typeCache, sig) == "") m.typeCache[sig] = result & seqStar(m) if not isImportedType(t): - if skipTypes(t[0], typedescInst).kind != tyEmpty: + if skipTypes(t.elementType, typedescInst).kind != tyEmpty: const cppSeq = "struct $2 : #TGenericSeq {$n" cSeq = "struct $2 {$n" & @@ -1022,11 +1022,11 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes if m.compileToCpp: appcg(m, m.s[cfsSeqTypes], cppSeq & " $1 data[SEQ_DECL_SIZE];$n" & - "};$n", [getTypeDescAux(m, t[0], check, kind), result]) + "};$n", [getTypeDescAux(m, t.elementType, check, kind), result]) else: appcg(m, m.s[cfsSeqTypes], cSeq & " $1 data[SEQ_DECL_SIZE];$n" & - "};$n", [getTypeDescAux(m, t[0], check, kind), result]) + "};$n", [getTypeDescAux(m, t.elementType, check, kind), result]) else: result = rope("TGenericSeq") result.add(seqStar(m)) @@ -1034,7 +1034,7 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes result = getTypeName(m, origTyp, sig) m.typeCache[sig] = result if not isImportedType(t): - let foo = getTypeDescAux(m, t[0], check, kind) + let foo = getTypeDescAux(m, t.elementType, check, kind) m.s[cfsTypes].addf("typedef $1 $2[1];$n", [foo, result]) of tyArray: var n: BiggestInt = toInt64(lengthOrd(m.config, t)) @@ -1042,9 +1042,9 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes result = getTypeName(m, origTyp, sig) m.typeCache[sig] = result if not isImportedType(t): - let foo = getTypeDescAux(m, t[1], check, kind) + let e = getTypeDescAux(m, t.elementType, check, kind) m.s[cfsTypes].addf("typedef $1 $2[$3];$n", - [foo, result, rope(n)]) + [e, result, rope(n)]) of tyObject, tyTuple: let tt = origTyp.skipTypes({tyDistinct}) if isImportedCppType(t) and tt.kind == tyGenericInst: @@ -1112,8 +1112,8 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes of tySet: # Don't use the imported name as it may be scoped: 'Foo::SomeKind' result = rope("tySet_") - t.lastSon.typeName(result) - result.add $t.lastSon.hashType(m.config) + t.elementType.typeName(result) + result.add $t.elementType.hashType(m.config) m.typeCache[sig] = result if not isImportedType(t): let s = int(getSize(m.config, t)) @@ -1123,7 +1123,7 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes [result, rope(getSize(m.config, t))]) of tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias, tySink, tyOwned, tyUserTypeClass, tyUserTypeClassInst, tyInferred: - result = getTypeDescAux(m, lastSon(t), check, kind) + result = getTypeDescAux(m, skipModifier(t), check, kind) else: internalError(m.config, "getTypeDescAux(" & $t.kind & ')') result = "" @@ -1204,11 +1204,11 @@ proc genMemberProcHeader(m: BModule; prc: PSym; result: var Rope; asPtr: bool = var memberOp = "#." #only virtual var typ: PType if isCtor: - typ = prc.typ[0] + typ = prc.typ.returnType else: - typ = prc.typ[1] + typ = prc.typ.firstParamType if typ.kind == tyPtr: - typ = typ[0] + typ = typ.elementType memberOp = "#->" var typDesc = getTypeDescWeak(m, typ, check, dkParam) let asPtrStr = rope(if asPtr: "_PTR" else: "") @@ -1333,8 +1333,8 @@ 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.lastSon != nil: - var x = typ.lastSon + if typ.len > 0 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): base = rope("0") @@ -1439,22 +1439,20 @@ proc genObjectFields(m: BModule; typ, origType: PType, n: PNode, expr: Rope; else: internalError(m.config, n.info, "genObjectFields") proc genObjectInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo) = - if typ.kind == tyObject: - if incompleteType(typ): - localError(m.config, info, "request for RTTI generation for incomplete object: " & - typeToString(typ)) - genTypeInfoAux(m, typ, origType, name, info) - else: - genTypeInfoAuxBase(m, typ, origType, name, rope("0"), info) + assert typ.kind == tyObject + if incompleteType(typ): + localError(m.config, info, "request for RTTI generation for incomplete object: " & + typeToString(typ)) + genTypeInfoAux(m, typ, origType, name, info) var tmp = getNimNode(m) if not isImportedType(typ): genObjectFields(m, typ, origType, typ.n, tmp, info) m.s[cfsTypeInit3].addf("$1.node = &$2;$n", [tiNameForHcr(m, name), tmp]) - var t = typ[0] + var t = typ.baseClass while t != nil: t = t.skipTypes(skipPtrs) t.flags.incl tfObjHasKids - t = t[0] + t = t.baseClass proc genTupleInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo) = genTypeInfoAuxBase(m, typ, typ, name, rope("0"), info) @@ -1520,14 +1518,14 @@ proc genEnumInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) = m.s[cfsTypeInit3].addf("$1.flags = 1<<2;$n", [tiNameForHcr(m, name)]) proc genSetInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) = - assert(typ[0] != nil) + assert(typ.elementType != nil) genTypeInfoAux(m, typ, typ, name, info) var tmp = getNimNode(m) m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 0;$n$3.node = &$1;$n", [tmp, rope(firstOrd(m.config, typ)), tiNameForHcr(m, name)]) proc genArrayInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) = - genTypeInfoAuxBase(m, typ, typ, name, genTypeInfoV1(m, typ[1], info), info) + genTypeInfoAuxBase(m, typ, typ, name, genTypeInfoV1(m, typ.elementType, info), info) proc fakeClosureType(m: BModule; owner: PSym): PType = # we generate the same RTTI as for a tuple[pointer, ref tuple[]] @@ -1596,14 +1594,14 @@ proc generateRttiDestructor(g: ModuleGraph; typ: PType; owner: PSym; kind: TType n[paramsPos] = result.typ.n let body = newNodeI(nkStmtList, info) let castType = makePtrType(typ, idgen) - if theProc.typ[1].kind != tyVar: + if theProc.typ.firstParamType.kind != tyVar: body.add newTreeI(nkCall, info, newSymNode(theProc), newDeref(newTreeIT( nkCast, info, castType, newNodeIT(nkType, info, castType), newSymNode(dest) )) ) else: - let addrOf = newNodeIT(nkAddr, info, theProc.typ[1]) + let addrOf = newNodeIT(nkAddr, info, theProc.typ.firstParamType) addrOf.add newDeref(newTreeIT( nkCast, info, castType, newNodeIT(nkType, info, castType), newSymNode(dest) @@ -1731,7 +1729,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[0] != nil and optEnableDeepCopy in m.config.globalOptions: + if t.kind == tyObject and t.len > 0 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) = @@ -1781,7 +1779,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[0] != nil and optEnableDeepCopy in m.config.globalOptions: + if t.kind == tyObject and t.len > 0 and t.baseClass != nil and optEnableDeepCopy in m.config.globalOptions: discard genTypeInfoV1(m, t, info) proc genTypeInfoV2(m: BModule; t: PType; info: TLineInfo): Rope = @@ -1827,7 +1825,7 @@ proc openArrayToTuple(m: BModule; t: PType): PType = result = newType(tyTuple, m.idgen, t.owner) let p = newType(tyPtr, m.idgen, t.owner) let a = newType(tyUncheckedArray, m.idgen, t.owner) - a.add t.lastSon + a.add t.elementType p.add a result.add p result.add getSysType(m.g.graph, t.owner.info, tyInt) @@ -1909,11 +1907,11 @@ proc genTypeInfoV1(m: BModule; t: PType; info: TLineInfo): Rope = of tyPointer, tyBool, tyChar, tyCstring, tyString, tyInt..tyUInt64, tyVar, tyLent: genTypeInfoAuxBase(m, t, t, result, rope"0", info) of tyStatic: - if t.n != nil: result = genTypeInfoV1(m, lastSon t, info) + if t.n != nil: result = genTypeInfoV1(m, skipModifier t, info) else: internalError(m.config, "genTypeInfoV1(" & $t.kind & ')') of tyUserTypeClasses: internalAssert m.config, t.isResolvedUserTypeClass - return genTypeInfoV1(m, t.lastSon, info) + return genTypeInfoV1(m, t.skipModifier, info) of tyProc: if t.callConv != ccClosure: genTypeInfoAuxBase(m, t, t, result, rope"0", info) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index d22a6bdc2..b6456a7b8 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1171,7 +1171,7 @@ proc genProcAux*(m: BModule, prc: PSym) = let tmpInfo = prc.info discard freshLineInfo(p, prc.info) - if sfPure notin prc.flags and prc.typ[0] != nil: + if sfPure notin prc.flags and prc.typ.returnType != nil: if resultPos >= prc.ast.len: internalError(m.config, prc.info, "proc has no result symbol") let resNode = prc.ast[resultPos] @@ -1217,7 +1217,7 @@ proc genProcAux*(m: BModule, prc: PSym) = for i in 1..<prc.typ.n.len: let param = prc.typ.n[i].sym if param.typ.isCompileTimeOnly: continue - assignParam(p, param, prc.typ[0]) + assignParam(p, param, prc.typ.returnType) closureSetup(p, prc) genProcBody(p, procBody) diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 833bb6fe5..6bfa6d789 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -79,8 +79,8 @@ proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult = aa = skipTypes(aa, {tyGenericInst, tyAlias}) bb = skipTypes(bb, {tyGenericInst, tyAlias}) if aa.kind == bb.kind and aa.kind in {tyVar, tyPtr, tyRef, tyLent, tySink}: - aa = aa.lastSon - bb = bb.lastSon + aa = aa.elementType + bb = bb.elementType else: break if sameType(a.typ[i], b.typ[i]): @@ -102,10 +102,10 @@ proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult = if result == Yes: # check for return type: # ignore flags of return types; # bug #22673 - if not sameTypeOrNil(a.typ[0], b.typ[0], {IgnoreFlags}): - if b.typ[0] != nil and b.typ[0].kind == tyUntyped: + if not sameTypeOrNil(a.typ.returnType, b.typ.returnType, {IgnoreFlags}): + if b.typ.returnType != nil and b.typ.returnType.kind == tyUntyped: # infer 'auto' from the base to make it consistent: - b.typ[0] = a.typ[0] + b.typ.setReturnType a.typ.returnType else: return No @@ -132,7 +132,7 @@ proc createDispatcher(s: PSym; g: ModuleGraph; idgen: IdGenerator): PSym = disp.ast = copyTree(s.ast) disp.ast[bodyPos] = newNodeI(nkEmpty, s.info) disp.loc.r = "" - if s.typ[0] != nil: + if s.typ.returnType != nil: if disp.ast.len > resultPos: disp.ast[resultPos].sym = copySym(s.ast[resultPos].sym, idgen) else: @@ -157,9 +157,10 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) = proc methodDef*(g: ModuleGraph; idgen: IdGenerator; s: PSym) = var witness: PSym = nil - if s.typ[1].owner.getModule != s.getModule and vtables in g.config.features and not g.config.isDefined("nimInternalNonVtablesTesting"): + if s.typ.firstParamType.owner.getModule != s.getModule and vtables in g.config.features and not + g.config.isDefined("nimInternalNonVtablesTesting"): localError(g.config, s.info, errGenerated, "method `" & s.name.s & - "` can be defined only in the same module with its type (" & s.typ[1].typeToString() & ")") + "` can be defined only in the same module with its type (" & s.typ.firstParamType.typeToString() & ")") for i in 0..<g.methods.len: let disp = g.methods[i].dispatcher case sameMethodBucket(disp, s, multimethods = optMultiMethods in g.config.globalOptions) @@ -179,10 +180,10 @@ proc methodDef*(g: ModuleGraph; idgen: IdGenerator; s: PSym) = if witness.isNil: witness = g.methods[i].methods[0] # create a new dispatcher: # stores the id and the position - if s.typ[1].skipTypes(skipPtrs).itemId notin g.bucketTable: - g.bucketTable[s.typ[1].skipTypes(skipPtrs).itemId] = 1 + if s.typ.firstParamType.skipTypes(skipPtrs).itemId notin g.bucketTable: + g.bucketTable[s.typ.firstParamType.skipTypes(skipPtrs).itemId] = 1 else: - g.bucketTable.inc(s.typ[1].skipTypes(skipPtrs).itemId) + g.bucketTable.inc(s.typ.firstParamType.skipTypes(skipPtrs).itemId) g.methods.add((methods: @[s], dispatcher: createDispatcher(s, g, idgen))) #echo "adding ", s.info if witness != nil: @@ -263,7 +264,7 @@ proc genIfDispatcher*(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet; cond = a else: cond = isn - let retTyp = base.typ[0] + let retTyp = base.typ.returnType let call = newNodeIT(nkCall, base.info, retTyp) call.add newSymNode(curr) for col in 1..<paramLen: diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim index 4e4523601..122a69da6 100644 --- a/compiler/closureiters.nim +++ b/compiler/closureiters.nim @@ -198,7 +198,7 @@ proc newEnvVar(ctx: var Ctx, name: string, typ: PType): PSym = else: let envParam = getEnvParam(ctx.fn) # let obj = envParam.typ.lastSon - result = addUniqueField(envParam.typ.lastSon, result, ctx.g.cache, ctx.idgen) + result = addUniqueField(envParam.typ.elementType, result, ctx.g.cache, ctx.idgen) proc newEnvVarAccess(ctx: Ctx, s: PSym): PNode = if ctx.stateVarSym.isNil: @@ -208,7 +208,7 @@ proc newEnvVarAccess(ctx: Ctx, s: PSym): PNode = proc newTmpResultAccess(ctx: var Ctx): PNode = if ctx.tmpResultSym.isNil: - ctx.tmpResultSym = ctx.newEnvVar(":tmpResult", ctx.fn.typ[0]) + ctx.tmpResultSym = ctx.newEnvVar(":tmpResult", ctx.fn.typ.returnType) ctx.newEnvVarAccess(ctx.tmpResultSym) proc newUnrollFinallyAccess(ctx: var Ctx, info: TLineInfo): PNode = @@ -831,7 +831,7 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode = let retStmt = if ctx.nearestFinally == 0: # last finally, we can return - let retValue = if ctx.fn.typ[0].isNil: + let retValue = if ctx.fn.typ.returnType.isNil: ctx.g.emptyNode else: newTree(nkFastAsgn, diff --git a/compiler/concepts.nim b/compiler/concepts.nim index 037060417..01bfc542d 100644 --- a/compiler/concepts.nim +++ b/compiler/concepts.nim @@ -96,7 +96,7 @@ proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool = ignorableForArgType = {tyVar, tySink, tyLent, tyOwned, tyGenericInst, tyAlias, tyInferred} case f.kind of tyAlias: - result = matchType(c, f.lastSon, a, m) + result = matchType(c, f.skipModifier, a, m) of tyTypeDesc: if isSelf(f): #let oldLen = m.inferred.len @@ -136,7 +136,7 @@ proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool = m.inferred.add((f, ak)) elif m.magic == mArrGet and ak.kind in {tyArray, tyOpenArray, tySequence, tyVarargs, tyCstring, tyString}: when logBindings: echo "B adding ", f, " ", lastSon ak - m.inferred.add((f, lastSon ak)) + m.inferred.add((f, last ak)) result = true else: when logBindings: echo "C adding ", f, " ", ak @@ -252,7 +252,7 @@ proc matchSym(c: PContext; candidate: PSym, n: PNode; m: var MatchCon): bool = m.inferred.setLen oldLen return false - if not matchReturnType(c, n[0].sym.typ[0], candidate.typ[0], m): + if not matchReturnType(c, n[0].sym.typ.returnType, candidate.typ.returnType, m): m.inferred.setLen oldLen return false diff --git a/compiler/enumtostr.nim b/compiler/enumtostr.nim index b8d0480c7..908c48ccb 100644 --- a/compiler/enumtostr.nim +++ b/compiler/enumtostr.nim @@ -64,7 +64,7 @@ proc searchObjCaseImpl(obj: PNode; field: PSym): PNode = proc searchObjCase(t: PType; field: PSym): PNode = result = searchObjCaseImpl(t.n, field) if result == nil and t.len > 0: - result = searchObjCase(t[0].skipTypes({tyAlias, tyGenericInst, tyRef, tyPtr}), field) + result = searchObjCase(t.baseClass.skipTypes({tyAlias, tyGenericInst, tyRef, tyPtr}), field) doAssert result != nil proc genCaseObjDiscMapping*(t: PType; field: PSym; info: TLineInfo; g: ModuleGraph; idgen: IdGenerator): PSym = diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim index ab26ca1bb..9cbf931cd 100644 --- a/compiler/evalffi.nim +++ b/compiler/evalffi.nim @@ -99,7 +99,7 @@ proc mapType(conf: ConfigRef, t: ast.PType): ptr libffi.Type = tyTyped, tyTypeDesc, tyProc, tyArray, tyStatic, tyNil: result = addr libffi.type_pointer of tyDistinct, tyAlias, tySink: - result = mapType(conf, t[0]) + result = mapType(conf, t.skipModifier) else: result = nil # too risky: @@ -126,16 +126,16 @@ proc packSize(conf: ConfigRef, v: PNode, typ: PType): int = if v.kind in {nkNilLit, nkPtrLit}: result = sizeof(pointer) else: - result = sizeof(pointer) + packSize(conf, v[0], typ.lastSon) + result = sizeof(pointer) + packSize(conf, v[0], typ.elementType) of tyDistinct, tyGenericInst, tyAlias, tySink: - result = packSize(conf, v, typ[0]) + result = packSize(conf, v, typ.skipModifier) of tyArray: # consider: ptr array[0..1000_000, int] which is common for interfacing; # we use the real length here instead if v.kind in {nkNilLit, nkPtrLit}: result = sizeof(pointer) elif v.len != 0: - result = v.len * packSize(conf, v[0], typ[1]) + result = v.len * packSize(conf, v[0], typ.elementType) else: result = 0 else: @@ -234,19 +234,19 @@ proc pack(conf: ConfigRef, v: PNode, typ: PType, res: pointer) = packRecCheck = 0 globalError(conf, v.info, "cannot map value to FFI " & typeToString(v.typ)) inc packRecCheck - pack(conf, v[0], typ.lastSon, res +! sizeof(pointer)) + pack(conf, v[0], typ.elementType, res +! sizeof(pointer)) dec packRecCheck awr(pointer, res +! sizeof(pointer)) of tyArray: - let baseSize = getSize(conf, typ[1]) + let baseSize = getSize(conf, typ.elementType) for i in 0..<v.len: - pack(conf, v[i], typ[1], res +! i * baseSize) + pack(conf, v[i], typ.elementType, res +! i * baseSize) of tyObject, tyTuple: packObject(conf, v, typ, res) of tyNil: discard of tyDistinct, tyGenericInst, tyAlias, tySink: - pack(conf, v, typ[0], res) + pack(conf, v, typ.skipModifier, res) else: globalError(conf, v.info, "cannot map value to FFI " & typeToString(v.typ)) @@ -304,9 +304,9 @@ proc unpackArray(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode = result = n if result.kind != nkBracket: globalError(conf, n.info, "cannot map value from FFI") - let baseSize = getSize(conf, typ[1]) + let baseSize = getSize(conf, typ.elementType) for i in 0..<result.len: - result[i] = unpack(conf, x +! i * baseSize, typ[1], result[i]) + result[i] = unpack(conf, x +! i * baseSize, typ.elementType, result[i]) proc canonNodeKind(k: TNodeKind): TNodeKind = case k @@ -387,7 +387,7 @@ proc unpack(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode = awi(nkPtrLit, cast[int](p)) elif n != nil and n.len == 1: internalAssert(conf, n.kind == nkRefTy) - n[0] = unpack(conf, p, typ.lastSon, n[0]) + n[0] = unpack(conf, p, typ.elementType, n[0]) result = n else: result = nil @@ -405,7 +405,7 @@ proc unpack(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode = of tyNil: setNil() of tyDistinct, tyGenericInst, tyAlias, tySink: - result = unpack(conf, x, typ.lastSon, n) + result = unpack(conf, x, typ.skipModifier, n) else: # XXX what to do with 'array' here? result = nil @@ -444,7 +444,7 @@ proc callForeignFunction*(conf: ConfigRef, call: PNode): PNode = let typ = call[0].typ if prep_cif(cif, mapCallConv(conf, typ.callConv, call.info), cuint(call.len-1), - mapType(conf, typ[0]), sig) != OK: + mapType(conf, typ.returnType), sig) != OK: globalError(conf, call.info, "error in FFI call") var args: ArgList = default(ArgList) @@ -453,15 +453,15 @@ proc callForeignFunction*(conf: ConfigRef, call: PNode): PNode = var t = call[i].typ args[i-1] = alloc0(packSize(conf, call[i], t)) pack(conf, call[i], t, args[i-1]) - let retVal = if isEmptyType(typ[0]): pointer(nil) - else: alloc(getSize(conf, typ[0]).int) + let retVal = if isEmptyType(typ.returnType): pointer(nil) + else: alloc(getSize(conf, typ.returnType).int) libffi.call(cif, fn, retVal, args) if retVal.isNil: result = newNode(nkEmpty) else: - result = unpack(conf, retVal, typ[0], nil) + result = unpack(conf, retVal, typ.returnType, nil) result.info = call.info if retVal != nil: dealloc retVal diff --git a/compiler/expanddefaults.nim b/compiler/expanddefaults.nim index 988433278..395d31cc8 100644 --- a/compiler/expanddefaults.nim +++ b/compiler/expanddefaults.nim @@ -55,8 +55,8 @@ proc expandDefaultN(n: PNode; info: TLineInfo; res: PNode) = discard proc expandDefaultObj(t: PType; info: TLineInfo; res: PNode) = - if t[0] != nil: - expandDefaultObj(t[0], info, res) + if t.baseClass != nil: + expandDefaultObj(t.baseClass, info, res) expandDefaultN(t.n, info, res) proc expandDefault(t: PType; info: TLineInfo): PNode = @@ -82,13 +82,13 @@ proc expandDefault(t: PType; info: TLineInfo): PNode = result = newZero(t, info, nkIntLit) of tyRange: # Could use low(T) here to finally fix old language quirks - result = expandDefault(t[0], info) + result = expandDefault(skipModifier t, info) of tyVoid: result = newZero(t, info, nkEmpty) of tySink, tyGenericInst, tyDistinct, tyAlias, tyOwned: - result = expandDefault(t.lastSon, info) + result = expandDefault(t.skipModifier, info) of tyOrdinal, tyGenericBody, tyGenericParam, tyInferred, tyStatic: if t.len > 0: - result = expandDefault(t.lastSon, info) + result = expandDefault(t.skipModifier, info) else: result = newZero(t, info, nkEmpty) of tyFromExpr: @@ -100,16 +100,16 @@ proc expandDefault(t: PType; info: TLineInfo): PNode = result = newZero(t, info, nkBracket) let n = toInt64(lengthOrd(nil, t)) for i in 0..<n: - result.add expandDefault(t[1], info) + result.add expandDefault(t.elementType, info) of tyPtr, tyRef, tyProc, tyPointer, tyCstring: result = newZero(t, info, nkNilLit) of tyVar, tyLent: - let e = t.lastSon + let e = t.elementType if e.skipTypes(abstractInst).kind in {tyOpenArray, tyVarargs}: # skip the modifier, `var openArray` is a (ptr, len) pair too: result = expandDefault(e, info) else: - result = newZero(t.lastSon, info, nkNilLit) + result = newZero(e, info, nkNilLit) of tySet: result = newZero(t, info, nkCurly) of tyObject: diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 7a64790c2..b8d6d5f63 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[1].kind != tyVar: + if op.typ != nil and op.typ.len > 1 and op.typ.firstParamType.kind != tyVar: addrExp = dest else: addrExp = newNodeIT(nkHiddenAddr, dest.info, makePtrType(c, dest.typ)) @@ -489,7 +489,7 @@ proc passCopyToSink(n: PNode; c: var Con; s: var Scope): PNode = proc isDangerousSeq(t: PType): bool {.inline.} = let t = t.skipTypes(abstractInst) - result = t.kind == tySequence and tfHasOwned notin t[0].flags + result = t.kind == tySequence and tfHasOwned notin t.elementType.flags proc containsConstSeq(n: PNode): bool = if n.kind == nkBracket and n.len > 0 and n.typ != nil and isDangerousSeq(n.typ): diff --git a/compiler/isolation_check.nim b/compiler/isolation_check.nim index b11d64a6b..08a2cc604 100644 --- a/compiler/isolation_check.nim +++ b/compiler/isolation_check.nim @@ -65,7 +65,7 @@ proc canAlias(arg, ret: PType; marker: var IntSet): bool = if result: break of tyArray, tySequence, tyDistinct, tyGenericInst, tyAlias, tyInferred, tySink, tyLent, tyOwned, tyRef: - result = canAlias(arg, ret.lastSon, marker) + result = canAlias(arg, ret.skipModifier, marker) of tyProc: result = ret.callConv == ccClosure else: @@ -119,11 +119,11 @@ proc containsDangerousRefAux(t: PType; marker: var IntSet): SearchResult = if result != NotFound: return result case t.kind of tyObject: - if t[0] != nil: - result = containsDangerousRefAux(t[0].skipTypes(skipPtrs), marker) + if t.baseClass != nil: + result = containsDangerousRefAux(t.baseClass.skipTypes(skipPtrs), marker) if result == NotFound: result = containsDangerousRefAux(t.n, marker) of tyGenericInst, tyDistinct, tyAlias, tySink: - result = containsDangerousRefAux(lastSon(t), marker) + result = containsDangerousRefAux(skipModifier(t), marker) of tyArray, tySet, tyTuple, tySequence: for i in 0..<t.len: result = containsDangerousRefAux(t[i], marker) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 7c636af8b..fb1145360 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -187,7 +187,7 @@ proc mapType(typ: PType): TJSTypeKind = let t = skipTypes(typ, abstractInst) case t.kind of tyVar, tyRef, tyPtr: - if skipTypes(t.lastSon, abstractInst).kind in MappedToObject: + if skipTypes(t.elementType, abstractInst).kind in MappedToObject: result = etyObject else: result = etyBaseIndex @@ -196,7 +196,7 @@ proc mapType(typ: PType): TJSTypeKind = result = etyBaseIndex of tyRange, tyDistinct, tyOrdinal, tyProxy, tyLent: # tyLent is no-op as JS has pass-by-reference semantics - result = mapType(t[0]) + result = mapType(skipModifier t) of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt of tyBool: result = etyBool of tyFloat..tyFloat128: result = etyFloat @@ -212,9 +212,9 @@ proc mapType(typ: PType): TJSTypeKind = result = etyNone of tyGenericInst, tyInferred, tyAlias, tyUserTypeClass, tyUserTypeClassInst, tySink, tyOwned: - result = mapType(typ.lastSon) + result = mapType(typ.skipModifier) of tyStatic: - if t.n != nil: result = mapType(lastSon t) + if t.n != nil: result = mapType(skipModifier t) else: result = etyNone of tyProc: result = etyProc of tyCstring: result = etyString @@ -516,7 +516,7 @@ proc maybeMakeTempAssignable(p: PProc, n: PNode; x: TCompRes): tuple[a, tmp: Rop let (m1, tmp1) = maybeMakeTemp(p, n[0], address) let typ = skipTypes(n[0].typ, abstractPtrs) if typ.kind == tyArray: - first = firstOrd(p.config, typ[0]) + first = firstOrd(p.config, typ.indexType) if optBoundsCheck in p.options: useMagic(p, "chckIndx") if first == 0: # save a couple chars @@ -1439,7 +1439,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) = r.address = x var typ = skipTypes(m[0].typ, abstractPtrs) if typ.kind == tyArray: - first = firstOrd(p.config, typ[0]) + first = firstOrd(p.config, typ.indexType) if optBoundsCheck in p.options: useMagic(p, "chckIndx") if first == 0: # save a couple chars @@ -1455,7 +1455,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) = proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) = var ty = skipTypes(n[0].typ, abstractVarRange) - if ty.kind in {tyRef, tyPtr, tyLent, tyOwned}: ty = skipTypes(ty.lastSon, abstractVarRange) + if ty.kind in {tyRef, tyPtr, tyLent, tyOwned}: ty = skipTypes(ty.elementType, abstractVarRange) case ty.kind of tyArray, tyOpenArray, tySequence, tyString, tyCstring, tyVarargs: genArrayAddr(p, n, r) @@ -1889,7 +1889,7 @@ proc createObjInitList(p: PProc, typ: PType, excludedFieldIDs: IntSet, output: v while t != nil: t = t.skipTypes(skipPtrs) createRecordVarAux(p, t.n, excludedFieldIDs, output) - t = t[0] + t = t.baseClass proc arrayTypeForElemType(conf: ConfigRef; typ: PType): string = let typ = typ.skipTypes(abstractRange) @@ -1938,7 +1938,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope = of tyFloat..tyFloat128: result = putToSeq("0.0", indirect) of tyRange, tyGenericInst, tyAlias, tySink, tyOwned, tyLent: - result = createVar(p, lastSon(typ), indirect) + result = createVar(p, skipModifier(typ), indirect) of tySet: result = putToSeq("{}", indirect) of tyBool: @@ -1990,7 +1990,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope = result = putToSeq("null", indirect) of tyStatic: if t.n != nil: - result = createVar(p, lastSon t, indirect) + result = createVar(p, skipModifier t, indirect) else: internalError(p.config, "createVar: " & $t.kind) result = "" @@ -2699,7 +2699,7 @@ proc genProc(oldProc: PProc, prc: PSym): Rope = var resultAsgn: Rope = "" var name = mangleName(p.module, prc) let header = generateHeader(p, prc.typ) - if prc.typ[0] != nil and sfPure notin prc.flags: + if prc.typ.returnType != nil and sfPure notin prc.flags: resultSym = prc.ast[resultPos].sym let mname = mangleName(p.module, resultSym) # otherwise uses "fat pointers" diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim index 4b4ca9fe7..a1698edf6 100644 --- a/compiler/jstypes.nim +++ b/compiler/jstypes.nim @@ -69,7 +69,7 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope = else: internalError(p.config, n.info, "genObjectFields") proc objHasTypeField(t: PType): bool {.inline.} = - tfInheritable in t.flags or t[0] != nil + tfInheritable in t.flags or t.baseClass != nil proc genObjectInfo(p: PProc, typ: PType, name: Rope) = let kind = if objHasTypeField(typ): tyObject else: tyTuple @@ -79,9 +79,9 @@ proc genObjectInfo(p: PProc, typ: PType, name: Rope) = p.g.typeInfo.addf("var NNI$1 = $2;$n", [rope(typ.id), genObjectFields(p, typ, typ.n)]) p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)]) - if (typ.kind == tyObject) and (typ[0] != nil): + if (typ.kind == tyObject) and (typ.baseClass != nil): p.g.typeInfo.addf("$1.base = $2;$n", - [name, genTypeInfo(p, typ[0].skipTypes(skipPtrs))]) + [name, genTypeInfo(p, typ.baseClass.skipTypes(skipPtrs))]) proc genTupleFields(p: PProc, typ: PType): Rope = var s: Rope = "" @@ -117,9 +117,9 @@ proc genEnumInfo(p: PProc, typ: PType, name: Rope) = prepend(p.g.typeInfo, s) p.g.typeInfo.add(n) p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)]) - if typ[0] != nil: + if typ.baseClass != nil: p.g.typeInfo.addf("$1.base = $2;$n", - [name, genTypeInfo(p, typ[0])]) + [name, genTypeInfo(p, typ.baseClass)]) proc genTypeInfo(p: PProc, typ: PType): Rope = let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink, tyOwned}) @@ -127,7 +127,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope = if containsOrIncl(p.g.typeInfoGenerated, t.id): return case t.kind of tyDistinct: - result = genTypeInfo(p, t[0]) + result = genTypeInfo(p, t.skipModifier) of tyPointer, tyProc, tyBool, tyChar, tyCstring, tyString, tyInt..tyUInt64: var s = "var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" % @@ -139,7 +139,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope = [result, rope(ord(t.kind))] prepend(p.g.typeInfo, s) p.g.typeInfo.addf("$1.base = $2;$n", - [result, genTypeInfo(p, t.lastSon)]) + [result, genTypeInfo(p, t.elementType)]) of tyArray: var s = "var $1 = {size: 0, kind: $2, base: null, node: null, finalizer: null};$n" % @@ -151,6 +151,6 @@ proc genTypeInfo(p: PProc, typ: PType): Rope = of tyObject: genObjectInfo(p, t, result) of tyTuple: genTupleInfo(p, t, result) of tyStatic: - if t.n != nil: result = genTypeInfo(p, lastSon t) + if t.n != nil: result = genTypeInfo(p, skipModifier t) else: internalError(p.config, "genTypeInfo(" & $t.kind & ')') else: internalError(p.config, "genTypeInfo(" & $t.kind & ')') diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 9345ac114..38fdf5b92 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -157,7 +157,7 @@ proc getClosureIterResult*(g: ModuleGraph; iter: PSym; idgen: IdGenerator): PSym else: # XXX a bit hacky: result = newSym(skResult, getIdent(g.cache, ":result"), idgen, iter, iter.info, {}) - result.typ = iter.typ[0] + result.typ = iter.typ.returnType incl(result.flags, sfUsed) iter.ast.add newSymNode(result) @@ -246,7 +246,7 @@ proc liftingHarmful(conf: ConfigRef; owner: PSym): bool {.inline.} = proc createTypeBoundOpsLL(g: ModuleGraph; refType: PType; info: TLineInfo; idgen: IdGenerator; owner: PSym) = if owner.kind != skMacro: - createTypeBoundOps(g, nil, refType.lastSon, info, idgen) + createTypeBoundOps(g, nil, refType.elementType, info, idgen) createTypeBoundOps(g, nil, refType, info, idgen) if tfHasAsgn in refType.flags or optSeqDestructors in g.config.globalOptions: owner.flags.incl sfInjectDestructors @@ -551,8 +551,8 @@ proc accessViaEnvParam(g: ModuleGraph; n: PNode; owner: PSym): PNode = let envParam = getHiddenParam(g, owner) if not envParam.isNil: var access = newSymNode(envParam) + var obj = access.typ.elementType while true: - let obj = access.typ[0] assert obj.kind == tyObject let field = getFieldFromObj(obj, s) if field != nil: @@ -560,6 +560,7 @@ proc accessViaEnvParam(g: ModuleGraph; n: PNode; owner: PSym): PNode = let upField = lookupInRecord(obj.n, getIdent(g.cache, upName)) if upField == nil: break access = rawIndirectAccess(access, upField, n.info) + obj = access.typ.baseClass localError(g.config, n.info, "internal error: environment misses: " & s.name.s) result = n @@ -571,7 +572,7 @@ proc newEnvVar(cache: IdentCache; owner: PSym; typ: PType; info: TLineInfo; idge when false: if owner.kind == skIterator and owner.typ.callConv == ccClosure: let it = getHiddenParam(owner) - addUniqueField(it.typ[0], v) + addUniqueField(it.typ.elementType, v) result = indirectAccess(newSymNode(it), v, v.info) else: result = newSymNode(v) diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 36d9d5b1a..2987a04a8 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -139,9 +139,9 @@ proc genContainerOf(c: var TLiftCtx; objType: PType, field, x: PSym): PNode = result.add minusExpr proc destructorCall(c: var TLiftCtx; op: PSym; x: PNode): PNode = - var destroy = newNodeIT(nkCall, x.info, op.typ[0]) + var destroy = newNodeIT(nkCall, x.info, op.typ.returnType) destroy.add(newSymNode(op)) - if op.typ[1].kind != tyVar: + if op.typ.firstParamType.kind != tyVar: destroy.add x else: destroy.add genAddr(c, x) @@ -153,7 +153,7 @@ proc destructorCall(c: var TLiftCtx; op: PSym; x: PNode): PNode = result = destroy proc genWasMovedCall(c: var TLiftCtx; op: PSym; x: PNode): PNode = - result = newNodeIT(nkCall, x.info, op.typ[0]) + result = newNodeIT(nkCall, x.info, op.typ.returnType) result.add(newSymNode(op)) result.add genAddr(c, x) @@ -221,8 +221,8 @@ 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[0] != nil: - fillBody(c, skipTypes(t[0], abstractPtrs), body, x, y) + if t.len > 0 and 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) = @@ -302,7 +302,7 @@ proc newHookCall(c: var TLiftCtx; op: PSym; x, y: PNode): PNode = result.add newSymNode(op) if sfNeverRaises notin op.flags: c.canRaise = true - if op.typ[1].kind == tyVar: + if op.typ.firstParamType.kind == tyVar: result.add genAddr(c, x) else: result.add x @@ -317,7 +317,7 @@ proc newHookCall(c: var TLiftCtx; op: PSym; x, y: PNode): PNode = result.add boolLit(c.g, y.info, true) proc newOpCall(c: var TLiftCtx; op: PSym; x: PNode): PNode = - result = newNodeIT(nkCall, x.info, op.typ[0]) + result = newNodeIT(nkCall, x.info, op.typ.returnType) result.add(newSymNode(op)) result.add x if sfNeverRaises notin op.flags: @@ -545,7 +545,7 @@ proc forallElements(c: var TLiftCtx; t: PType; body, x, y: PNode) = let counterIdx = body.len let i = declareCounter(c, body, toInt64(firstOrd(c.g.config, t))) let whileLoop = genWhileLoop(c, i, x) - let elemType = t.lastSon + let elemType = t.elementType let b = if c.kind == attachedTrace: y else: y.at(i, elemType) fillBody(c, elemType, whileLoop[1], x.at(i, elemType), b) if whileLoop[1].len > 0: @@ -656,7 +656,7 @@ proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = proc cyclicType*(g: ModuleGraph, t: PType): bool = case t.kind - of tyRef: result = types.canFormAcycle(g, t.lastSon) + of tyRef: result = types.canFormAcycle(g, t.elementType) of tyProc: result = t.callConv == ccClosure else: result = false @@ -681,7 +681,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = ]# var actions = newNodeI(nkStmtList, c.info) - let elemType = t.lastSon + let elemType = t.elementType createTypeBoundOps(c.g, c.c, elemType, c.info, c.idgen) let isCyclic = c.g.config.selectedGC == gcOrc and types.canFormAcycle(c.g, elemType) @@ -851,7 +851,7 @@ proc weakrefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = proc ownedRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = var actions = newNodeI(nkStmtList, c.info) - let elemType = t.lastSon + let elemType = t.skipModifier #fillBody(c, elemType, actions, genDeref(x), genDeref(y)) #var disposeCall = genBuiltin(c, mDispose, "dispose", x) @@ -1017,7 +1017,7 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) = fillBodyObjT(c, t, body, x, y) of tyDistinct: if not considerUserDefinedOp(c, t, body, x, y): - fillBody(c, t[0], body, x, y) + fillBody(c, t.elementType, body, x, y) of tyTuple: fillBodyTup(c, t, body, x, y) of tyVarargs, tyOpenArray: @@ -1034,14 +1034,14 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) = discard of tyOrdinal, tyRange, tyInferred, tyGenericInst, tyAlias, tySink: - fillBody(c, lastSon(t), body, x, y) + fillBody(c, skipModifier(t), body, x, y) of tyConcept, tyIterable: raiseAssert "unreachable" proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; info: TLineInfo; idgen: IdGenerator): PSym = assert typ.kind == tyDistinct - let baseType = typ[0] + let baseType = typ.elementType if getAttachedOp(g, baseType, kind) == nil: discard produceSym(g, c, baseType, kind, info, idgen) result = getAttachedOp(g, baseType, kind) @@ -1147,7 +1147,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; fn: result) let dest = if kind == attachedDup: result.ast[resultPos].sym else: result.typ.n[1].sym - let d = if result.typ[1].kind == tyVar: newDeref(newSymNode(dest)) else: newSymNode(dest) + let d = if result.typ.firstParamType.kind == tyVar: newDeref(newSymNode(dest)) else: newSymNode(dest) let src = case kind of {attachedDestructor, attachedWasMoved}: newNodeIT(nkSym, info, getSysType(g, info, tyPointer)) of attachedDup: newSymNode(result.typ.n[1].sym) @@ -1160,7 +1160,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; ## compiler can use a combination of `=destroy` and memCopy for sink op dest.flags.incl sfCursor let op = getAttachedOp(g, typ, attachedDestructor) - result.ast[bodyPos].add newOpCall(a, op, if op.typ[1].kind == tyVar: d[0] else: d) + result.ast[bodyPos].add newOpCall(a, op, if op.typ.firstParamType.kind == tyVar: d[0] else: d) result.ast[bodyPos].add newAsgnStmt(d, src) else: var tk: TTypeKind diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index f8ae67f41..0ed4c436f 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -19,7 +19,7 @@ when defined(nimPreviewSlimSystem): import std/assertions proc newDeref*(n: PNode): PNode {.inline.} = - result = newNodeIT(nkHiddenDeref, n.info, n.typ[0]) + result = newNodeIT(nkHiddenDeref, n.info, n.typ.elementType) result.add n proc newTupleAccess*(g: ModuleGraph; tup: PNode, i: int): PNode = @@ -262,7 +262,7 @@ proc indirectAccess*(a: PNode, b: ItemId, info: TLineInfo): PNode = assert t.kind == tyObject field = lookupInRecord(t.n, b) if field != nil: break - t = t[0] + t = t.baseClass if t == nil: break t = t.skipTypes(skipPtrs) #if field == nil: @@ -286,7 +286,7 @@ proc indirectAccess*(a: PNode, b: string, info: TLineInfo; cache: IdentCache): P assert t.kind == tyObject field = getSymFromList(t.n, bb) if field != nil: break - t = t[0] + t = t.baseClass if t == nil: break t = t.skipTypes(skipPtrs) #if field == nil: diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index b365a3a19..1ec6b9a69 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -35,7 +35,7 @@ proc getSysMagic*(g: ModuleGraph; info: TLineInfo; name: string, m: TMagic): PSy for r in systemModuleSyms(g, id): if r.magic == m: # prefer the tyInt variant: - if r.typ[0] != nil and r.typ[0].kind == tyInt: return r + if r.typ.returnType != nil and r.typ.returnType.kind == tyInt: return r result = r if result != nil: return result localError(g.config, info, "system module needs: " & name) diff --git a/compiler/nilcheck.nim b/compiler/nilcheck.nim index 2a6de8733..6261c8fda 100644 --- a/compiler/nilcheck.nim +++ b/compiler/nilcheck.nim @@ -507,7 +507,7 @@ proc checkCall(n, ctx, map): Check = # as it might have been mutated # TODO similar for normal refs and fields: find dependent exprs: brackets - if child.kind == nkHiddenAddr and not child.typ.isNil and child.typ.kind == tyVar and child.typ[0].kind == tyRef: + if child.kind == nkHiddenAddr and not child.typ.isNil and child.typ.kind == tyVar and child.typ.elementType.kind == tyRef: if not isNew: result.map = newNilMap(map) isNew = true @@ -1367,7 +1367,7 @@ proc checkNil*(s: PSym; body: PNode; conf: ConfigRef, idgen: IdGenerator) = continue map.store(context, context.index(child), typeNilability(child.typ), TArg, child.info, child) - map.store(context, resultExprIndex, if not s.typ[0].isNil and s.typ[0].kind == tyRef: Nil else: Safe, TResult, s.ast.info) + map.store(context, resultExprIndex, if not s.typ.returnType.isNil and s.typ.returnType.kind == tyRef: Nil else: Safe, TResult, s.ast.info) # echo "checking ", s.name.s, " ", filename @@ -1383,5 +1383,5 @@ proc checkNil*(s: PSym; body: PNode; conf: ConfigRef, idgen: IdGenerator) = # (ANotNil, BNotNil) : # do we check on asgn nilability at all? - if not s.typ[0].isNil and s.typ[0].kind == tyRef and tfNotNil in s.typ[0].flags: + if not s.typ.returnType.isNil and s.typ.returnType.kind == tyRef and tfNotNil in s.typ.returnType.flags: checkResult(s.ast, context, res.map) diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index 59a542a85..7edf55278 100644 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -65,7 +65,7 @@ proc toBitSet*(conf: ConfigRef; s: PNode): TBitSet = result = @[] var first: Int128 = Zero var j: Int128 = Zero - first = firstOrd(conf, s.typ[0]) + first = firstOrd(conf, s.typ.elementType) bitSetInit(result, int(getSize(conf, s.typ))) for i in 0..<s.len: if s[i].kind == nkRange: diff --git a/compiler/nir/ast2ir.nim b/compiler/nir/ast2ir.nim index 51dfcdb09..1730181f3 100644 --- a/compiler/nir/ast2ir.nim +++ b/compiler/nir/ast2ir.nim @@ -586,7 +586,7 @@ proc genIndex(c: var ProcCon; n: PNode; arr: PType; d: var Value) = proc rawGenNew(c: var ProcCon; d: Value; refType: PType; ninfo: TLineInfo; needsInit: bool) = assert refType.kind == tyRef - let baseType = refType.lastSon + let baseType = refType.elementType let info = toLineInfo(c, ninfo) let codegenProc = magicsys.getCompilerProc(c.m.graph, @@ -611,7 +611,7 @@ proc genNew(c: var ProcCon; n: PNode; needsInit: bool) = proc genNewSeqOfCap(c: var ProcCon; n: PNode; d: var Value) = let info = toLineInfo(c, n.info) let seqtype = skipTypes(n.typ, abstractVarRange) - let baseType = seqtype.lastSon + let baseType = seqtype.elementType var a = c.genx(n[1]) if isEmpty(d): d = getTemp(c, n) # $1.len = 0 @@ -639,7 +639,7 @@ proc genNewSeqOfCap(c: var ProcCon; n: PNode; d: var Value) = freeTemp c, a proc genNewSeqPayload(c: var ProcCon; info: PackedLineInfo; d, b: Value; seqtype: PType) = - let baseType = seqtype.lastSon + let baseType = seqtype.elementType # $1.p = ($4*) #newSeqPayload($2, sizeof($3), NIM_ALIGNOF($3)) let payloadPtr = seqPayloadPtrType(c.m.types, c.m.nirm.types, seqtype)[0] @@ -1597,7 +1597,7 @@ proc genDestroySeq(c: var ProcCon; n: PNode; t: PType) = let strLitFlag = 1 shl (c.m.graph.config.target.intSize * 8 - 2) # see also NIM_STRLIT_FLAG let x = c.genx(n[1]) - let baseType = t.lastSon + let baseType = t.elementType let seqType = typeToIr(c.m, t) let p = fieldAt(x, 0, seqType) @@ -1655,7 +1655,7 @@ proc genIndexCheck(c: var ProcCon; n: PNode; a: Value; kind: IndexFor; arr: PTyp proc addSliceFields(c: var ProcCon; target: var Tree; info: PackedLineInfo; x: Value; n: PNode; arrType: PType) = - let elemType = arrayPtrTypeOf(c.m.nirm.types, typeToIr(c.m, arrType.lastSon)) + let elemType = arrayPtrTypeOf(c.m.nirm.types, typeToIr(c.m, arrType.elementType)) case arrType.kind of tyString, tySequence: let checkKind = if arrType.kind == tyString: ForStr else: ForSeq @@ -1970,7 +1970,7 @@ proc genDeref(c: var ProcCon; n: PNode; d: var Value; flags: GenFlags) = proc addAddrOfFirstElem(c: var ProcCon; target: var Tree; info: PackedLineInfo; tmp: Value; typ: PType) = let arrType = typ.skipTypes(abstractVar) - let elemType = arrayPtrTypeOf(c.m.nirm.types, typeToIr(c.m, arrType.lastSon)) + let elemType = arrayPtrTypeOf(c.m.nirm.types, typeToIr(c.m, arrType.elementType)) case arrType.kind of tyString: let t = typeToIr(c.m, typ) @@ -2079,7 +2079,7 @@ proc genRefObjConstr(c: var ProcCon; n: PNode; d: var Value) = if isEmpty(d): d = getTemp(c, n) let info = toLineInfo(c, n.info) let refType = n.typ.skipTypes(abstractInstOwned) - let objType = refType.lastSon + let objType = refType.elementType rawGenNew(c, d, refType, n.info, needsInit = nfAllFieldsSet notin n.flags) var deref = default(Value) @@ -2092,7 +2092,7 @@ proc genSeqConstr(c: var ProcCon; n: PNode; d: var Value) = let info = toLineInfo(c, n.info) let seqtype = skipTypes(n.typ, abstractVarRange) - let baseType = seqtype.lastSon + let baseType = seqtype.elementType var b = default(Value) b.addIntVal c.lit.numbers, info, c.m.nativeIntId, n.len diff --git a/compiler/nir/types2ir.nim b/compiler/nir/types2ir.nim index 9c9513284..aa8bcc12f 100644 --- a/compiler/nir/types2ir.nim +++ b/compiler/nir/types2ir.nim @@ -171,7 +171,7 @@ proc nativeInt(c: TypesCon): TypeId = else: result = Int64Id proc openArrayPayloadType*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId = - let e = lastSon(t) + let e = elementType(t) let elementType = typeToIr(c, g, e) let arr = g.openType AArrayPtrTy g.addType elementType @@ -179,7 +179,7 @@ proc openArrayPayloadType*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId proc openArrayToIr(c: var TypesCon; g: var TypeGraph; t: PType): TypeId = # object (a: ArrayPtr[T], len: int) - let e = lastSon(t) + let e = elementType(t) let mangledBase = mangle(c, e) let typeName = "NimOpenArray" & mangledBase @@ -265,7 +265,7 @@ proc seqPayloadType(c: var TypesCon; g: var TypeGraph; t: PType): (string, TypeI cap: int data: UncheckedArray[T] ]# - let e = lastSon(t) + let e = elementType(t) result = (mangle(c, e), TypeId(-1)) let payloadName = "NimSeqPayload" & result[0] @@ -397,7 +397,7 @@ proc typeToIr*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId = of tyChar: result = Char8Id of tyVoid: result = VoidId of tySink, tyGenericInst, tyDistinct, tyAlias, tyOwned, tyRange: - result = typeToIr(c, g, t.lastSon) + result = typeToIr(c, g, t.skipModifier) of tyEnum: if firstOrd(c.conf, t) < 0: result = Int32Id @@ -410,7 +410,7 @@ proc typeToIr*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId = else: result = Int32Id of tyOrdinal, tyGenericBody, tyGenericParam, tyInferred, tyStatic: if t.len > 0: - result = typeToIr(c, g, t.lastSon) + result = typeToIr(c, g, t.skipModifier) else: result = TypeId(-1) of tyFromExpr: @@ -422,7 +422,7 @@ proc typeToIr*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId = cached(c, t): var n = toInt64(lengthOrd(c.conf, t)) if n <= 0: n = 1 # make an array of at least one element - let elemType = typeToIr(c, g, t[1]) + let elemType = typeToIr(c, g, t.elementType) let a = openType(g, ArrayTy) g.addType(elemType) g.addArrayLen n @@ -430,20 +430,20 @@ proc typeToIr*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId = result = finishType(g, a) of tyPtr, tyRef: cached(c, t): - let e = t.lastSon + let e = t.elementType if e.kind == tyUncheckedArray: - let elemType = typeToIr(c, g, e.lastSon) + let elemType = typeToIr(c, g, e.elementType) let a = openType(g, AArrayPtrTy) g.addType(elemType) result = finishType(g, a) else: - let elemType = typeToIr(c, g, t.lastSon) + let elemType = typeToIr(c, g, t.elementType) let a = openType(g, APtrTy) g.addType(elemType) result = finishType(g, a) of tyVar, tyLent: cached(c, t): - let e = t.lastSon + let e = t.elementType if e.skipTypes(abstractInst).kind in {tyOpenArray, tyVarargs}: # skip the modifier, `var openArray` is a (ptr, len) pair too: result = typeToIr(c, g, e) @@ -510,7 +510,7 @@ proc typeToIr*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId = of tyUncheckedArray: # We already handled the `ptr UncheckedArray` in a special way. cached(c, t): - let elemType = typeToIr(c, g, t.lastSon) + let elemType = typeToIr(c, g, t.elementType) let a = openType(g, LastArrayTy) g.addType(elemType) result = finishType(g, a) diff --git a/compiler/plugins/itersgen.nim b/compiler/plugins/itersgen.nim index c5e9dc853..e2c97bdc5 100644 --- a/compiler/plugins/itersgen.nim +++ b/compiler/plugins/itersgen.nim @@ -25,7 +25,7 @@ proc iterToProcImpl*(c: PContext, n: PNode): PNode = return let t = n[2].typ.skipTypes({tyTypeDesc, tyGenericInst}) - if t.kind notin {tyRef, tyPtr} or t.lastSon.kind != tyObject: + if t.kind notin {tyRef, tyPtr} or t.elementType.kind != tyObject: localError(c.config, n[2].info, "type must be a non-generic ref|ptr to object with state field") return diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 35b4d63c2..001af6ae7 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -145,9 +145,9 @@ proc pragmaEnsures(c: PContext, n: PNode) = else: openScope(c) let o = getCurrOwner(c) - if o.kind in routineKinds and o.typ != nil and o.typ[0] != nil: + if o.kind in routineKinds and o.typ != nil and o.typ.returnType != nil: var s = newSym(skResult, getIdent(c.cache, "result"), c.idgen, o, n.info) - s.typ = o.typ[0] + s.typ = o.typ.returnType incl(s.flags, sfUsed) addDecl(c, s) n[1] = c.semExpr(c, n[1]) @@ -1011,7 +1011,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, # Disable the 'noreturn' annotation when in the "Quirky Exceptions" mode! if c.config.exc != excQuirky: incl(sym.flags, sfNoReturn) - if sym.typ[0] != nil: + if sym.typ.returnType != nil: localError(c.config, sym.ast[paramsPos][0].info, ".noreturn with return type not allowed") of wNoDestroy: diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 2a586386b..bc1cbd65e 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -366,7 +366,7 @@ proc litAux(g: TSrcGen; n: PNode, x: BiggestInt, size: int): string = result = t while result != nil and result.kind in {tyGenericInst, tyRange, tyVar, tyLent, tyDistinct, tyOrdinal, tyAlias, tySink}: - result = lastSon(result) + result = skipModifier(result) result = "" let typ = n.typ.skip diff --git a/compiler/sem.nim b/compiler/sem.nim index 03e599753..d63fa56c9 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -196,8 +196,8 @@ proc commonType*(c: PContext; x, y: PType): PType = k = a.kind if b.kind != a.kind: return x # bug #7601, array construction of ptr generic - a = a.lastSon.skipTypes({tyGenericInst}) - b = b.lastSon.skipTypes({tyGenericInst}) + a = a.elementType.skipTypes({tyGenericInst}) + b = b.elementType.skipTypes({tyGenericInst}) if a.kind == tyObject and b.kind == tyObject: result = commonSuperclass(a, b) # this will trigger an error later: @@ -498,15 +498,15 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode, c.friendModules.add(s.owner.getModule) result = macroResult resetSemFlag result - if s.typ[0] == nil: + if s.typ.returnType == nil: result = semStmt(c, result, flags) else: - var retType = s.typ[0] + var retType = s.typ.returnType if retType.kind == tyTypeDesc and tfUnresolved in retType.flags and retType.len == 1: # bug #11941: template fails(T: type X, v: auto): T # does not mean we expect a tyTypeDesc. - retType = retType[0] + retType = retType.skipModifier case retType.kind of tyUntyped, tyAnything: # Not expecting a type here allows templates like in ``tmodulealias.in``. diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 26a40b4dc..6904e6bbc 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -680,7 +680,7 @@ proc semResolvedCall(c: PContext, x: var TCandidate, result = x.call instGenericConvertersSons(c, result, x) result[0] = newSymNode(finalCallee, getCallLineInfo(result[0])) - result.typ = finalCallee.typ[0] + result.typ = finalCallee.typ.returnType updateDefaultParams(result) proc canDeref(n: PNode): bool {.inline.} = @@ -821,7 +821,7 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): tuple[s: PS ]# t = skipTypes(param.typ, desiredTypes) isDistinct = t.kind == tyDistinct or param.typ.kind == tyDistinct - if t.kind == tyGenericInvocation and t[0].lastSon.kind == tyDistinct: + if t.kind == tyGenericInvocation and t[0].last.kind == tyDistinct: result.state = bsGeneric return if isDistinct: hasDistinct = true @@ -840,7 +840,7 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): tuple[s: PS if resolved != nil: result.s = resolved[0].sym result.state = bsMatch - if not compareTypes(result.s.typ[0], fn.typ[0], dcEqIgnoreDistinct, {IgnoreFlags}): + if not compareTypes(result.s.typ.returnType, fn.typ.returnType, dcEqIgnoreDistinct, {IgnoreFlags}): result.state = bsReturnNotMatch elif result.s.magic in {mArrPut, mArrGet}: # cannot borrow these magics for now diff --git a/compiler/semdata.nim b/compiler/semdata.nim index b1ffbec49..e56cfc944 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -446,10 +446,6 @@ proc newTypeWithSons*(c: PContext, kind: TTypeKind, sons: seq[PType]): PType = result = newType(kind, c.idgen, getCurrOwner(c), sons = sons) -proc newTypeWithSons*(c: PContext, kind: TTypeKind, - parent: PType): PType = - result = newType(kind, c.idgen, getCurrOwner(c), parent = parent) - proc makeStaticExpr*(c: PContext, n: PNode): PNode = result = newNodeI(nkStaticExpr, n.info) result.sons = @[n] diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 82ff000a7..d20ac92ca 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -196,19 +196,19 @@ proc checkConvertible(c: PContext, targetTyp: PType, src: PNode): TConvStatus = var d = skipTypes(targetTyp, abstractVar) var s = srcTyp if s.kind in tyUserTypeClasses and s.isResolvedUserTypeClass: - s = s.lastSon + s = s.last s = skipTypes(s, abstractVar-{tyTypeDesc, tyOwned}) if s.kind == tyOwned and d.kind != tyOwned: - s = s.lastSon + s = s.skipModifier var pointers = 0 while (d != nil) and (d.kind in {tyPtr, tyRef, tyOwned}): if s.kind == tyOwned and d.kind != tyOwned: - s = s.lastSon + s = s.skipModifier elif d.kind != s.kind: break else: - d = d.lastSon - s = s.lastSon + d = d.elementType + s = s.elementType inc pointers let targetBaseTyp = skipTypes(targetTyp, abstractVarRange) @@ -442,7 +442,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = of tySequence, tyString, tyCstring, tyOpenArray, tyVarargs: n.typ = getSysType(c.graph, n.info, tyInt) of tyArray: - n.typ = typ[0] # indextype + n.typ = typ.indexType if n.typ.kind == tyRange and emptyRange(n.typ.n[0], n.typ.n[1]): #Invalid range n.typ = getSysType(c.graph, n.info, tyInt) of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt..tyUInt64, tyFloat..tyFloat64: @@ -640,7 +640,7 @@ proc arrayConstrType(c: PContext, n: PNode): PType = else: var t = skipTypes(n[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink}) addSonSkipIntLit(typ, t, c.idgen) - typ[0] = makeRangeType(c, 0, n.len - 1, n.info) + typ.setIndexType makeRangeType(c, 0, n.len - 1, n.info) result = typ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode = @@ -713,7 +713,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp addSonSkipIntLit(result.typ, typ, c.idgen) for i in 0..<result.len: result[i] = fitNode(c, typ, result[i], result[i].info) - result.typ[0] = makeRangeType(c, toInt64(firstIndex), toInt64(lastIndex), n.info, + result.typ.setIndexType makeRangeType(c, toInt64(firstIndex), toInt64(lastIndex), n.info, indexType) proc fixAbstractType(c: PContext, n: PNode) = @@ -1433,7 +1433,7 @@ proc tryReadingTypeField(c: PContext, n: PNode, i: PIdent, ty: PType): PNode = n.typ = makeTypeDesc(c, field.typ) result = n of tyGenericInst: - result = tryReadingTypeField(c, n, i, ty.lastSon) + result = tryReadingTypeField(c, n, i, ty.skipModifier) if result == nil: result = tryReadingGenericParam(c, n, i, ty) else: @@ -1493,7 +1493,7 @@ proc builtinFieldAccess(c: PContext; n: PNode; flags: var TExprFlags): PNode = return nil if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass: - ty = ty.lastSon + ty = ty.last ty = skipTypes(ty, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyOwned, tyAlias, tySink, tyStatic}) while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct, tyGenericInst, tyAlias}) var check: PNode = nil @@ -1580,7 +1580,7 @@ proc semDeref(c: PContext, n: PNode): PNode = result = n var t = skipTypes(n[0].typ, {tyGenericInst, tyVar, tyLent, tyAlias, tySink, tyOwned}) case t.kind - of tyRef, tyPtr: n.typ = t.lastSon + of tyRef, tyPtr: n.typ = t.elementType else: result = nil #GlobalError(n[0].info, errCircumNeedsPointer) @@ -1929,7 +1929,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = if c.p.owner.kind != skMacro and resultTypeIsInferrable(lhs.sym.typ): var rhsTyp = rhs.typ if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass: - rhsTyp = rhsTyp.lastSon + rhsTyp = rhsTyp.last if lhs.sym.typ.kind == tyAnything: rhsTyp = rhsTyp.skipIntLit(c.idgen) if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}: @@ -1938,7 +1938,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = typeAllowedCheck(c, n.info, rhsTyp, skResult) lhs.typ = rhsTyp c.p.resultSym.typ = rhsTyp - c.p.owner.typ[0] = rhsTyp + c.p.owner.typ.setReturnType rhsTyp else: typeMismatch(c.config, n.info, lhs.typ, rhsTyp, rhs) borrowCheck(c, n, lhs, rhs) @@ -2004,12 +2004,12 @@ proc semProcBody(c: PContext, n: PNode; expectedType: PType = nil): PNode = if isEmptyType(result.typ): # we inferred a 'void' return type: c.p.resultSym.typ = errorType(c) - c.p.owner.typ[0] = nil + c.p.owner.typ.setReturnType nil else: localError(c.config, c.p.resultSym.info, errCannotInferReturnType % c.p.owner.name.s) - if isIterator(c.p.owner.typ) and c.p.owner.typ[0] != nil and - c.p.owner.typ[0].kind == tyAnything: + if isIterator(c.p.owner.typ) and c.p.owner.typ.returnType != nil and + c.p.owner.typ.returnType.kind == tyAnything: localError(c.config, c.p.owner.info, errCannotInferReturnType % c.p.owner.name.s) closeScope(c) diff --git a/compiler/semfields.nim b/compiler/semfields.nim index 5f3172f81..d1637e1f2 100644 --- a/compiler/semfields.nim +++ b/compiler/semfields.nim @@ -156,8 +156,8 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = var t = tupleTypeA while t.kind == tyObject: semForObjectFields(fc, t.n, n, stmts) - if t[0] == nil: break - t = skipTypes(t[0], skipPtrs) + if t.baseClass == nil: break + t = skipTypes(t.baseClass, skipPtrs) c.p.breakInLoop = oldBreakInLoop dec(c.p.nestedLoopCounter) # for TR macros this 'while true: ...; break' loop is pretty bad, so diff --git a/compiler/semfold.nim b/compiler/semfold.nim index faa609584..8ded414c3 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -122,10 +122,10 @@ proc ordinalValToString*(a: PNode; g: ModuleGraph): string = result = $x proc isFloatRange(t: PType): bool {.inline.} = - result = t.kind == tyRange and t[0].kind in {tyFloat..tyFloat128} + result = t.kind == tyRange and t.elementType.kind in {tyFloat..tyFloat128} proc isIntRange(t: PType): bool {.inline.} = - result = t.kind == tyRange and t[0].kind in { + result = t.kind == tyRange and t.elementType.kind in { tyInt..tyInt64, tyUInt8..tyUInt32} proc pickIntRange(a, b: PType): PType = diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim index 12d7d32e0..9e84e7c62 100644 --- a/compiler/semmacrosanity.nim +++ b/compiler/semmacrosanity.nim @@ -35,12 +35,12 @@ proc ithField(n: PNode, field: var int): PSym = else: discard proc ithField(t: PType, field: var int): PSym = - var base = t[0] + var base = t.baseClass while base != nil: let b = skipTypes(base, skipPtrs) result = ithField(b.n, field) if result != nil: return result - base = b[0] + base = b.baseClass result = ithField(t.n, field) proc annotateType*(n: PNode, t: PType; conf: ConfigRef) = diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 548b922fe..bf8375adf 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -22,7 +22,7 @@ proc addDefaultFieldForNew(c: PContext, n: PNode): PNode = var t = typ.skipTypes({tyGenericInst, tyAlias, tySink})[0] while true: asgnExpr.sons.add defaultFieldsForTheUninitialized(c, t.n, false) - let base = t[0] + let base = t.baseClass if base == nil: break t = skipTypes(base, skipPtrs) @@ -393,7 +393,7 @@ proc semUnown(c: PContext; n: PNode): PNode = for e in elems: result.rawAddSon(e) else: result = t - of tyOwned: result = t[0] + of tyOwned: result = t.elementType of tySequence, tyOpenArray, tyArray, tyVarargs, tyVar, tyLent, tyGenericInst, tyAlias: let b = unownedType(c, t[^1]) @@ -433,7 +433,7 @@ proc turnFinalizerIntoDestructor(c: PContext; orig: PSym; info: TLineInfo): PSym result.info = info result.flags.incl sfFromGeneric result.owner = orig - let origParamType = orig.typ[1] + let origParamType = orig.typ.firstParamType let newParamType = makeVarType(result, origParamType.skipTypes(abstractPtrs), c.idgen) let oldParam = orig.typ.n[1].sym let newParam = newSym(skParam, oldParam.name, c.idgen, result, result.info) @@ -497,7 +497,7 @@ proc semNewFinalize(c: PContext; n: PNode): PNode = localError(c.config, n.info, "finalizer must be a direct reference to a proc") # check if we converted this finalizer into a destructor already: - let t = whereToBindTypeHook(c, fin.typ[1].skipTypes(abstractInst+{tyRef})) + let t = whereToBindTypeHook(c, fin.typ.firstParamType.skipTypes(abstractInst+{tyRef})) if t != nil and getAttachedOp(c.graph, t, attachedDestructor) != nil and getAttachedOp(c.graph, t, attachedDestructor).owner == fin: discard "already turned this one into a finalizer" @@ -506,13 +506,13 @@ proc semNewFinalize(c: PContext; n: PNode): PNode = fin.owner = fin.instantiatedFrom let wrapperSym = newSym(skProc, getIdent(c.graph.cache, fin.name.s & "FinalizerWrapper"), c.idgen, fin.owner, fin.info) let selfSymNode = newSymNode(copySym(fin.ast[paramsPos][1][0].sym, c.idgen)) - selfSymNode.typ = fin.typ[1] + selfSymNode.typ = fin.typ.firstParamType wrapperSym.flags.incl sfUsed let wrapper = c.semExpr(c, newProcNode(nkProcDef, fin.info, body = newTree(nkCall, newSymNode(fin), selfSymNode), params = nkFormalParams.newTree(c.graph.emptyNode, newTree(nkIdentDefs, selfSymNode, newNodeIT(nkType, - fin.ast[paramsPos][1][1].info, fin.typ[1]), c.graph.emptyNode) + fin.ast[paramsPos][1][1].info, fin.typ.firstParamType), c.graph.emptyNode) ), name = newSymNode(wrapperSym), pattern = fin.ast[patternPos], genericParams = fin.ast[genericParamsPos], pragmas = fin.ast[pragmasPos], exceptions = fin.ast[miscPos]), {}) @@ -618,8 +618,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, let op = getAttachedOp(c.graph, t, attachedDestructor) if op != nil: result[0] = newSymNode(op) - - if op.typ != nil and op.typ.len == 2 and op.typ[1].kind != tyVar: + if op.typ != nil and op.typ.len == 2 and op.typ.firstParamType.kind != tyVar: if n[1].kind == nkSym and n[1].sym.kind == skParam and n[1].typ.kind == tyVar: result[1] = genDeref(n[1]) diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index 37c939bcd..ae254f45b 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -415,8 +415,8 @@ proc semConstructTypeAux(c: PContext, discard collectMissingFields(c, t.n, constrCtx, result.defaults) let base = t[0] if base == nil or base.id == t.id or - base.kind in {tyRef, tyPtr} and base[0].id == t.id: - break + base.kind in {tyRef, tyPtr} and base.elementType.id == t.id: + break t = skipTypes(base, skipPtrs) if t.kind != tyObject: # XXX: This is not supposed to happen, but apparently @@ -439,7 +439,7 @@ proc computeRequiresInit(c: PContext, t: PType): bool = proc defaultConstructionError(c: PContext, t: PType, info: TLineInfo) = var objType = t while objType.kind notin {tyObject, tyDistinct}: - objType = objType.lastSon + objType = objType.last assert objType != nil if objType.kind == tyObject: var constrCtx = initConstrContext(objType, newNodeI(nkObjConstr, info)) @@ -470,7 +470,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType t = skipTypes(t, {tyGenericInst, tyAlias, tySink, tyOwned}) if t.kind == tyRef: - t = skipTypes(t[0], {tyGenericInst, tyAlias, tySink, tyOwned}) + t = skipTypes(t.elementType, {tyGenericInst, tyAlias, tySink, tyOwned}) if optOwnedRefs in c.config.globalOptions: result.typ = makeVarType(c, result.typ, tyOwned) # we have to watch out, there are also 'owned proc' types that can be used diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index e010bf179..448f4d26a 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -757,7 +757,7 @@ proc addIdToIntersection(tracked: PEffects, inter: var TIntersection, resCounter template hasResultSym(s: PSym): bool = s != nil and s.kind in {skProc, skFunc, skConverter, skMethod} and - not isEmptyType(s.typ[0]) + not isEmptyType(s.typ.returnType) proc trackCase(tracked: PEffects, n: PNode) = track(tracked, n[0]) @@ -985,7 +985,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.lastSon.flags != {}: + if arg.typ.len != 0 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! @@ -995,7 +995,7 @@ proc trackCall(tracked: PEffects; n: PNode) = # check required for 'nim check': if n[1].typ.len > 0: - createTypeBoundOps(tracked, n[1].typ.lastSon, n.info) + 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'? @@ -1322,7 +1322,7 @@ proc track(tracked: PEffects, n: PNode) = if tracked.owner.kind != skMacro: # XXX n.typ can be nil in runnableExamples, we need to do something about it. if n.typ != nil and n.typ.skipTypes(abstractInst).kind == tyRef: - createTypeBoundOps(tracked, n.typ.lastSon, n.info) + createTypeBoundOps(tracked, n.typ.elementType, n.info) createTypeBoundOps(tracked, n.typ, n.info) of nkTupleConstr: for i in 0..<n.len: @@ -1571,7 +1571,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) = var t: TEffects = initEffects(g, inferredEffects, s, c) rawInitEffects g, effects - if not isEmptyType(s.typ[0]) and + if not isEmptyType(s.typ.returnType) and s.kind in {skProc, skFunc, skConverter, skMethod}: var res = s.ast[resultPos].sym # get result symbol t.scopes[res.id] = t.currentBlock @@ -1590,13 +1590,13 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) = if isOutParam(typ) and param.id notin t.init: message(g.config, param.info, warnProveInit, param.name.s) - if not isEmptyType(s.typ[0]) and - (s.typ[0].requiresInit or s.typ[0].skipTypes(abstractInst).kind == tyVar or + if not isEmptyType(s.typ.returnType) and + (s.typ.returnType.requiresInit or s.typ.returnType.skipTypes(abstractInst).kind == tyVar or strictDefs in c.features) and s.kind in {skProc, skFunc, skConverter, skMethod} and s.magic == mNone: var res = s.ast[resultPos].sym # get result symbol if res.id notin t.init and breaksBlock(body) != bsNoReturn: - if tfRequiresInit in s.typ[0].flags: + if tfRequiresInit in s.typ.returnType.flags: localError(g.config, body.info, "'$1' requires explicit initialization" % "result") else: message(g.config, body.info, warnProveInit, "result") diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 70818bb67..3104f3158 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -42,7 +42,7 @@ proc implicitlyDiscardable(n: PNode): bool proc hasEmpty(typ: PType): bool = if typ.kind in {tySequence, tyArray, tySet}: - result = typ.lastSon.kind == tyEmpty + result = typ.elementType.kind == tyEmpty elif typ.kind == tyTuple: result = false for s in typ: @@ -451,16 +451,16 @@ proc hasUnresolvedParams(n: PNode; flags: TExprFlags): bool = proc makeDeref(n: PNode): PNode = var t = n.typ if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass: - t = t.lastSon + t = t.last t = skipTypes(t, {tyGenericInst, tyAlias, tySink, tyOwned}) result = n if t.kind in {tyVar, tyLent}: - result = newNodeIT(nkHiddenDeref, n.info, t[0]) + result = newNodeIT(nkHiddenDeref, n.info, t.elementType) result.add n - t = skipTypes(t[0], {tyGenericInst, tyAlias, tySink, tyOwned}) + t = skipTypes(t.elementType, {tyGenericInst, tyAlias, tySink, tyOwned}) while t.kind in {tyPtr, tyRef}: var a = result - let baseTyp = t.lastSon + let baseTyp = t.elementType result = newNodeIT(nkHiddenDeref, n.info, baseTyp) result.add a t = skipTypes(baseTyp, {tyGenericInst, tyAlias, tySink, tyOwned}) @@ -703,7 +703,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = else: typ = def.typ.skipTypes({tyStatic, tySink}).skipIntLit(c.idgen) if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass: - typ = typ.lastSon + typ = typ.last if hasEmpty(typ): localError(c.config, def.info, errCannotInferTypeOfTheLiteral % typ.kind.toHumanStr) elif typ.kind == tyProc and def.kind == nkSym and isGenericRoutine(def.sym.ast): @@ -1043,7 +1043,7 @@ proc handleStmtMacro(c: PContext; n, selector: PNode; magicType: string; var symx = initOverloadIter(o, c, headSymbol) while symx != nil: if symx.kind in {skTemplate, skMacro}: - if symx.typ.len == 2 and symx.typ[1] == maType.typ: + if symx.typ.len == 2 and symx.typ.firstParamType == maType.typ: if match == nil: match = symx else: @@ -1238,7 +1238,7 @@ proc semRaise(c: PContext, n: PNode): PNode = typ = typ.skipTypes({tyAlias, tyGenericInst, tyOwned}) if typ.kind != tyRef: localError(c.config, n.info, errExprCannotBeRaised) - if typ.len > 0 and not isException(typ.lastSon): + if typ.len > 0 and not isException(typ.elementType): localError(c.config, n.info, "raised object of type $1 does not inherit from Exception" % typeToString(typ)) proc addGenericParamListToScope(c: PContext, n: PNode) = @@ -1401,7 +1401,7 @@ proc checkCovariantParamsUsages(c: PContext; genericType: PType) = if t.base.kind == tyGenericParam: return true return traverseSubTypes(c, t.base) of tyDistinct, tyAlias, tySink, tyOwned: - return traverseSubTypes(c, t.lastSon) + return traverseSubTypes(c, t.skipModifier) of tyGenericInst: internalAssert c.config, false else: @@ -1466,7 +1466,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = # possibilities such as instantiating C++ generic types with # garbage collected Nim types. if sfImportc in s.flags: - var body = s.typ.lastSon + var body = s.typ.last if body.kind == tyObject: # erases all declared fields body.n.sons = @[] @@ -1509,11 +1509,11 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = aa[0].kind == nkObjectTy: # give anonymous object a dummy symbol: var st = s.typ - if st.kind == tyGenericBody: st = st.lastSon + if st.kind == tyGenericBody: st = st.typeBodyImpl internalAssert c.config, st.kind in {tyPtr, tyRef} - internalAssert c.config, st.lastSon.sym == nil + internalAssert c.config, st.last.sym == nil incl st.flags, tfRefsAnonObj - let objTy = st.lastSon + let objTy = st.last # add flags for `ref object` etc to underlying `object` incl(objTy.flags, oldFlags) # {.inheritable, final.} is already disallowed, but @@ -1526,12 +1526,12 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = let symNode = newSymNode(obj) obj.ast = a.shallowCopy case a[0].kind - of nkSym: obj.ast[0] = symNode - of nkPragmaExpr: - obj.ast[0] = a[0].shallowCopy - obj.ast[0][0] = symNode - obj.ast[0][1] = a[0][1] - else: assert(false) + of nkSym: obj.ast[0] = symNode + of nkPragmaExpr: + obj.ast[0] = a[0].shallowCopy + obj.ast[0][0] = symNode + obj.ast[0][1] = a[0][1] + else: assert(false) obj.ast[1] = a[1] obj.ast[2] = a[2][0] if sfPure in s.flags: @@ -1682,25 +1682,25 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) = # search for the correct alias: var (b, state) = searchForBorrowProc(c, c.currentScope.parent, s) case state - of bsMatch: - # store the alias: - n[bodyPos] = newSymNode(b) - # Carry over the original symbol magic, this is necessary in order to ensure - # the semantic pass is correct - s.magic = b.magic - if b.typ != nil and b.typ.len > 0: - s.typ.n[0] = b.typ.n[0] - s.typ.flags = b.typ.flags - of bsNoDistinct: - localError(c.config, n.info, "borrow proc without distinct type parameter is meaningless") - of bsReturnNotMatch: - localError(c.config, n.info, "borrow from proc return type mismatch: '$1'" % typeToString(b.typ[0])) - of bsGeneric: - localError(c.config, n.info, "borrow with generic parameter is not supported") - of bsNotSupported: - localError(c.config, n.info, "borrow from '$1' is not supported" % $b.name.s) - else: - localError(c.config, n.info, errNoSymbolToBorrowFromFound) + of bsMatch: + # store the alias: + n[bodyPos] = newSymNode(b) + # Carry over the original symbol magic, this is necessary in order to ensure + # the semantic pass is correct + s.magic = b.magic + if b.typ != nil and b.typ.len > 0: + s.typ.n[0] = b.typ.n[0] + s.typ.flags = b.typ.flags + of bsNoDistinct: + localError(c.config, n.info, "borrow proc without distinct type parameter is meaningless") + of bsReturnNotMatch: + localError(c.config, n.info, "borrow from proc return type mismatch: '$1'" % typeToString(b.typ.returnType)) + of bsGeneric: + localError(c.config, n.info, "borrow with generic parameter is not supported") + of bsNotSupported: + localError(c.config, n.info, "borrow from '$1' is not supported" % $b.name.s) + else: + localError(c.config, n.info, errNoSymbolToBorrowFromFound) proc swapResult(n: PNode, sRes: PSym, dNode: PNode) = ## Swap nodes that are (skResult) symbols to d(estination)Node. @@ -1813,8 +1813,8 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode = pushOwner(c, s) addParams(c, params, skProc) pushProcCon(c, s) - addResult(c, n, n.typ[0], skProc) - s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos], n.typ[0])) + addResult(c, n, n.typ.returnType, skProc) + s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos], n.typ.returnType)) trackProc(c, s, s.ast[bodyPos]) popProcCon(c) popOwner(c) @@ -1844,8 +1844,8 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) = if s.kind == skMacro: let resultType = sysTypeFromName(c.graph, n.info, "NimNode") addResult(c, n, resultType, s.kind) - elif s.typ[0] != nil and not isInlineIterator(s.typ): - addResult(c, n, s.typ[0], s.kind) + elif s.typ.returnType != nil and not isInlineIterator(s.typ): + addResult(c, n, s.typ.returnType, s.kind) proc canonType(c: PContext, t: PType): PType = if t.kind == tySequence: @@ -1864,7 +1864,7 @@ proc prevDestructor(c: PContext; prevOp: PSym; obj: PType; info: TLineInfo) = proc whereToBindTypeHook(c: PContext; t: PType): PType = result = t while true: - if result.kind in {tyGenericBody, tyGenericInst}: result = result.lastSon + if result.kind in {tyGenericBody, tyGenericInst}: result = result.skipModifier elif result.kind == tyGenericInvocation: result = result[0] else: break if result.kind in {tyObject, tyDistinct, tySequence, tyString}: @@ -1879,13 +1879,13 @@ proc bindDupHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp) = var obj = t[1] while true: incl(obj.flags, tfHasAsgn) - if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon + if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.skipModifier elif obj.kind == tyGenericInvocation: obj = obj[0] else: break var res = t[0] while true: - if res.kind in {tyGenericBody, tyGenericInst}: res = res.lastSon + if res.kind in {tyGenericBody, tyGenericInst}: res = res.skipModifier elif res.kind == tyGenericInvocation: res = res[0] else: break @@ -1925,7 +1925,7 @@ proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp; suppressV var obj = t[1].skipTypes({tyVar}) while true: incl(obj.flags, tfHasAsgn) - if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon + if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.skipModifier elif obj.kind == tyGenericInvocation: obj = obj[0] else: break if obj.kind in {tyObject, tyDistinct, tySequence, tyString}: @@ -1969,13 +1969,13 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = newIdentNode(c.cache.getIdent("raises"), s.info), newNodeI(nkBracket, s.info)) of "deepcopy", "=deepcopy": if s.typ.len == 2 and - s.typ[1].skipTypes(abstractInst).kind in {tyRef, tyPtr} and - sameType(s.typ[1], s.typ[0]): + s.typ.firstParamType.skipTypes(abstractInst).kind in {tyRef, tyPtr} and + sameType(s.typ.firstParamType, s.typ.returnType): # Note: we store the deepCopy in the base of the pointer to mitigate # the problem that pointers are structural types: - var t = s.typ[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst) + var t = s.typ.firstParamType.skipTypes(abstractInst).elementType.skipTypes(abstractInst) while true: - if t.kind == tyGenericBody: t = t.lastSon + if t.kind == tyGenericBody: t = t.typeBodyImpl elif t.kind == tyGenericInvocation: t = t[0] else: break if t.kind in {tyObject, tyDistinct, tyEnum, tySequence, tyString}: @@ -2008,12 +2008,12 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = var obj = t[1][0] while true: incl(obj.flags, tfHasAsgn) - if obj.kind == tyGenericBody: obj = obj.lastSon + if obj.kind == tyGenericBody: obj = obj.skipModifier elif obj.kind == tyGenericInvocation: obj = obj[0] else: break var objB = t[2] while true: - if objB.kind == tyGenericBody: objB = objB.lastSon + if objB.kind == tyGenericBody: objB = objB.skipModifier elif objB.kind in {tyGenericInvocation, tyGenericInst}: objB = objB[0] else: break @@ -2087,15 +2087,15 @@ proc semCppMember(c: PContext; s: PSym; n: PNode) = localError(c.config, n.info, pragmaName & " unsupported for generic routine") var typ: PType if isCtor: - typ = s.typ[0] + typ = s.typ.returnType if typ == nil or typ.kind != tyObject: localError(c.config, n.info, "constructor must return an object") if sfImportc in typ.sym.flags: localError(c.config, n.info, "constructor in an imported type needs importcpp pragma") else: - typ = s.typ[1] + typ = s.typ.firstParamType if typ.kind == tyPtr and not isCtor: - typ = typ[0] + typ = typ.elementType if typ.kind != tyObject: localError(c.config, n.info, pragmaName & " must be either ptr to object or object type.") if typ.owner.id == s.owner.id and c.module.id == s.owner.id: @@ -2106,7 +2106,7 @@ proc semCppMember(c: PContext; s: PSym; n: PNode) = else: localError(c.config, n.info, pragmaName & " procs are only supported in C++") else: - var typ = s.typ[0] + var typ = s.typ.returnType if typ != nil and typ.kind == tyObject and typ.itemId notin c.graph.initializersPerType: var initializerCall = newTree(nkCall, newSymNode(s)) var isInitializer = n[paramsPos].len > 1 @@ -2360,8 +2360,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, # absolutely no generics (empty) or a single generic return type are # allowed, everything else, including a nullary generic is an error. pushProcCon(c, s) - addResult(c, n, s.typ[0], skProc) - s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos], s.typ[0])) + addResult(c, n, s.typ.returnType, skProc) + s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos], s.typ.returnType)) trackProc(c, s, s.ast[bodyPos]) popProcCon(c) elif efOperand notin flags: @@ -2377,7 +2377,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if s.kind == skMacro: sysTypeFromName(c.graph, n.info, "NimNode") elif not isInlineIterator(s.typ): - s.typ[0] + s.typ.returnType else: nil # semantic checking also needed with importc in case used in VM @@ -2386,7 +2386,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, # context as it may even be evaluated in 'system.compiles': trackProc(c, s, s.ast[bodyPos]) else: - if (s.typ[0] != nil and s.kind != skIterator): + if (s.typ.returnType != nil and s.kind != skIterator): addDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), c.idgen, s, n.info)) openScope(c) @@ -2401,7 +2401,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if hasProto: localError(c.config, n.info, errImplOfXexpected % proto.name.s) if {sfImportc, sfBorrow, sfError} * s.flags == {} and s.magic == mNone: # this is a forward declaration and we're building the prototype - if s.kind in {skProc, skFunc} and s.typ[0] != nil and s.typ[0].kind == tyAnything: + if s.kind in {skProc, skFunc} and s.typ.returnType != nil and s.typ.returnType.kind == tyAnything: localError(c.config, n[paramsPos][0].info, "return type 'auto' cannot be used in forward declarations") incl(s.flags, sfForward) @@ -2483,9 +2483,9 @@ proc semMethod(c: PContext, n: PNode): PNode = # test case): let disp = getDispatcher(s) # auto return type? - if disp != nil and disp.typ[0] != nil and disp.typ[0].kind == tyUntyped: - let ret = s.typ[0] - disp.typ[0] = ret + if disp != nil and disp.typ.returnType != nil and disp.typ.returnType.kind == tyUntyped: + let ret = s.typ.returnType + disp.typ.setReturnType ret if disp.ast[resultPos].kind == nkSym: if isEmptyType(ret): disp.ast[resultPos] = c.graph.emptyNode else: disp.ast[resultPos].sym.typ = ret diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 3256b8d85..20c8f57bd 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -657,7 +657,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = # a template's parameters are not gensym'ed even if that was originally the # case as we determine whether it's a template parameter in the template # body by the absence of the sfGenSym flag: - let retType = s.typ[0] + let retType = s.typ.returnType if retType != nil and retType.kind != tyUntyped: allUntyped = false for i in 1..<s.typ.n.len: @@ -673,7 +673,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = # XXX why do we need tyTyped as a return type again? s.typ.n = newNodeI(nkFormalParams, n.info) rawAddSon(s.typ, newTypeS(tyTyped, c)) - s.typ.n.add newNodeIT(nkType, n.info, s.typ[0]) + s.typ.n.add newNodeIT(nkType, n.info, s.typ.returnType) if n[genericParamsPos].safeLen == 0: # restore original generic type params as no explicit or implicit were found n[genericParamsPos] = n[miscPos][1] diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 7968122ed..e27713522 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -173,7 +173,7 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType = if n.len == 2 and n[1].kind != nkEmpty: var base = semTypeNode(c, n[1], nil) addSonSkipIntLit(result, base, c.idgen) - if base.kind in {tyGenericInst, tyAlias, tySink}: base = lastSon(base) + if base.kind in {tyGenericInst, tyAlias, tySink}: base = skipModifier(base) if base.kind notin {tyGenericParam, tyGenericInvocation}: if base.kind == tyForward: c.skipTypes.add n @@ -232,7 +232,7 @@ proc isRecursiveType(t: PType, cycleDetector: var IntSet): bool = return true case t.kind of tyAlias, tyGenericInst, tyDistinct: - return isRecursiveType(t.lastSon, cycleDetector) + return isRecursiveType(t.skipModifier, cycleDetector) else: return false @@ -379,11 +379,11 @@ proc semArrayIndex(c: PContext, n: PNode): PType = localError(c.config, n.info, "Array length can't be negative, but was " & $e.intVal) result = makeRangeType(c, 0, e.intVal-1, n.info, e.typ) - elif e.kind == nkSym and (e.typ.kind == tyStatic or e.typ.kind == tyTypeDesc) : + elif e.kind == nkSym and (e.typ.kind == tyStatic or e.typ.kind == tyTypeDesc): if e.typ.kind == tyStatic: if e.sym.ast != nil: return semArrayIndex(c, e.sym.ast) - if e.typ.lastSon.kind != tyGenericParam and not isOrdinalType(e.typ.lastSon): + if e.typ.skipModifier.kind != tyGenericParam and not isOrdinalType(e.typ.skipModifier): let info = if n.safeLen > 1: n[1].info else: n.info localError(c.config, info, errOrdinalTypeExpected % typeToString(e.typ, preferDesc)) result = makeRangeWithStaticExpr(c, e) @@ -412,7 +412,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = # 3 = length(array indx base) let indx = semArrayIndex(c, n[1]) var indxB = indx - if indxB.kind in {tyGenericInst, tyAlias, tySink}: indxB = lastSon(indxB) + if indxB.kind in {tyGenericInst, tyAlias, tySink}: indxB = skipModifier(indxB) if indxB.kind notin {tyGenericParam, tyStatic, tyFromExpr} and tfUnresolved notin indxB.flags: if indxB.skipTypes({tyRange}).kind in {tyUInt, tyUInt64}: @@ -897,7 +897,7 @@ proc skipGenericInvocation(t: PType): PType {.inline.} = if result.kind == tyGenericInvocation: result = result[0] while result.kind in {tyGenericInst, tyGenericBody, tyRef, tyPtr, tyAlias, tySink, tyOwned}: - result = lastSon(result) + result = skipModifier(result) proc tryAddInheritedFields(c: PContext, check: var IntSet, pos: var int, obj: PType, n: PNode, isPartial = false, innerObj: PType = nil): bool = @@ -1013,7 +1013,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = addSonSkipIntLit(result, region, c.idgen) addSonSkipIntLit(result, t, c.idgen) if tfPartial in result.flags: - if result.lastSon.kind == tyObject: incl(result.lastSon.flags, tfPartial) + if result.elementType.kind == tyObject: incl(result.elementType.flags, tfPartial) # if not isNilable: result.flags.incl tfNotNil case wrapperKind of tyOwned: @@ -1159,7 +1159,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, # like: type myseq = distinct seq. # Maybe there is another better place to associate # the seq type class with the seq identifier. - if paramType.kind == tySequence and paramType.lastSon.kind == tyNone: + if paramType.kind == tySequence and paramType.elementType.kind == tyNone: let typ = c.newTypeWithSons(tyBuiltInTypeClass, @[newTypeS(paramType.kind, c)]) result = addImplicitGeneric(c, typ, paramTypId, info, genericParams, paramName) @@ -1185,9 +1185,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, else: result.rawAddSon newTypeS(tyAnything, c) - if paramType.lastSon.kind == tyUserTypeClass: + if paramType.typeBodyImpl.kind == tyUserTypeClass: result.kind = tyUserTypeClassInst - result.rawAddSon paramType.lastSon + result.rawAddSon paramType.typeBodyImpl return addImplicitGeneric(c, result, paramTypId, info, genericParams, paramName) let x = instGenericContainer(c, paramType.sym.info, result, @@ -1199,7 +1199,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, of tyGenericInst: result = nil - if paramType.lastSon.kind == tyUserTypeClass: + if paramType.skipModifier.kind == tyUserTypeClass: var cp = copyType(paramType, c.idgen, getCurrOwner(c)) copyTypeProps(c.graph, c.idgen.module, cp, paramType) @@ -1211,9 +1211,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, if lifted != nil: paramType[i] = lifted result = paramType - result.lastSon.shouldHaveMeta + result.last.shouldHaveMeta - let liftBody = recurse(paramType.lastSon, true) + let liftBody = recurse(paramType.skipModifier, true) if liftBody != nil: result = liftBody result.flags.incl tfHasMeta @@ -1232,7 +1232,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, # before one of its param types return - if body.lastSon.kind == tyUserTypeClass: + if body.last.kind == tyUserTypeClass: let expanded = instGenericContainer(c, info, paramType, allowMetaTypes = true) result = recurse(expanded, true) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index bb664c71f..b514cc8fa 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -18,20 +18,16 @@ when defined(nimPreviewSlimSystem): const tfInstClearedFlags = {tfHasMeta, tfUnresolved} proc checkPartialConstructedType(conf: ConfigRef; info: TLineInfo, t: PType) = - if t.kind in {tyVar, tyLent} and t[0].kind in {tyVar, tyLent}: + if t.kind in {tyVar, tyLent} and t.elementType.kind in {tyVar, tyLent}: localError(conf, info, "type 'var var' is not allowed") proc checkConstructedType*(conf: ConfigRef; info: TLineInfo, typ: PType) = var t = typ.skipTypes({tyDistinct}) if t.kind in tyTypeClasses: discard - elif t.kind in {tyVar, tyLent} and t[0].kind in {tyVar, tyLent}: + elif t.kind in {tyVar, tyLent} and t.elementType.kind in {tyVar, tyLent}: localError(conf, info, "type 'var var' is not allowed") elif computeSize(conf, t) == szIllegalRecursion or isTupleRecursive(t): localError(conf, info, "illegal recursion in type '" & typeToString(t) & "'") - when false: - if t.kind == tyObject and t[0] != nil: - if t[0].kind != tyObject or tfFinal in t[0].flags: - localError(info, errInheritanceOnlyWithNonFinalObjects) proc searchInstTypes*(g: ModuleGraph; key: PType): PType = result = nil @@ -61,7 +57,7 @@ proc searchInstTypes*(g: ModuleGraph; key: PType): PType = proc cacheTypeInst(c: PContext; inst: PType) = let gt = inst[0] - let t = if gt.kind == tyGenericBody: gt.lastSon else: gt + let t = if gt.kind == tyGenericBody: gt.typeBodyImpl else: gt if t.kind in {tyStatic, tyError, tyGenericParam} + tyTypeClasses: return addToGenericCache(c, gt.sym, inst) @@ -418,7 +414,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = if body.kind == tyError: return - let bbody = lastSon body + let bbody = last body var newbody = replaceTypeVarsT(cl, bbody) cl.skipTypedesc = oldSkipTypedesc newbody.flags = newbody.flags + (t.flags + body.flags - tfInstClearedFlags) @@ -449,11 +445,11 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = # can come here for tyGenericInst too, see tests/metatype/ttypeor.nim # need to look into this issue later assert newbody.kind in {tyRef, tyPtr} - if newbody.lastSon.typeInst != nil: + if newbody.last.typeInst != nil: #internalError(cl.c.config, cl.info, "ref already has a 'typeInst' field") discard else: - newbody.lastSon.typeInst = result + newbody.last.typeInst = result # DESTROY: adding object|opt for opt[topttree.Tree] # sigmatch: Formal opt[=destroy.T] real opt[topttree.Tree] # adding myseq for myseq[system.int] @@ -554,7 +550,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = case t.kind of tyGenericInvocation: result = handleGenericInvocation(cl, t) - if result.lastSon.kind == tyUserTypeClass: + if result.last.kind == tyUserTypeClass: result.kind = tyUserTypeClassInst of tyGenericBody: @@ -617,7 +613,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = idTablePut(cl.localCache, t, result) for i in 1..<result.len: result[i] = replaceTypeVarsT(cl, result[i]) - propagateToOwner(result, result.lastSon) + propagateToOwner(result, result.last) else: if containsGenericType(t): diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 2f1a72fd6..ca1b74604 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -110,9 +110,9 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi if CoDistinct in flags: if t.sym != nil: c.hashSym(t.sym) if t.sym == nil or tfFromGeneric in t.flags: - c.hashType t.lastSon, flags, conf + c.hashType t.elementType, flags, conf elif CoType in flags or t.sym == nil: - c.hashType t.lastSon, flags, conf + c.hashType t.elementType, flags, conf else: c.hashSym(t.sym) of tyGenericInst: @@ -124,13 +124,13 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi for i in 0..<normalizedType.len - 1: c.hashType t[i], flags, conf else: - c.hashType t.lastSon, flags, conf + c.hashType t.skipModifier, flags, conf of tyAlias, tySink, tyUserTypeClasses, tyInferred: - c.hashType t.lastSon, flags, conf + c.hashType t.skipModifier, flags, conf of tyOwned: if CoConsiderOwned in flags: c &= char(t.kind) - c.hashType t.lastSon, flags, conf + c.hashType t.skipModifier, flags, conf of tyBool, tyChar, tyInt..tyUInt64: # no canonicalization for integral types, so that e.g. ``pid_t`` is # produced instead of ``NI``: @@ -184,13 +184,17 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi c &= ".empty" else: c &= t.id - if t.len > 0 and t[0] != nil: - hashType c, t[0], flags, conf - of tyRef, tyPtr, tyGenericBody, tyVar: + if t.len > 0 and t.baseClass != nil: + hashType c, t.baseClass, flags, conf + of tyRef, tyPtr, tyVar: c &= char(t.kind) if t.len > 0: - c.hashType t.lastSon, flags, conf + c.hashType t.elementType, flags, conf if tfVarIsPtr in t.flags: c &= ".varisptr" + of tyGenericBody: + c &= char(t.kind) + if t.len > 0: + c.hashType t.typeBodyImpl, flags, conf of tyFromExpr: c &= char(t.kind) c.hashTree(t.n, {}, conf) @@ -210,11 +214,11 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi if CoIgnoreRange notin flags: c &= char(t.kind) c.hashTree(t.n, {}, conf) - c.hashType(t[0], flags, conf) + c.hashType(t.elementType, flags, conf) of tyStatic: c &= char(t.kind) c.hashTree(t.n, {}, conf) - c.hashType(t[0], flags, conf) + c.hashType(t.skipModifier, flags, conf) of tyProc: c &= char(t.kind) c &= (if tfIterator in t.flags: "iterator " else: "proc ") @@ -226,7 +230,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi c &= ':' c.hashType(param.typ, flags, conf) c &= ',' - c.hashType(t[0], flags, conf) + c.hashType(t.returnType, flags, conf) else: for i in 0..<t.len: c.hashType(t[i], flags, conf) c &= char(t.callConv) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index aa7a72dd9..c52c90c7d 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -214,10 +214,16 @@ proc sumGeneric(t: PType): int = var isvar = 0 while true: case t.kind - of tyGenericInst, tyArray, tyRef, tyPtr, tyDistinct, tyUncheckedArray, - tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyGenericBody, + of tyArray, tyRef, tyPtr, tyDistinct, tyUncheckedArray, + tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyLent, tyOwned: - t = t.lastSon + t = t.elementType + inc result + of tyGenericInst: + t = t.skipModifier + inc result + of tyGenericBody: + t = t.typeBodyImpl inc result of tyOr: var maxBranch = 0 @@ -227,11 +233,11 @@ proc sumGeneric(t: PType): int = inc result, maxBranch break of tyVar: - t = t[0] + t = t.elementType inc result inc isvar of tyTypeDesc: - t = t.lastSon + t = t.elementType if t.kind == tyEmpty: break inc result of tyGenericInvocation, tyTuple, tyProc, tyAnd: @@ -241,9 +247,9 @@ proc sumGeneric(t: PType): int = result += sumGeneric(t[i]) break of tyStatic: - return sumGeneric(t[0]) + 1 + return sumGeneric(t.skipModifier) + 1 of tyGenericParam, tyUntyped, tyTyped: break - of tyAlias, tySink: t = t.lastSon + of tyAlias, tySink: t = t.skipModifier of tyBool, tyChar, tyEnum, tyObject, tyPointer, tyString, tyCstring, tyInt..tyInt64, tyFloat..tyFloat128, tyUInt..tyUInt64, tyCompositeTypeClass: @@ -372,7 +378,7 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType = # 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: - result = t.lastSon + result = t.skipModifier else: result = t else: @@ -468,13 +474,16 @@ proc getObjectTypeOrNil(f: PType): PType = result = nil else: result = getObjectTypeOrNil(f[0]) - of tyGenericBody, tyGenericInst: - result = getObjectTypeOrNil(f.lastSon) + of tyGenericInst: + result = getObjectTypeOrNil(f.skipModifier) + of tyGenericBody: + result = getObjectTypeOrNil(f.typeBodyImpl) + of tyUserTypeClass: if f.isResolvedUserTypeClass: result = f.base # ?? idk if this is right else: - result = f.lastSon + result = f.skipModifier of tyStatic, tyOwned, tyVar, tyLent, tySink: result = getObjectTypeOrNil(f.base) of tyInferred: @@ -483,7 +492,7 @@ proc getObjectTypeOrNil(f: PType): PType = of tyTyped, tyUntyped, tyFromExpr: result = nil of tyRange: - result = f.lastSon + result = f.elementType else: result = f @@ -528,13 +537,15 @@ proc skipToObject(t: PType; skipped: var SkippedPtr): PType = of tyRef: inc ptrs skipped = skippedRef - r = r.lastSon + r = r.elementType of tyPtr: inc ptrs skipped = skippedPtr - r = r.lastSon - of tyGenericBody, tyGenericInst, tyAlias, tySink, tyOwned: - r = r.lastSon + r = r.elementType + of tyGenericInst, tyAlias, tySink, tyOwned: + r = r.elementType + of tyGenericBody: + r = r.typeBodyImpl else: break if r.kind == tyObject and ptrs <= 1: result = r @@ -930,7 +941,7 @@ proc inferStaticParam*(c: var TCandidate, lhs: PNode, rhs: BiggestInt): bool = else: discard elif lhs.kind == nkSym and lhs.typ.kind == tyStatic and lhs.typ.n == nil: - var inferred = newTypeWithSons(c.c, tyStatic, lhs.typ) + var inferred = newTypeWithSons(c.c, tyStatic, @[lhs.typ.elementType]) inferred.n = newIntNode(nkIntLit, rhs) put(c, lhs.typ, inferred) if c.c.matchedConcept != nil: @@ -973,7 +984,7 @@ proc inferStaticsInRange(c: var TCandidate, doInferStatic(lowerBound, getInt(upperBound) + 1 - lengthOrd(c.c.config, concrete)) template subtypeCheck() = - if result <= isSubrange and f.lastSon.skipTypes(abstractInst).kind in { + if result <= isSubrange and f.last.skipTypes(abstractInst).kind in { tyRef, tyPtr, tyVar, tyLent, tyOwned}: result = isNone @@ -1105,16 +1116,16 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, # situation when nkDotExpr are rotated to nkDotCalls if aOrig.kind in {tyAlias, tySink}: - return typeRel(c, f, lastSon(aOrig), flags) + return typeRel(c, f, skipModifier(aOrig), flags) if a.kind == tyGenericInst and skipTypes(f, {tyStatic, tyVar, tyLent, tySink}).kind notin { tyGenericBody, tyGenericInvocation, tyGenericInst, tyGenericParam} + tyTypeClasses: - return typeRel(c, f, lastSon(a), flags) + return typeRel(c, f, skipModifier(a), flags) if a.isResolvedUserTypeClass: - return typeRel(c, f, a.lastSon, flags) + return typeRel(c, f, a.skipModifier, flags) template bindingRet(res) = if doBind: @@ -1161,7 +1172,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, # seq[float] matches the first, but not the second # we must turn the problem around: # is number a subset of int? - return typeRel(c, a.lastSon, f.lastSon, flags) + return typeRel(c, a.elementType, f.elementType, flags) else: # negative type classes are essentially infinite, @@ -1248,12 +1259,12 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, of tyArray: case a.kind of tyArray: - var fRange = f[0] - var aRange = a[0] + var fRange = f.indexType + var aRange = a.indexType if fRange.kind in {tyGenericParam, tyAnything}: var prev = PType(idTableGet(c.bindings, fRange)) if prev == nil: - put(c, fRange, a[0]) + put(c, fRange, a.indexType) fRange = a else: fRange = prev @@ -1261,7 +1272,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, # This typeDesc rule is wrong, see bug #7331 let aa = a[1] #.skipTypes({tyTypeDesc}) - if f[0].kind != tyGenericParam and aa.kind == tyEmpty: + if f.indexType.kind != tyGenericParam and aa.kind == tyEmpty: result = isGeneric else: result = typeRel(c, ff, aa, flags) @@ -1287,7 +1298,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, else: discard of tyUncheckedArray: if a.kind == tyUncheckedArray: - result = typeRel(c, base(f), base(a), flags) + result = typeRel(c, elementType(f), elementType(a), flags) if result < isGeneric: result = isNone else: discard of tyOpenArray, tyVarargs: @@ -1295,7 +1306,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, # handle varargs[typed]: if f.kind == tyVarargs: if tfVarargs in a.flags: - return typeRel(c, f.base, a.lastSon, flags) + return typeRel(c, f.base, a.elementType, flags) if f[0].kind == tyTyped: return template matchArrayOrSeq(aBase: PType) = @@ -1315,13 +1326,13 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, result = typeRel(c, base(f), base(a), flags) if result < isGeneric: result = isNone of tyArray: - if (f[0].kind != tyGenericParam) and (a[1].kind == tyEmpty): + if (f[0].kind != tyGenericParam) and (a.elementType.kind == tyEmpty): return isSubtype - matchArrayOrSeq(a[1]) + matchArrayOrSeq(a.elementType) of tySequence: - if (f[0].kind != tyGenericParam) and (a[0].kind == tyEmpty): + if (f[0].kind != tyGenericParam) and (a.elementType.kind == tyEmpty): return isConvertible - matchArrayOrSeq(a[0]) + matchArrayOrSeq(a.elementType) of tyString: if f.kind == tyOpenArray: if f[0].kind == tyChar: @@ -1333,11 +1344,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, of tySequence: case a.kind of tySequence: - if (f[0].kind != tyGenericParam) and (a[0].kind == tyEmpty): + if (f[0].kind != tyGenericParam) and (a.elementType.kind == tyEmpty): result = isSubtype else: let ff = f[0] - let aa = a[0] + let aa = a.elementType result = typeRel(c, ff, aa, flags) if result < isGeneric: if nimEnableCovariance and @@ -1351,7 +1362,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, else: discard of tyOrdinal: if isOrdinalType(a): - var x = if a.kind == tyOrdinal: a[0] else: a + var x = if a.kind == tyOrdinal: a.elementType else: a if f[0].kind == tyNone: result = isGeneric else: @@ -1409,7 +1420,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, if a.len < f.len: return isNone for i in 0..<f.len-1: if typeRel(c, f[i], a[i], flags) == isNone: return isNone - result = typeRel(c, f.lastSon, a.lastSon, flags + {trNoCovariance}) + result = typeRel(c, f.elementType, a.elementType, flags + {trNoCovariance}) subtypeCheck() if result <= isIntConv: result = isNone elif tfNotNil in f.flags and tfNotNil notin a.flags: @@ -1424,7 +1435,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, of tyOwned: case a.kind of tyOwned: - result = typeRel(c, lastSon(f), lastSon(a), flags) + result = typeRel(c, skipModifier(f), skipModifier(a), flags) of tyNil: result = f.allowsNil else: discard of tyPointer: @@ -1481,12 +1492,12 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, if a.kind == f.kind: result = isEqual of tyAlias, tySink: - result = typeRel(c, lastSon(f), a, flags) + result = typeRel(c, skipModifier(f), a, flags) of tyIterable: if a.kind == tyIterable: if f.len == 1: - result = typeRel(c, lastSon(f), lastSon(a), flags) + result = typeRel(c, skipModifier(f), skipModifier(a), flags) else: # f.len = 3, for some reason result = isGeneric @@ -1534,13 +1545,13 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, return isNone if prev == nil: put(c, f, a) else: - let fKind = rootf.lastSon.kind + let fKind = rootf.last.kind if fKind in {tyAnd, tyOr}: - result = typeRel(c, lastSon(f), a, flags) + result = typeRel(c, last(f), a, flags) if result != isNone: put(c, f, a) return - var aAsObject = roota.lastSon + var aAsObject = roota.last if fKind in {tyRef, tyPtr}: if aAsObject.kind == tyObject: @@ -1559,8 +1570,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, result = isNone else: - assert lastSon(origF) != nil - result = typeRel(c, lastSon(origF), a, flags) + assert last(origF) != nil + result = typeRel(c, last(origF), a, flags) if result != isNone and a.kind != tyNil: put(c, f, a) @@ -1568,19 +1579,19 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, considerPreviousT: if a == f or a.kind == tyGenericInst and a.skipGenericAlias[0] == f: bindingRet isGeneric - let ff = lastSon(f) + let ff = last(f) if ff != nil: result = typeRel(c, ff, a, flags) of tyGenericInvocation: var x = a.skipGenericAlias if x.kind == tyGenericParam and x.len > 0: - x = x.lastSon + x = x.last let concpt = f[0].skipTypes({tyGenericBody}) var preventHack = concpt.kind == tyConcept if x.kind == tyOwned and f[0].kind != tyOwned: preventHack = true - x = x.lastSon + x = x.last # XXX: This is very hacky. It should be moved back into liftTypeParam if x.kind in {tyGenericInst, tyArray} and c.calleeSym != nil and @@ -1613,7 +1624,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, var askip = skippedNone var fskip = skippedNone let aobj = x.skipToObject(askip) - let fobj = genericBody.lastSon.skipToObject(fskip) + let fobj = genericBody.last.skipToObject(fskip) result = typeRel(c, genericBody, x, flags) if result != isNone: # see tests/generics/tgeneric3.nim for an example that triggers this @@ -1723,7 +1734,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, of tyUserTypeClassInst, tyUserTypeClass: if f.isResolvedUserTypeClass: - result = typeRel(c, f.lastSon, a, flags) + result = typeRel(c, f.last, a, flags) else: considerPreviousT: if aOrig == f: return isEqual @@ -1732,7 +1743,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, bindConcreteTypeToUserTypeClass(matched, a) if doBind: put(c, f, matched) result = isGeneric - elif a.len > 0 and a.lastSon == f: + elif a.len > 0 and a.last == f: # Needed for checking `Y` == `Addable` in the following #[ type @@ -1751,7 +1762,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, of tyCompositeTypeClass: considerPreviousT: let roota = a.skipGenericAlias - let rootf = f.lastSon.skipGenericAlias + let rootf = f.last.skipGenericAlias if a.kind == tyGenericInst and roota.base == rootf.base: for i in 1..<rootf.len-1: let ff = rootf[i] @@ -1760,7 +1771,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, if result == isNone: return if ff.kind == tyRange and result != isEqual: return isNone else: - result = typeRel(c, rootf.lastSon, a, flags) + result = typeRel(c, rootf.last, a, flags) if result != isNone: put(c, f, a) result = isGeneric @@ -1785,7 +1796,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, c.typedescMatched = true var aa = a while aa.kind in {tyTypeDesc, tyGenericParam} and aa.len > 0: - aa = lastSon(aa) + aa = last(aa) if aa.kind in {tyGenericParam} + tyTypeClasses: # If the constraint is a genericParam or typeClass this isGeneric return isGeneric @@ -1859,7 +1870,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, elif f.base.kind == tyGenericParam: # Handling things like `type A[T; Y: static T] = object` if f.base.len > 0: # There is a constraint, handle it - result = typeRel(c, f.base.lastSon, a, flags) + result = typeRel(c, f.base.last, a, flags) else: # No constraint if tfGenericTypeParam in f.flags: @@ -1872,7 +1883,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, if result != isNone: put(c, f, aOrig) elif aOrig.n != nil and aOrig.n.typ != nil: result = if f.base.kind != tyNone: - typeRel(c, f.lastSon, aOrig.n.typ, flags) + typeRel(c, f.last, aOrig.n.typ, flags) else: isGeneric if result != isNone: var boundType = newTypeWithSons(c.c, tyStatic, @[aOrig.n.typ]) @@ -1882,7 +1893,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, result = isNone elif prev.kind == tyStatic: if aOrig.kind == tyStatic: - result = typeRel(c, prev.lastSon, a, flags) + result = typeRel(c, prev.last, a, flags) if result != isNone and prev.n != nil: if not exprStructuralEquivalent(prev.n, aOrig.n): result = isNone @@ -2039,8 +2050,8 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType, arg: PNode): PNode = result = nil for i in 0..<c.converters.len: - var src = c.converters[i].typ[1] - var dest = c.converters[i].typ[0] + var src = c.converters[i].typ.firstParamType + var dest = c.converters[i].typ.returnType # for generic type converters we need to check 'src <- a' before # 'f <- dest' in order to not break the unification: # see tests/tgenericconverter: @@ -2073,7 +2084,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType, param = implicitConv(nkHiddenSubConv, src, copyTree(arg), m, c) elif src.kind in {tyVar}: # Analyse the converter return type. - param = newNodeIT(nkHiddenAddr, arg.info, s.typ[1]) + param = newNodeIT(nkHiddenAddr, arg.info, s.typ.firstParamType) param.add copyTree(arg) else: param = copyTree(arg) @@ -2779,9 +2790,9 @@ proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo; var f = dc.typ[col] if op == attachedDeepCopy: - if f.kind in {tyRef, tyPtr}: f = f.lastSon + if f.kind in {tyRef, tyPtr}: f = f.elementType else: - if f.kind in {tyVar}: f = f.lastSon + if f.kind in {tyVar}: f = f.elementType if typeRel(m, f, t) == isNone: result = nil localError(c.config, info, "cannot instantiate: '" & dc.name.s & "'") diff --git a/compiler/sizealignoffsetimpl.nim b/compiler/sizealignoffsetimpl.nim index 9e5a9ab90..7cc11f55f 100644 --- a/compiler/sizealignoffsetimpl.nim +++ b/compiler/sizealignoffsetimpl.nim @@ -248,7 +248,7 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = typ.size = conf.target.ptrSize typ.align = int16(conf.target.ptrSize) of tyCstring, tySequence, tyPtr, tyRef, tyVar, tyLent: - let base = typ.lastSon + let base = typ.last if base == typ: # this is not the correct location to detect ``type A = ptr A`` typ.size = szIllegalRecursion @@ -262,9 +262,9 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = typ.size = conf.target.ptrSize of tyArray: - computeSizeAlign(conf, typ[1]) - let elemSize = typ[1].size - let len = lengthOrd(conf, typ[0]) + computeSizeAlign(conf, typ.elementType) + let elemSize = typ.elementType.size + let len = lengthOrd(conf, typ.indexType) if elemSize < 0: typ.size = elemSize typ.align = int16(elemSize) @@ -273,10 +273,10 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = typ.align = szUnknownSize else: typ.size = toInt64Checked(len * int32(elemSize), szTooBigSize) - typ.align = typ[1].align + typ.align = typ.elementType.align of tyUncheckedArray: - let base = typ.lastSon + let base = typ.last computeSizeAlign(conf, base) typ.size = 0 typ.align = base.align @@ -300,11 +300,11 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = typ.size = 8 typ.align = int16(conf.floatInt64Align) of tySet: - if typ[0].kind == tyGenericParam: + if typ.elementType.kind == tyGenericParam: typ.size = szUncomputedSize typ.align = szUncomputedSize else: - let length = toInt64(lengthOrd(conf, typ[0])) + let length = toInt64(lengthOrd(conf, typ.elementType)) if length <= 8: typ.size = 1 typ.align = 1 @@ -324,10 +324,10 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = typ.size = align(length, 8) div 8 + 1 typ.align = 1 of tyRange: - computeSizeAlign(conf, typ[0]) - typ.size = typ[0].size - typ.align = typ[0].align - typ.paddingAtEnd = typ[0].paddingAtEnd + computeSizeAlign(conf, typ.elementType) + typ.size = typ.elementType.size + typ.align = typ.elementType.align + typ.paddingAtEnd = typ.elementType.paddingAtEnd of tyTuple: try: @@ -351,11 +351,11 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = of tyObject: try: var accum = - if typ[0] != nil: + if typ.baseClass != nil: # compute header size - var st = typ[0] + var st = typ.baseClass while st.kind in skipPtrs: - st = st[^1] + st = st.skipModifier computeSizeAlign(conf, st) if conf.backend == backendCpp: OffsetAccum( @@ -403,24 +403,24 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = typ.align = szIllegalRecursion typ.paddingAtEnd = szIllegalRecursion of tyInferred: - if typ.len > 1: - computeSizeAlign(conf, typ.lastSon) - typ.size = typ.lastSon.size - typ.align = typ.lastSon.align - typ.paddingAtEnd = typ.lastSon.paddingAtEnd + if typ.len > 0: + computeSizeAlign(conf, typ.last) + typ.size = typ.last.size + typ.align = typ.last.align + typ.paddingAtEnd = typ.last.paddingAtEnd of tyGenericInst, tyDistinct, tyGenericBody, tyAlias, tySink, tyOwned: - computeSizeAlign(conf, typ.lastSon) - typ.size = typ.lastSon.size - typ.align = typ.lastSon.align - typ.paddingAtEnd = typ.lastSon.paddingAtEnd + computeSizeAlign(conf, typ.last) + typ.size = typ.last.size + typ.align = typ.last.align + typ.paddingAtEnd = typ.last.paddingAtEnd of tyTypeClasses: if typ.isResolvedUserTypeClass: - computeSizeAlign(conf, typ.lastSon) - typ.size = typ.lastSon.size - typ.align = typ.lastSon.align - typ.paddingAtEnd = typ.lastSon.paddingAtEnd + computeSizeAlign(conf, typ.last) + typ.size = typ.last.size + typ.align = typ.last.align + typ.paddingAtEnd = typ.last.paddingAtEnd else: typ.size = szUnknownSize typ.align = szUnknownSize @@ -439,10 +439,10 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = of tyStatic: if typ.n != nil: - computeSizeAlign(conf, typ.lastSon) - typ.size = typ.lastSon.size - typ.align = typ.lastSon.align - typ.paddingAtEnd = typ.lastSon.paddingAtEnd + computeSizeAlign(conf, typ.last) + typ.size = typ.last.size + typ.align = typ.last.align + typ.paddingAtEnd = typ.last.paddingAtEnd else: typ.size = szUnknownSize typ.align = szUnknownSize diff --git a/compiler/spawn.nim b/compiler/spawn.nim index bfcdd78ea..b140729a8 100644 --- a/compiler/spawn.nim +++ b/compiler/spawn.nim @@ -50,7 +50,7 @@ proc typeNeedsNoDeepCopy(t: PType): bool = # note that seq[T] is fine, but 'var seq[T]' is not, so we need to skip 'var' # for the stricter check and likewise we can skip 'seq' for a less # strict check: - if t.kind in {tyVar, tyLent, tySequence}: t = t.lastSon + if t.kind in {tyVar, tyLent, tySequence}: t = t.elementType result = not containsGarbageCollectedRef(t) proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; idgen: IdGenerator; owner: PSym; typ: PType; diff --git a/compiler/trees.nim b/compiler/trees.nim index e39cbafe6..99b6a9d01 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -116,7 +116,7 @@ proc isDeepConstExpr*(n: PNode; preventInheritance = false): bool = let t = n.typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink, tyOwned}) if t.kind in {tyRef, tyPtr} or tfUnion in t.flags: return false if t.kind == tyObject: - if preventInheritance and t[0] != nil: + if preventInheritance and t.baseClass != nil: result = false elif isCaseObj(t.n): result = false diff --git a/compiler/typeallowed.nim b/compiler/typeallowed.nim index 483e55bc9..e82de29f3 100644 --- a/compiler/typeallowed.nim +++ b/compiler/typeallowed.nim @@ -120,7 +120,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, if tfGenericTypeParam in t.flags or taConcept in flags: #or taField notin flags: discard elif t.isResolvedUserTypeClass: - result = typeAllowedAux(marker, t.lastSon, kind, c, flags) + result = typeAllowedAux(marker, t.last, kind, c, flags) elif kind notin {skParam, skResult}: result = t of tyGenericBody, tyGenericParam, tyGenericInvocation, @@ -133,9 +133,9 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, of tyOrdinal: if kind != skParam: result = t of tyGenericInst, tyDistinct, tyAlias, tyInferred: - result = typeAllowedAux(marker, lastSon(t), kind, c, flags) + result = typeAllowedAux(marker, skipModifier(t), kind, c, flags) of tyRange: - if skipTypes(t[0], abstractInst-{tyTypeDesc}).kind notin + if skipTypes(t.elementType, abstractInst-{tyTypeDesc}).kind notin {tyChar, tyEnum, tyInt..tyFloat128, tyInt..tyUInt64, tyRange}: result = t of tyOpenArray: # you cannot nest openArrays/sinks/etc. @@ -151,39 +151,39 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, result = typeAllowedAux(marker, t[0], kind, c, flags+{taIsOpenArray}) of tySink: # you cannot nest openArrays/sinks/etc. - if kind != skParam or taIsOpenArray in flags or t[0].kind in {tySink, tyLent, tyVar}: + if kind != skParam or taIsOpenArray in flags or t.elementType.kind in {tySink, tyLent, tyVar}: result = t else: - result = typeAllowedAux(marker, t[0], kind, c, flags) + result = typeAllowedAux(marker, t.elementType, kind, c, flags) of tyUncheckedArray: if kind != skParam and taHeap notin flags: result = t else: - result = typeAllowedAux(marker, lastSon(t), kind, c, flags-{taHeap}) + result = typeAllowedAux(marker, elementType(t), kind, c, flags-{taHeap}) of tySequence: - if t[0].kind != tyEmpty: - result = typeAllowedAux(marker, t[0], kind, c, flags+{taHeap}) + if t.elementType.kind != tyEmpty: + result = typeAllowedAux(marker, t.elementType, kind, c, flags+{taHeap}) elif kind in {skVar, skLet}: result = t[0] of tyArray: - if t[1].kind == tyTypeDesc: - result = t[1] - elif t[1].kind != tyEmpty: - result = typeAllowedAux(marker, t[1], kind, c, flags) + if t.elementType.kind == tyTypeDesc: + result = t.elementType + elif t.elementType.kind != tyEmpty: + result = typeAllowedAux(marker, t.elementType, kind, c, flags) elif kind in {skVar, skLet}: - result = t[1] + result = t.elementType of tyRef: if kind == skConst and taIsDefaultField notin flags: result = t - else: result = typeAllowedAux(marker, t.lastSon, kind, c, flags+{taHeap}) + else: result = typeAllowedAux(marker, t.elementType, kind, c, flags+{taHeap}) of tyPtr: - result = typeAllowedAux(marker, t.lastSon, kind, c, flags+{taHeap}) + result = typeAllowedAux(marker, t.elementType, kind, c, flags+{taHeap}) of tySet: for i in 0..<t.len: result = typeAllowedAux(marker, t[i], kind, c, flags) if result != nil: break of tyObject, tyTuple: if kind in {skProc, skFunc, skConst} and - t.kind == tyObject and t[0] != nil and taIsDefaultField notin flags: + t.kind == tyObject and t.baseClass != nil and taIsDefaultField notin flags: result = t else: let flags = flags+{taField} @@ -200,7 +200,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, result = nil of tyOwned: if t.len == 1 and t[0].skipTypes(abstractInst).kind in {tyRef, tyPtr, tyProc}: - result = typeAllowedAux(marker, t.lastSon, kind, c, flags+{taHeap}) + result = typeAllowedAux(marker, t.skipModifier, kind, c, flags+{taHeap}) else: result = t of tyConcept: @@ -247,10 +247,10 @@ proc classifyViewTypeAux(marker: var IntSet, t: PType): ViewTypeKind = result = immutableView of tyGenericInst, tyDistinct, tyAlias, tyInferred, tySink, tyOwned, tyUncheckedArray, tySequence, tyArray, tyRef, tyStatic: - result = classifyViewTypeAux(marker, lastSon(t)) + result = classifyViewTypeAux(marker, skipModifier(t)) of tyFromExpr: if t.len > 0: - result = classifyViewTypeAux(marker, lastSon(t)) + result = classifyViewTypeAux(marker, skipModifier(t)) else: result = noView of tyTuple: @@ -262,8 +262,8 @@ proc classifyViewTypeAux(marker: var IntSet, t: PType): ViewTypeKind = result = noView if t.n != nil: result = classifyViewTypeNode(marker, t.n) - if t[0] != nil: - result.combine classifyViewTypeAux(marker, t[0]) + if t.baseClass != nil: + result.combine classifyViewTypeAux(marker, t.baseClass) else: # it doesn't matter what these types contain, 'ptr openArray' is not a # view type! @@ -281,7 +281,7 @@ proc directViewType*(t: PType): ViewTypeKind = of tyLent, tyOpenArray: result = immutableView of abstractInst-{tyTypeDesc}: - result = directViewType(t.lastSon) + result = directViewType(t.skipModifier) else: result = noView diff --git a/compiler/types.nim b/compiler/types.nim index f10d5aa86..8166db6ae 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -65,9 +65,6 @@ proc addTypeDeclVerboseMaybe*(result: var string, conf: ConfigRef; typ: PType) = template `$`*(typ: PType): string = typeToString(typ) -proc base*(t: PType): PType = - result = t[0] - # ------------------- type iterator: ---------------------------------------- type TTypeIter* = proc (t: PType, closure: RootRef): bool {.nimcall.} # true if iteration should stop @@ -109,7 +106,7 @@ const typedescInst* = abstractInst + {tyTypeDesc, tyOwned, tyUserTypeClass} proc invalidGenericInst*(f: PType): bool = - result = f.kind == tyGenericInst and lastSon(f) == nil + result = f.kind == tyGenericInst and skipModifier(f) == nil proc isPureObject*(typ: PType): bool = var t = typ @@ -184,10 +181,10 @@ proc getProcHeader*(conf: ConfigRef; sym: PSym; prefer: TPreferedDesc = preferNa proc elemType*(t: PType): PType = assert(t != nil) case t.kind - of tyGenericInst, tyDistinct, tyAlias, tySink: result = elemType(lastSon(t)) - of tyArray: result = t[1] + of tyGenericInst, tyDistinct, tyAlias, tySink: result = elemType(skipModifier(t)) + of tyArray: result = t.elementType of tyError: result = t - else: result = t.lastSon + else: result = t.elementType assert(result != nil) proc enumHasHoles*(t: PType): bool = @@ -200,7 +197,7 @@ proc isOrdinalType*(t: PType, allowEnumWithHoles: bool = false): bool = baseKinds = {tyChar, tyInt..tyInt64, tyUInt..tyUInt64, tyBool, tyEnum} parentKinds = {tyRange, tyOrdinal, tyGenericInst, tyAlias, tySink, tyDistinct} result = (t.kind in baseKinds and (not t.enumHasHoles or allowEnumWithHoles)) or - (t.kind in parentKinds and isOrdinalType(t.lastSon, allowEnumWithHoles)) + (t.kind in parentKinds and isOrdinalType(t.skipModifier, allowEnumWithHoles)) proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter, closure: RootRef): bool @@ -229,7 +226,7 @@ proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter, if not containsOrIncl(marker, t.id): case t.kind of tyGenericInst, tyGenericBody, tyAlias, tySink, tyInferred: - result = iterOverTypeAux(marker, lastSon(t), iter, closure) + result = iterOverTypeAux(marker, skipModifier(t), iter, closure) else: for i in 0..<t.len: result = iterOverTypeAux(marker, t[i], iter, closure) @@ -279,7 +276,7 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate, result = searchTypeForAux(t[0].skipTypes(skipPtrs), predicate, marker) if not result: result = searchTypeNodeForAux(t.n, predicate, marker) of tyGenericInst, tyDistinct, tyAlias, tySink: - result = searchTypeForAux(lastSon(t), predicate, marker) + result = searchTypeForAux(skipModifier(t), predicate, marker) of tyArray, tySet, tyTuple: for i in 0..<t.len: result = searchTypeForAux(t[i], predicate, marker) @@ -328,7 +325,7 @@ proc analyseObjectWithTypeFieldAux(t: PType, if result == frNone: if isObjectWithTypeFieldPredicate(t): result = frHeader of tyGenericInst, tyDistinct, tyAlias, tySink: - result = analyseObjectWithTypeFieldAux(lastSon(t), marker) + result = analyseObjectWithTypeFieldAux(skipModifier(t), marker) of tyArray, tyTuple: for i in 0..<t.len: res = analyseObjectWithTypeFieldAux(t[i], marker) @@ -521,7 +518,7 @@ template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) = # TODO: It would be a good idea to kill the special state of a resolved # concept by switching to tyAlias within the instantiated procs. -# Currently, tyAlias is always skipped with lastSon, which means that +# Currently, tyAlias is always skipped with skipModifier, which means that # we can store information about the matched concept in another position. # Then builtInFieldAccess can be modified to properly read the derived # consts and types stored within the concept. @@ -558,10 +555,10 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = of IntegralTypes + {tyFloat..tyFloat128} + {tyString, tyCstring}: result = typeToStr[t.kind] of tyGenericBody: - result = typeToString(t.lastSon) + result = typeToString(t.last) of tyCompositeTypeClass: # avoids showing `A[any]` in `proc fun(a: A)` with `A = object[T]` - result = typeToString(t.lastSon.lastSon) + result = typeToString(t.last.last) else: result = t.sym.name.s if prefer == preferMixed and result != t.sym.name.s: @@ -599,28 +596,29 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result.add(typeToString(t[i], preferGenericArg)) result.add(']') of tyGenericBody: - result = typeToString(t.lastSon) & '[' + result = typeToString(t.last) & '[' for i in 0..<t.len-1: if i > 0: result.add(", ") result.add(typeToString(t[i], preferTypeName)) result.add(']') of tyTypeDesc: - if t[0].kind == tyNone: result = "typedesc" - else: result = "typedesc[" & typeToString(t[0]) & "]" + if t.elementType.kind == tyNone: result = "typedesc" + else: result = "typedesc[" & typeToString(t.elementType) & "]" of tyStatic: if prefer == preferGenericArg and t.n != nil: result = t.n.renderTree else: - result = "static[" & (if t.len > 0: typeToString(t[0]) else: "") & "]" + result = "static[" & (if t.len > 0: typeToString(t.skipModifier) else: "") & "]" if t.n != nil: result.add "(" & renderTree(t.n) & ")" of tyUserTypeClass: if t.sym != nil and t.sym.owner != nil: - if t.isResolvedUserTypeClass: return typeToString(t.lastSon) + if t.isResolvedUserTypeClass: return typeToString(t.last) return t.sym.owner.name.s else: result = "<invalid tyUserTypeClass>" of tyBuiltInTypeClass: - result = case t.base.kind + result = + case t.base.kind of tyVar: "var" of tyRef: "ref" of tyPtr: "ptr" @@ -656,7 +654,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = if i < t.len - 1: result.add(" or ") of tyNot: - result = "not " & typeToString(t[0]) + result = "not " & typeToString(t.elementType) of tyUntyped: #internalAssert t.len == 0 result = "untyped" @@ -668,43 +666,43 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = of tyArray: result = "array" if t.len > 0: - if t[0].kind == tyRange: - result &= "[" & rangeToStr(t[0].n) & ", " & - typeToString(t[1]) & ']' + if t.indexType.kind == tyRange: + result &= "[" & rangeToStr(t.indexType.n) & ", " & + typeToString(t.elementType) & ']' else: - result &= "[" & typeToString(t[0]) & ", " & - typeToString(t[1]) & ']' + result &= "[" & typeToString(t.indexType) & ", " & + typeToString(t.elementType) & ']' of tyUncheckedArray: result = "UncheckedArray" if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' + result &= "[" & typeToString(t.elementType) & ']' of tySequence: if t.sym != nil and prefer != preferResolved: result = t.sym.name.s else: result = "seq" if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' + result &= "[" & typeToString(t.elementType) & ']' of tyOrdinal: result = "ordinal" if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' + result &= "[" & typeToString(t.skipModifier) & ']' of tySet: result = "set" if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' + result &= "[" & typeToString(t.elementType) & ']' of tyOpenArray: result = "openArray" if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' + result &= "[" & typeToString(t.elementType) & ']' of tyDistinct: - result = "distinct " & typeToString(t[0], + result = "distinct " & typeToString(t.elementType, if prefer == preferModuleInfo: preferModuleInfo else: preferTypeName) of tyIterable: # xxx factor this pattern result = "iterable" if t.len > 0: - result &= "[" & typeToString(t[0]) & ']' + result &= "[" & typeToString(t.skipModifier) & ']' of tyTuple: # we iterate over t.sons here, because t.n may be nil if t.n != nil: @@ -734,13 +732,13 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = if i < t.len - 1: result.add(", ") result.add ']' else: - result.add typeToString(t[0]) + result.add typeToString(t.elementType) of tyRange: result = "range " if t.n != nil and t.n.kind == nkRange: result.add rangeToStr(t.n) if prefer != preferExported: - result.add("(" & typeToString(t[0]) & ")") + result.add("(" & typeToString(t.elementType) & ")") of tyProc: result = if tfIterator in t.flags: "iterator " elif t.owner != nil: @@ -760,7 +758,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result.add(typeToString(t[i])) if i < t.len - 1: result.add(", ") result.add(')') - if t.len > 0 and t[0] != nil: result.add(": " & typeToString(t[0])) + if t.len > 0 and t.returnType != nil: result.add(": " & typeToString(t.returnType)) var prag = if t.callConv == ccNimCall and tfExplicitCallConv notin t.flags: "" else: $t.callConv if not isNil(t.owner) and not isNil(t.owner.ast) and (t.owner.ast.len - 1) >= pragmasPos: let pragmasNode = t.owner.ast[pragmasPos] @@ -778,11 +776,11 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = prag.add("gcsafe") if prag.len != 0: result.add("{." & prag & ".}") of tyVarargs: - result = typeToStr[t.kind] % typeToString(t[0]) + result = typeToStr[t.kind] % typeToString(t.elementType) of tySink: - result = "sink " & typeToString(t[0]) + result = "sink " & typeToString(t.skipModifier) of tyOwned: - result = "owned " & typeToString(t[0]) + result = "owned " & typeToString(t.elementType) else: result = typeToStr[t.kind] result.addTypeFlags(t) @@ -792,8 +790,8 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 = case t.kind of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: result = Zero - of tySet, tyVar: result = firstOrd(conf, t[0]) - of tyArray: result = firstOrd(conf, t[0]) + of tySet, tyVar: result = firstOrd(conf, t.elementType) + of tyArray: result = firstOrd(conf, t.indexType) of tyRange: assert(t.n != nil) # range directly given: assert(t.n.kind == nkRange) @@ -815,8 +813,8 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 = of tyUInt..tyUInt64: result = Zero of tyEnum: # if basetype <> nil then return firstOrd of basetype - if t.len > 0 and t[0] != nil: - result = firstOrd(conf, t[0]) + if t.len > 0 and t.baseClass != nil: + result = firstOrd(conf, t.baseClass) else: if t.n.len > 0: assert(t.n[0].kind == nkSym) @@ -824,10 +822,12 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 = else: result = Zero of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink, - tyStatic, tyInferred, tyUserTypeClasses, tyLent: - result = firstOrd(conf, lastSon(t)) + tyStatic, tyInferred, tyLent: + result = firstOrd(conf, skipModifier(t)) + of tyUserTypeClasses: + result = firstOrd(conf, last(t)) of tyOrdinal: - if t.len > 0: result = firstOrd(conf, lastSon(t)) + if t.len > 0: result = firstOrd(conf, skipModifier(t)) else: result = Zero internalError(conf, "invalid kind for firstOrd(" & $t.kind & ')') @@ -844,10 +844,12 @@ proc firstFloat*(t: PType): BiggestFloat = assert(t.n != nil) # range directly given: assert(t.n.kind == nkRange) getFloatValue(t.n[0]) - of tyVar: firstFloat(t[0]) + of tyVar: firstFloat(t.elementType) of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink, - tyStatic, tyInferred, tyUserTypeClasses: - firstFloat(lastSon(t)) + tyStatic, tyInferred: + firstFloat(skipModifier(t)) + of tyUserTypeClasses: + firstFloat(last(t)) else: internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')') NaN @@ -915,11 +917,13 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 = else: result = Zero of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink, - tyStatic, tyInferred, tyUserTypeClasses, tyLent: - result = lastOrd(conf, lastSon(t)) + tyStatic, tyInferred, tyLent: + result = lastOrd(conf, skipModifier(t)) + of tyUserTypeClasses: + result = lastOrd(conf, last(t)) of tyProxy: result = Zero of tyOrdinal: - if t.len > 0: result = lastOrd(conf, lastSon(t)) + if t.len > 0: result = lastOrd(conf, skipModifier(t)) else: result = Zero internalError(conf, "invalid kind for lastOrd(" & $t.kind & ')') @@ -932,14 +936,16 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 = proc lastFloat*(t: PType): BiggestFloat = case t.kind of tyFloat..tyFloat128: Inf - of tyVar: lastFloat(t[0]) + of tyVar: lastFloat(t.elementType) of tyRange: assert(t.n != nil) # range directly given: assert(t.n.kind == nkRange) getFloatValue(t.n[1]) of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink, - tyStatic, tyInferred, tyUserTypeClasses: - lastFloat(lastSon(t)) + tyStatic, tyInferred: + lastFloat(skipModifier(t)) + of tyUserTypeClasses: + lastFloat(last(t)) else: internalError(newPartialConfigRef(), "invalid kind for lastFloat(" & $t.kind & ')') NaN @@ -953,17 +959,19 @@ proc floatRangeCheck*(x: BiggestFloat, t: PType): bool = of tyRange: x in firstFloat(t)..lastFloat(t) of tyVar: - floatRangeCheck(x, t[0]) + floatRangeCheck(x, t.elementType) of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink, - tyStatic, tyInferred, tyUserTypeClasses: - floatRangeCheck(x, lastSon(t)) + tyStatic, tyInferred: + floatRangeCheck(x, skipModifier(t)) + of tyUserTypeClasses: + floatRangeCheck(x, last(t)) else: internalError(newPartialConfigRef(), "invalid kind for floatRangeCheck:" & $t.kind) false proc lengthOrd*(conf: ConfigRef; t: PType): Int128 = if t.skipTypes(tyUserTypeClasses).kind == tyDistinct: - result = lengthOrd(conf, t[0]) + result = lengthOrd(conf, t.skipModifier) else: let last = lastOrd(conf, t) let first = firstOrd(conf, t) @@ -1191,17 +1199,17 @@ proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool = if not result: return proc isGenericAlias*(t: PType): bool = - return t.kind == tyGenericInst and t.lastSon.kind == tyGenericInst + return t.kind == tyGenericInst and t.skipModifier.kind == tyGenericInst proc genericAliasDepth*(t: PType): int = result = 0 var it = t while it.isGenericAlias: - it = it.lastSon + it = it.skipModifier inc result proc skipGenericAlias*(t: PType): PType = - return if t.isGenericAlias: t.lastSon else: t + return if t.isGenericAlias: t.skipModifier else: t proc sameFlags*(a, b: PType): bool {.inline.} = result = eqTypeFlags*a.flags == eqTypeFlags*b.flags @@ -1222,10 +1230,10 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = if x == y: return true var a = skipTypes(x, {tyAlias}) while a.kind == tyUserTypeClass and tfResolved in a.flags: - a = skipTypes(a[^1], {tyAlias}) + a = skipTypes(a.last, {tyAlias}) var b = skipTypes(y, {tyAlias}) while b.kind == tyUserTypeClass and tfResolved in b.flags: - b = skipTypes(b[^1], {tyAlias}) + b = skipTypes(b.last, {tyAlias}) assert(a != nil) assert(b != nil) if a.kind != b.kind: @@ -1273,7 +1281,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = result = exprStructuralEquivalent(a.n, b.n) and sameFlags(a, b) if result and a.len == b.len and a.len == 1: cycleCheck() - result = sameTypeAux(a[0], b[0], c) + result = sameTypeAux(a.skipModifier, b.skipModifier, c) of tyObject: ifFastObjectTypeCheckFailed(a, b): cycleCheck() @@ -1283,9 +1291,9 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = if c.cmp == dcEq: if sameFlags(a, b): ifFastObjectTypeCheckFailed(a, b): - result = sameTypeAux(a[0], b[0], c) + result = sameTypeAux(a.elementType, b.elementType, c) else: - result = sameTypeAux(a[0], b[0], c) and sameFlags(a, b) + result = sameTypeAux(a.elementType, b.elementType, c) and sameFlags(a, b) of tyEnum, tyForward: # XXX generic enums do not make much sense, but require structural checking result = a.id == b.id and sameFlags(a, b) @@ -1334,12 +1342,12 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = ((ExactConstraints notin c.flags) or sameConstraints(a.n, b.n)) of tyRange: cycleCheck() - result = sameTypeOrNilAux(a[0], b[0], c) and + result = sameTypeOrNilAux(a.elementType, b.elementType, c) and sameValue(a.n[0], b.n[0]) and sameValue(a.n[1], b.n[1]) of tyGenericInst, tyAlias, tyInferred, tyIterable: cycleCheck() - result = sameTypeAux(a.lastSon, b.lastSon, c) + result = sameTypeAux(a.skipModifier, b.skipModifier, c) of tyNone: result = false of tyConcept: result = exprStructuralEquivalent(a.n, b.n) @@ -1374,14 +1382,14 @@ proc inheritanceDiff*(a, b: PType): int = while x != nil: x = skipTypes(x, skipPtrs) if sameObjectTypes(x, b): return - x = x[0] + x = x.baseClass dec(result) var y = b result = 0 while y != nil: y = skipTypes(y, skipPtrs) if sameObjectTypes(y, a): return - y = y[0] + y = y.baseClass inc(result) result = high(int) @@ -1399,7 +1407,7 @@ proc commonSuperclass*(a, b: PType): PType = while x != nil: x = skipTypes(x, skipPtrs) ancestors.incl(x.id) - x = x[0] + x = x.baseClass var y = b while y != nil: var t = y # bug #7818, save type before skip @@ -1408,7 +1416,7 @@ proc commonSuperclass*(a, b: PType): PType = # bug #7818, defer the previous skipTypes if t.kind != tyGenericInst: t = y return t - y = y[0] + y = y.baseClass proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]], last: TTypeKind): bool = @@ -1429,7 +1437,7 @@ proc computeSize*(conf: ConfigRef; typ: PType): BiggestInt = proc getReturnType*(s: PSym): PType = # Obtains the return type of a iterator/proc/macro/template assert s.kind in skProcKinds - result = s.typ[0] + result = s.typ.returnType proc getAlign*(conf: ConfigRef; typ: PType): BiggestInt = computeSizeAlign(conf, typ) @@ -1457,7 +1465,7 @@ proc containsGenericType*(t: PType): bool = proc baseOfDistinct*(t: PType; g: ModuleGraph; idgen: IdGenerator): PType = if t.kind == tyDistinct: - result = t[0] + result = t.elementType else: result = copyType(t, idgen, t.owner) copyTypeProps(g, idgen.module, result, t) @@ -1465,7 +1473,7 @@ proc baseOfDistinct*(t: PType; g: ModuleGraph; idgen: IdGenerator): PType = var it = result while it.kind in {tyPtr, tyRef, tyOwned}: parent = it - it = it.lastSon + it = it.elementType if it.kind == tyDistinct and parent != nil: parent[0] = it[0] @@ -1580,7 +1588,7 @@ proc safeSkipTypes*(t: PType, kinds: TTypeKinds): PType = result = t var seen = initIntSet() while result.kind in kinds and not containsOrIncl(seen, result.id): - result = lastSon(result) + result = skipModifier(result) type OrdinalType* = enum @@ -1629,10 +1637,9 @@ proc skipConvTakeType*(n: PNode): PNode = proc isEmptyContainer*(t: PType): bool = case t.kind of tyUntyped, tyNil: result = true - of tyArray: result = t[1].kind == tyEmpty - of tySet, tySequence, tyOpenArray, tyVarargs: - result = t[0].kind == tyEmpty - of tyGenericInst, tyAlias, tySink: result = isEmptyContainer(t.lastSon) + of tyArray, tySet, tySequence, tyOpenArray, tyVarargs: + result = t.elementType.kind == tyEmpty + of tyGenericInst, tyAlias, tySink: result = isEmptyContainer(t.skipModifier) else: result = false proc takeType*(formal, arg: PType; g: ModuleGraph; idgen: IdGenerator): PType = @@ -1784,9 +1791,11 @@ proc isTupleRecursive(t: PType, cycleDetector: var IntSet): bool = cycleDetectorCopy = cycleDetector if isTupleRecursive(t[i], cycleDetectorCopy): return true - of tyAlias, tyRef, tyPtr, tyGenericInst, tyVar, tyLent, tySink, + of tyRef, tyPtr, tyVar, tyLent, tySink, tyArray, tyUncheckedArray, tySequence, tyDistinct: - return isTupleRecursive(t.lastSon, cycleDetector) + return isTupleRecursive(t.elementType, cycleDetector) + of tyAlias, tyGenericInst: + return isTupleRecursive(t.skipModifier, cycleDetector) else: return false @@ -1812,8 +1821,8 @@ proc isDefectException*(t: PType): bool = sfSystemModule in t.sym.owner.flags and t.sym.name.s == "Defect": return true - if t[0] == nil: break - t = skipTypes(t[0], abstractPtrs) + if t.baseClass == nil: break + t = skipTypes(t.baseClass, abstractPtrs) return false proc isDefectOrCatchableError*(t: PType): bool = @@ -1824,8 +1833,8 @@ proc isDefectOrCatchableError*(t: PType): bool = (t.sym.name.s == "Defect" or t.sym.name.s == "CatchableError"): return true - if t[0] == nil: break - t = skipTypes(t[0], abstractPtrs) + if t.baseClass == nil: break + t = skipTypes(t.baseClass, abstractPtrs) return false proc isSinkTypeForParam*(t: PType): bool = @@ -1847,19 +1856,19 @@ proc lookupFieldAgain*(ty: PType; field: PSym): PSym = assert(ty.kind in {tyTuple, tyObject}) result = lookupInRecord(ty.n, field.name) if result != nil: break - ty = ty[0] + ty = ty.baseClass if result == nil: result = field proc isCharArrayPtr*(t: PType; allowPointerToChar: bool): bool = let t = t.skipTypes(abstractInst) if t.kind == tyPtr: - let pointsTo = t[0].skipTypes(abstractInst) + let pointsTo = t.elementType.skipTypes(abstractInst) case pointsTo.kind of tyUncheckedArray: - result = pointsTo[0].kind == tyChar + result = pointsTo.elementType.kind == tyChar of tyArray: - result = pointsTo[1].kind == tyChar and firstOrd(nil, pointsTo[0]) == 0 and - skipTypes(pointsTo[0], {tyRange}).kind in {tyInt..tyInt64} + result = pointsTo.elementType.kind == tyChar and firstOrd(nil, pointsTo.indexType) == 0 and + skipTypes(pointsTo.indexType, {tyRange}).kind in {tyInt..tyInt64} of tyChar: result = allowPointerToChar else: diff --git a/compiler/vm.nim b/compiler/vm.nim index 8824eca37..1584b2893 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -527,7 +527,7 @@ template maybeHandlePtr(node2: PNode, reg: TFullReg, isAssign2: bool): bool = if nfIsPtr in node.flags or (typ != nil and typ.kind == tyPtr): assert node.kind == nkIntLit, $(node.kind) assert typ != nil - let typ2 = if typ.kind == tyPtr: typ[0] else: typ + let typ2 = if typ.kind == tyPtr: typ.elementType else: typ if not derefPtrToReg(node.intVal, typ2, reg, isAssign = isAssign2): # tyObject not supported in this context stackTrace(c, tos, pc, "deref unsupported ptr type: " & $(typeToString(typ), typ.kind)) @@ -1410,8 +1410,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = #echo "new pc ", newPc, " calling: ", prc.name.s var newFrame = PStackFrame(prc: prc, comesFrom: pc, next: tos) newSeq(newFrame.slots, prc.offset+ord(isClosure)) - if not isEmptyType(prc.typ[0]): - putIntoReg(newFrame.slots[0], getNullValue(prc.typ[0], prc.info, c.config)) + if not isEmptyType(prc.typ.returnType): + putIntoReg(newFrame.slots[0], getNullValue(prc.typ.returnType, prc.info, c.config)) for i in 1..rc-1: newFrame.slots[i] = regs[rb+i] if isClosure: @@ -1556,7 +1556,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[ra].node.typ = typ newSeq(regs[ra].node.sons, count) for i in 0..<count: - regs[ra].node[i] = getNullValue(typ[0], c.debug[pc], c.config) + regs[ra].node[i] = getNullValue(typ.elementType, c.debug[pc], c.config) of opcNewStr: decodeB(rkNode) regs[ra].node = newNodeI(nkStrLit, c.debug[pc]) @@ -1618,7 +1618,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = node2.flags.incl nfIsPtr regs[ra].node = node2 elif not derefPtrToReg(node.intVal, typ, regs[ra], isAssign = false): - stackTrace(c, tos, pc, "opcLdDeref unsupported type: " & $(typeToString(typ), typ[0].kind)) + stackTrace(c, tos, pc, "opcLdDeref unsupported type: " & $(typeToString(typ), typ.elementType.kind)) of opcLdGlobalAddrDerefFFI: let rb = instr.regBx - wordExcess - 1 let node = c.globals[rb] @@ -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[0] + while typ.kind == tyTypeDesc and typ.len > 0: typ = typ.skipModifier createStr regs[ra] regs[ra].node.strVal = typ.typeToString(preferExported) @@ -2293,8 +2293,8 @@ proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode = newSeq(tos.slots, maxSlots) # setup parameters: - if not isEmptyType(sym.typ[0]) or sym.kind == skMacro: - putIntoReg(tos.slots[0], getNullValue(sym.typ[0], sym.info, c.config)) + 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]) diff --git a/compiler/vmconv.nim b/compiler/vmconv.nim index 394fb838b..45d925df0 100644 --- a/compiler/vmconv.nim +++ b/compiler/vmconv.nim @@ -1,4 +1,5 @@ -import ast, idents, lineinfos, astalgo +import ast except elementType +import idents, lineinfos, astalgo import vmdef import std/times diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index ed3ca68ac..d85caa281 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -134,32 +134,32 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; of tyGenericInst: if inst: if allowRecursion: - result = mapTypeToAstR(t.lastSon, info) + result = mapTypeToAstR(t.skipModifier, info) # keep original type info for getType calls on the output node: result.typ = t else: result = newNodeX(nkBracketExpr) - #result.add mapTypeToAst(t.lastSon, info) + #result.add mapTypeToAst(t.last, info) result.add mapTypeToAst(t[0], info) for i in 1..<t.len-1: result.add mapTypeToAst(t[i], info) else: - result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion) + result = mapTypeToAstX(cache, t.skipModifier, info, idgen, inst, allowRecursion) # keep original type info for getType calls on the output node: result.typ = t of tyGenericBody: if inst: - result = mapTypeToAstR(t.lastSon, info) + result = mapTypeToAstR(t.typeBodyImpl, info) else: - result = mapTypeToAst(t.lastSon, info) + result = mapTypeToAst(t.typeBodyImpl, info) of tyAlias: - result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion) + result = mapTypeToAstX(cache, t.skipModifier, info, idgen, inst, allowRecursion) of tyOrdinal: - result = mapTypeToAst(t.lastSon, info) + result = mapTypeToAst(t.skipModifier, info) of tyDistinct: if inst: result = newNodeX(nkDistinctTy) - result.add mapTypeToAst(t[0], info) + result.add mapTypeToAst(t.skipModifier, info) else: if allowRecursion or t.sym == nil: result = mapTypeToBracket("distinct", mDistinct, t, info) @@ -188,10 +188,10 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; if allowRecursion or t.sym == nil: result = newNodeIT(nkObjectTy, if t.n.isNil: info else: t.n.info, t) result.add newNodeI(nkEmpty, info) - if t[0] == nil: + if t.baseClass == nil: result.add newNodeI(nkEmpty, info) else: - result.add mapTypeToAst(t[0], info) + result.add mapTypeToAst(t.baseClass, info) result.add copyTree(t.n) else: result = atomicType(t.sym) @@ -287,7 +287,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; result = mapTypeToBracket("builtinTypeClass", mNone, t, info) of tyUserTypeClass, tyUserTypeClassInst: if t.isResolvedUserTypeClass: - result = mapTypeToAst(t.lastSon, info) + result = mapTypeToAst(t.last, info) else: result = mapTypeToBracket("concept", mNone, t, info) result.add t.n.copyTree @@ -298,7 +298,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; of tyNot: result = mapTypeToBracket("not", mNot, t, info) of tyIterable: result = mapTypeToBracket("iterable", mIterableType, t, info) of tyAnything: result = atomicType("anything", mNone) - of tyInferred: result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion) + of tyInferred: result = mapTypeToAstX(cache, t.skipModifier, info, idgen, inst, allowRecursion) of tyStatic, tyFromExpr: if inst: if t.n != nil: result = t.n.copyTree diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 53b2974ba..7ef231f57 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1874,8 +1874,8 @@ 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[0] != nil: - let b = skipTypes(t[0], skipPtrs) + if t != nil and t.len > 0 and t.baseClass != nil: + let b = skipTypes(t.baseClass, skipPtrs) getNullValueAux(b, b.n, result, conf, currPosition) case obj.kind of nkRecList: diff --git a/compiler/vmmarshal.nim b/compiler/vmmarshal.nim index 8ce113369..d80010877 100644 --- a/compiler/vmmarshal.nim +++ b/compiler/vmmarshal.nim @@ -98,17 +98,17 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet; if i > 0: s.add(", ") if a[i].kind == nkRange: var x = copyNode(a[i][0]) - storeAny(s, t.lastSon, x, stored, conf) + storeAny(s, t.elementType, x, stored, conf) inc x.intVal while x.intVal <= a[i][1].intVal: s.add(", ") - storeAny(s, t.lastSon, x, stored, conf) + storeAny(s, t.elementType, x, stored, conf) inc x.intVal else: - storeAny(s, t.lastSon, a[i], stored, conf) + storeAny(s, t.elementType, a[i], stored, conf) s.add("]") of tyRange, tyGenericInst, tyAlias, tySink: - storeAny(s, t.lastSon, a, stored, conf) + storeAny(s, t.skipModifier, a, stored, conf) of tyEnum: # we need a slow linear search because of enums with holes: for e in items(t.n): @@ -127,7 +127,7 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet; s.add("[") s.add($x.ptrToInt) s.add(", ") - storeAny(s, t.lastSon, a, stored, conf) + storeAny(s, t.elementType, a, stored, conf) s.add("]") of tyString, tyCstring: if a.kind == nkNilLit: s.add("null") @@ -245,7 +245,7 @@ proc loadAny(p: var JsonParser, t: PType, next(p) result = newNode(nkCurly) while p.kind != jsonArrayEnd and p.kind != jsonEof: - result.add loadAny(p, t.lastSon, tab, cache, conf, idgen) + result.add loadAny(p, t.elementType, tab, cache, conf, idgen) if p.kind == jsonArrayEnd: next(p) else: raiseParseErr(p, "']' end of array expected") of tyPtr, tyRef: @@ -264,7 +264,7 @@ proc loadAny(p: var JsonParser, t: PType, if p.kind == jsonInt: let idx = p.getInt next(p) - result = loadAny(p, t.lastSon, tab, cache, conf, idgen) + result = loadAny(p, t.elementType, tab, cache, conf, idgen) tab[idx] = result else: raiseParseErr(p, "index for ref type expected") if p.kind == jsonArrayEnd: next(p) @@ -300,7 +300,7 @@ proc loadAny(p: var JsonParser, t: PType, result = nil raiseParseErr(p, "float expected") of tyRange, tyGenericInst, tyAlias, tySink: - result = loadAny(p, t.lastSon, tab, cache, conf, idgen) + result = loadAny(p, t.skipModifier, tab, cache, conf, idgen) else: result = nil internalError conf, "cannot marshal at compile-time " & t.typeToString diff --git a/compiler/vtables.nim b/compiler/vtables.nim index f57b59eae..eeacc7b47 100644 --- a/compiler/vtables.nim +++ b/compiler/vtables.nim @@ -91,7 +91,7 @@ proc collectVTableDispatchers*(g: ModuleGraph) = if relevantCol(g.methods[bucket].methods, 1): incl(relevantCols, 1) sortBucket(g.methods[bucket].methods, relevantCols) let base = g.methods[bucket].methods[^1] - let baseType = base.typ[1].skipTypes(skipPtrs-{tyTypeDesc}) + let baseType = base.typ.firstParamType.skipTypes(skipPtrs-{tyTypeDesc}) if baseType.itemId in g.objectTree and not containGenerics(baseType, g.objectTree[baseType.itemId]): let methodIndexLen = g.bucketTable[baseType.itemId] if baseType.itemId notin itemTable: # once is enough @@ -114,7 +114,7 @@ proc collectVTableDispatchers*(g: ModuleGraph) = mIndex = rootItemIdCount[baseType.itemId] rootItemIdCount.inc(baseType.itemId) for idx in 0..<g.methods[bucket].methods.len: - let obj = g.methods[bucket].methods[idx].typ[1].skipTypes(skipPtrs) + let obj = g.methods[bucket].methods[idx].typ.firstParamType.skipTypes(skipPtrs) itemTable[obj.itemId][mIndex] = LazySym(sym: g.methods[bucket].methods[idx]) g.addDispatchers genVTableDispatcher(g, g.methods[bucket].methods, mIndex) else: # if the base object doesn't have this method @@ -129,7 +129,7 @@ proc sortVTableDispatchers*(g: ModuleGraph) = if relevantCol(g.methods[bucket].methods, 1): incl(relevantCols, 1) sortBucket(g.methods[bucket].methods, relevantCols) let base = g.methods[bucket].methods[^1] - let baseType = base.typ[1].skipTypes(skipPtrs-{tyTypeDesc}) + let baseType = base.typ.firstParamType.skipTypes(skipPtrs-{tyTypeDesc}) if baseType.itemId in g.objectTree and not containGenerics(baseType, g.objectTree[baseType.itemId]): let methodIndexLen = g.bucketTable[baseType.itemId] if baseType.itemId notin itemTable: # once is enough @@ -152,7 +152,7 @@ proc sortVTableDispatchers*(g: ModuleGraph) = mIndex = rootItemIdCount[baseType.itemId] rootItemIdCount.inc(baseType.itemId) for idx in 0..<g.methods[bucket].methods.len: - let obj = g.methods[bucket].methods[idx].typ[1].skipTypes(skipPtrs) + let obj = g.methods[bucket].methods[idx].typ.firstParamType.skipTypes(skipPtrs) itemTable[obj.itemId][mIndex] = LazySym(sym: g.methods[bucket].methods[idx]) for baseType in rootTypeSeq: |