From 6ed33b6d61518c8de94b07c7ffb68fcc6f839897 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 14 Dec 2023 16:25:34 +0100 Subject: [PATCH] type graph refactor; part 3 (#23064) --- compiler/ast.nim | 82 +++++++++-- compiler/astalgo.nim | 69 ++++----- compiler/docgen.nim | 3 +- compiler/expanddefaults.nim | 2 +- compiler/ic/ic.nim | 2 +- compiler/isolation_check.nim | 16 +- compiler/semdata.nim | 2 +- compiler/sempass2.nim | 2 +- compiler/semstmts.nim | 12 +- compiler/semtypes.nim | 2 +- compiler/sigmatch.nim | 30 ++-- compiler/sizealignoffsetimpl.nim | 11 +- compiler/typeallowed.nim | 27 ++-- compiler/types.nim | 246 ++++++++++++------------------- compiler/varpartitions.nim | 3 +- compiler/vmdeps.nim | 2 +- tests/typerel/tregionptrs.nim | 16 -- 17 files changed, 257 insertions(+), 270 deletions(-) delete mode 100644 tests/typerel/tregionptrs.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index ab46a02d6e707..c880cb65178b5 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1199,9 +1199,6 @@ proc discardSons*(father: PNode) proc len*(n: PNode): int {.inline.} = result = n.sons.len -proc len*(n: PType): int {.inline.} = - result = n.sons.len - proc safeLen*(n: PNode): int {.inline.} = ## works even for leaves. if n.kind in {nkNone..nkNilLit}: result = 0 @@ -1576,11 +1573,74 @@ proc `$`*(s: PSym): string = else: result = "" -iterator items*(t: PType): PType = +when false: + iterator items*(t: PType): PType = + for i in 0.. 0 + +proc hasElementType*(t: PType): bool {.inline.} = t.sons.len > 0 +proc isEmptyTupleType*(t: PType): bool {.inline.} = t.sons.len == 0 +proc isSingletonTupleType*(t: PType): bool {.inline.} = t.sons.len == 1 + +iterator genericInstParams*(t: PType): (bool, PType) = + for i in 1.. 0: - s.add $t.kind - s.add " " - t = t.last - echo s - template debug*(x: PSym|PType|PNode) {.deprecated.} = when compiles(c.config): debug(c.config, x) @@ -337,21 +328,18 @@ proc typeToYamlAux(conf: ConfigRef; n: PType, marker: var IntSet, indent: int, sonsRope = "\"$1 @$2\"" % [rope($n.kind), rope( strutils.toHex(cast[int](n), sizeof(n) * 2))] else: - if n.len > 0: - sonsRope = rope("[") - for i in 0.. 0: sonsRope.add(",") - sonsRope.addf("$N$1$2", [rspaces(indent + 4), typeToYamlAux(conf, n[i], - marker, indent + 4, maxRecDepth - 1)]) - sonsRope.addf("$N$1]", [rspaces(indent + 2)]) - else: - sonsRope = rope("null") + sonsRope = rope("[") + for i, a in n.ikids: + if i > 0: sonsRope.add(",") + sonsRope.addf("$N$1$2", [rspaces(indent + 4), typeToYamlAux(conf, a, + marker, indent + 4, maxRecDepth - 1)]) + sonsRope.addf("$N$1]", [rspaces(indent + 2)]) let istr = rspaces(indent + 2) result = rope("{") result.addf("$N$1\"kind\": $2", [istr, makeYamlString($n.kind)]) result.addf("$N$1\"sym\": $2", [istr, symToYamlAux(conf, n.sym, marker, indent + 2, maxRecDepth - 1)]) - result.addf("$N$1\"n\": $2", [istr, treeToYamlAux(conf, n.n, marker, indent + 2, maxRecDepth - 1)]) + result.addf("$N$1\"n\": $2", [istr, treeToYamlAux(conf, n.n, marker, indent + 2, maxRecDepth - 1)]) if card(n.flags) > 0: result.addf("$N$1\"flags\": $2", [istr, flagsToStr(n.flags)]) result.addf("$N$1\"callconv\": $2", [istr, makeYamlString($n.callConv)]) @@ -573,14 +561,12 @@ proc value(this: var DebugPrinter; value: PType) = this.key "n" this.value value.n - if value.len > 0: - this.key "sons" - this.openBracket - for i in 0.. 0: this.comma + this.value a + this.closeBracket if value.n != nil: this.key "n" @@ -649,30 +635,33 @@ proc value(this: var DebugPrinter; value: PNode) = proc debug(n: PSym; conf: ConfigRef) = - var this: DebugPrinter - this.visited = initTable[pointer, int]() - this.renderSymType = true - this.useColor = not defined(windows) + var this = DebugPrinter( + visited: initTable[pointer, int](), + renderSymType: true, + useColor: not defined(windows) + ) this.value(n) echo($this.res) proc debug(n: PType; conf: ConfigRef) = - var this: DebugPrinter - this.visited = initTable[pointer, int]() - this.renderSymType = true - this.useColor = not defined(windows) + var this = DebugPrinter( + visited: initTable[pointer, int](), + renderSymType: true, + useColor: not defined(windows) + ) this.value(n) echo($this.res) proc debug(n: PNode; conf: ConfigRef) = - var this: DebugPrinter - this.visited = initTable[pointer, int]() - #this.renderSymType = true - this.useColor = not defined(windows) + var this = DebugPrinter( + visited: initTable[pointer, int](), + renderSymType: false, + useColor: not defined(windows) + ) this.value(n) echo($this.res) -proc nextTry(h, maxHash: Hash): Hash = +proc nextTry(h, maxHash: Hash): Hash {.inline.} = result = ((5 * h) + 1) and maxHash # For any initial h in range(maxHash), repeating that maxHash times # generates each int in range(maxHash) exactly once (see any text on diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 29eeced9be67d..b53307ee02f2e 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -1199,8 +1199,7 @@ proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind, nonExports = false): var param = %{"name": %($genericParam)} if genericParam.sym.typ.len > 0: param["types"] = newJArray() - for kind in genericParam.sym.typ: - param["types"].add %($kind) + param["types"].add %($genericParam.sym.typ.elementType) result.json["signature"]["genericParams"].add param if optGenIndex in d.conf.globalOptions: genItem(d, n, nameNode, k, kForceExport) diff --git a/compiler/expanddefaults.nim b/compiler/expanddefaults.nim index 395d31cc8617f..86f87cd8474dc 100644 --- a/compiler/expanddefaults.nim +++ b/compiler/expanddefaults.nim @@ -118,7 +118,7 @@ proc expandDefault(t: PType; info: TLineInfo): PNode = expandDefaultObj(t, info, result) of tyTuple: result = newZero(t, info, nkTupleConstr) - for it in t: + for it in t.kids: result.add expandDefault(it, info) of tyVarargs, tyOpenArray, tySequence, tyUncheckedArray: result = newZero(t, info, nkBracket) diff --git a/compiler/ic/ic.nim b/compiler/ic/ic.nim index 0085ea7485537..a7d3ed81c737b 100644 --- a/compiler/ic/ic.nim +++ b/compiler/ic/ic.nim @@ -370,7 +370,7 @@ proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemI paddingAtEnd: t.paddingAtEnd) storeNode(p, t, n) p.typeInst = t.typeInst.storeType(c, m) - for kid in items t: + for kid in kids t: p.types.add kid.storeType(c, m) c.addMissing t.sym p.sym = t.sym.safeItemId(c, m) diff --git a/compiler/isolation_check.nim b/compiler/isolation_check.nim index 08a2cc6045fbc..17fbde29eeb4e 100644 --- a/compiler/isolation_check.nim +++ b/compiler/isolation_check.nim @@ -54,14 +54,14 @@ proc canAlias(arg, ret: PType; marker: var IntSet): bool = of tyObject: if isFinal(ret): result = canAliasN(arg, ret.n, marker) - if not result and ret.len > 0 and ret[0] != nil: - result = canAlias(arg, ret[0], marker) + if not result and ret.baseClass != nil: + result = canAlias(arg, ret.baseClass, marker) else: result = true of tyTuple: result = false - for i in 0.. maxBranch: maxBranch = branchSum inc result, maxBranch @@ -240,11 +240,16 @@ proc sumGeneric(t: PType): int = t = t.elementType if t.kind == tyEmpty: break inc result - of tyGenericInvocation, tyTuple, tyProc, tyAnd: + of tyGenericInvocation, tyTuple, tyAnd: result += ord(t.kind in {tyGenericInvocation, tyAnd}) - for i in 0..= isGeneric: isGeneric else: x @@ -1660,7 +1665,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, of tyAnd: considerPreviousT: result = isEqual - for branch in f: + for branch in f.kids: let x = typeRel(c, branch, aOrig, flags) if x < isSubtype: return isNone # 'and' implies minimum matching result: @@ -1672,7 +1677,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, result = isNone let oldInheritancePenalty = c.inheritancePenalty var maxInheritance = 0 - for branch in f: + for branch in f.kids: c.inheritancePenalty = 0 let x = typeRel(c, branch, aOrig, flags) maxInheritance = max(maxInheritance, c.inheritancePenalty) @@ -1686,9 +1691,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, c.inheritancePenalty = oldInheritancePenalty + maxInheritance of tyNot: considerPreviousT: - for branch in f: - if typeRel(c, branch, aOrig, flags) != isNone: - return isNone + if typeRel(c, f.elementType, aOrig, flags) != isNone: + return isNone bindingRet isGeneric of tyAnything: @@ -1699,7 +1703,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, return isGeneric of tyBuiltInTypeClass: considerPreviousT: - let target = f[0] + let target = f.genericHead let targetKind = target.kind var effectiveArgType = a.getObjectTypeOrNil() if effectiveArgType == nil: return isNone diff --git a/compiler/sizealignoffsetimpl.nim b/compiler/sizealignoffsetimpl.nim index 7cc11f55f13a9..d114f59da53d6 100644 --- a/compiler/sizealignoffsetimpl.nim +++ b/compiler/sizealignoffsetimpl.nim @@ -332,8 +332,7 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = of tyTuple: try: var accum = OffsetAccum(maxAlign: 1) - for i in 0.. 0: + if typ.hasElementType: 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.last) - typ.size = typ.last.size - typ.align = typ.last.align + computeSizeAlign(conf, typ.skipModifier) + typ.size = typ.skipModifier.size + typ.align = typ.skipModifier.align typ.paddingAtEnd = typ.last.paddingAtEnd of tyTypeClasses: diff --git a/compiler/typeallowed.nim b/compiler/typeallowed.nim index 04dbc69c59a52..d226b2e063db0 100644 --- a/compiler/typeallowed.nim +++ b/compiler/typeallowed.nim @@ -96,9 +96,9 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, # only closure iterators may be assigned to anything. result = t let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags - for i in 1.. 0: + if t.hasElementType: result = classifyViewTypeAux(marker, skipModifier(t)) else: result = noView of tyTuple: result = noView - for i in 0.. 0: + if t.kind == tyGenericParam and t.genericParamHasConstraints: result.add ": " - var first = true - for son in t: - if not first: result.add " or " - result.add son.typeToString - first = false + result.add t.elementType.typeToString else: result = t.sym.owner.name.s & '.' & t.sym.name.s result.addTypeFlags(t) @@ -589,17 +552,23 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = "int" else: result = "int literal(" & $t.n.intVal & ")" - of tyGenericInst, tyGenericInvocation: + of tyGenericInst: result = typeToString(t.genericHead) & '[' - for i in 1.. 1: result.add(", ") - result.add(typeToString(t[i], preferGenericArg)) + for needsComma, a in t.genericInstParams: + if needsComma: result.add(", ") + result.add(typeToString(a, preferGenericArg)) + result.add(']') + of tyGenericInvocation: + result = typeToString(t.genericHead) & '[' + for needsComma, a in t.genericInvocationParams: + if needsComma: result.add(", ") + result.add(typeToString(a, preferGenericArg)) result.add(']') of tyGenericBody: result = typeToString(t.typeBodyImpl) & '[' - for i in 0.. 0: result.add(", ") - result.add(typeToString(t[i], preferTypeName)) + for needsComma, a in t.genericBodyParams: + if needsComma: result.add(", ") + result.add(typeToString(a, preferTypeName)) result.add(']') of tyTypeDesc: if t.elementType.kind == tyNone: result = "typedesc" @@ -608,7 +577,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = if prefer == preferGenericArg and t.n != nil: result = t.n.renderTree else: - result = "static[" & (if t.len > 0: typeToString(t.skipModifier) else: "") & "]" + result = "static[" & (if t.hasElementType: typeToString(t.skipModifier) else: "") & "]" if t.n != nil: result.add "(" & renderTree(t.n) & ")" of tyUserTypeClass: if t.sym != nil and t.sym.owner != nil: @@ -639,20 +608,18 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = of tyUserTypeClassInst: let body = t.base result = body.sym.name.s & "[" - for i in 1.. 1: result.add(", ") - result.add(typeToString(t[i])) + for needsComma, a in t.userTypeClassInstParams: + if needsComma: result.add(", ") + result.add(typeToString(a)) result.add "]" of tyAnd: - for i, son in t: + for i, son in t.ikids: + if i > 0: result.add(" and ") result.add(typeToString(son)) - if i < t.len - 1: - result.add(" and ") of tyOr: - for i, son in t: + for i, son in t.ikids: + if i > 0: result.add(" or ") result.add(typeToString(son)) - if i < t.len - 1: - result.add(" or ") of tyNot: result = "not " & typeToString(t.elementType) of tyUntyped: @@ -665,7 +632,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = "typeof(" & renderTree(t.n) & ")" of tyArray: result = "array" - if t.len > 0: + if t.hasElementType: if t.indexType.kind == tyRange: result &= "[" & rangeToStr(t.indexType.n) & ", " & typeToString(t.elementType) & ']' @@ -674,26 +641,26 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = typeToString(t.elementType) & ']' of tyUncheckedArray: result = "UncheckedArray" - if t.len > 0: + if t.hasElementType: 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: + if t.hasElementType: result &= "[" & typeToString(t.elementType) & ']' of tyOrdinal: result = "ordinal" - if t.len > 0: + if t.hasElementType: result &= "[" & typeToString(t.skipModifier) & ']' of tySet: result = "set" - if t.len > 0: + if t.hasElementType: result &= "[" & typeToString(t.elementType) & ']' of tyOpenArray: result = "openArray" - if t.len > 0: + if t.hasElementType: result &= "[" & typeToString(t.elementType) & ']' of tyDistinct: result = "distinct " & typeToString(t.elementType, @@ -701,38 +668,33 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = of tyIterable: # xxx factor this pattern result = "iterable" - if t.len > 0: + if t.hasElementType: result &= "[" & typeToString(t.skipModifier) & ']' of tyTuple: # we iterate over t.sons here, because t.n may be nil if t.n != nil: result = "tuple[" - assert(t.n.len == t.len) for i in 0.. 0: result.add ", " + result.add(typeToString(son)) result.add(')') of tyPtr, tyRef, tyVar, tyLent: result = if isOutParam(t): "out " else: typeToStr[t.kind] - if t.len >= 2: - setLen(result, result.len-1) - result.add '[' - for i in 0.. FirstParamAt: result.add(", ") + let j = paramTypeToNodeIndex(i) + if t.n != nil and j < t.n.len and t.n[j].kind == nkSym: + result.add(t.n[j].sym.name.s) result.add(": ") - result.add(typeToString(t[i])) - if i < t.len - 1: result.add(", ") + result.add(typeToString(a)) result.add(')') - if t.len > 0 and t.returnType != nil: result.add(": " & typeToString(t.returnType)) + if 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] @@ -813,7 +776,7 @@ 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.baseClass != nil: + if t.baseClass != nil: result = firstOrd(conf, t.baseClass) else: if t.n.len > 0: @@ -827,7 +790,7 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 = of tyUserTypeClasses: result = firstOrd(conf, last(t)) of tyOrdinal: - if t.len > 0: result = firstOrd(conf, skipModifier(t)) + if t.hasElementType: result = firstOrd(conf, skipModifier(t)) else: result = Zero internalError(conf, "invalid kind for firstOrd(" & $t.kind & ')') @@ -923,7 +886,7 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 = result = lastOrd(conf, last(t)) of tyProxy: result = Zero of tyOrdinal: - if t.len > 0: result = lastOrd(conf, skipModifier(t)) + if t.hasElementType: result = lastOrd(conf, skipModifier(t)) else: result = Zero internalError(conf, "invalid kind for lastOrd(" & $t.kind & ')') @@ -1093,11 +1056,11 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = # two tuples are equivalent iff the names, types and positions are the same; # however, both types may not have any field names (t.n may be nil) which # complicates the matter a bit. - if a.len == b.len: + if sameTupleLengths(a, b): result = true - for i in 0..= a.len or a[i] == nil: return false - a = a[i] - result = a.kind == last - include sizealignoffsetimpl @@ -1578,8 +1524,8 @@ proc isCompileTimeOnly*(t: PType): bool {.inline.} = proc containsCompileTimeOnly*(t: PType): bool = if isCompileTimeOnly(t): return true - for i in 0.. but expected 'APtr = ptr[RegionA, int]'" - line: 16 -""" - -type - RegionA = object - APtr = RegionA ptr int - RegionB = object - BPtr = RegionB ptr int - -var x,xx: APtr -var y: BPtr -x = nil -x = xx -x = y