Skip to content

Commit

Permalink
type graph refactor; part 3 (nim-lang#23064)
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq authored Dec 14, 2023
1 parent 1b7b0d6 commit 6ed33b6
Show file tree
Hide file tree
Showing 17 changed files with 257 additions and 270 deletions.
82 changes: 71 additions & 11 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1576,11 +1573,74 @@ proc `$`*(s: PSym): string =
else:
result = "<nil>"

iterator items*(t: PType): PType =
when false:
iterator items*(t: PType): PType =
for i in 0..<t.sons.len: yield t.sons[i]

iterator pairs*(n: PType): tuple[i: int, n: PType] =
for i in 0..<n.sons.len: yield (i, n.sons[i])

when true:
proc len*(n: PType): int {.inline.} =
result = n.sons.len

proc sameTupleLengths*(a, b: PType): bool {.inline.} =
result = a.sons.len == b.sons.len

iterator tupleTypePairs*(a, b: PType): (int, PType, PType) =
for i in 0 ..< a.sons.len:
yield (i, a.sons[i], b.sons[i])

iterator underspecifiedPairs*(a, b: PType; start = 0; without = 0): (PType, PType) =
# XXX Figure out with what typekinds this is called.
for i in start ..< a.sons.len + without:
yield (a.sons[i], b.sons[i])

proc signatureLen*(t: PType): int {.inline.} =
result = t.sons.len

proc kidsLen*(t: PType): int {.inline.} =
result = t.sons.len

proc genericParamHasConstraints*(t: PType): bool {.inline.} = t.sons.len > 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..<t.sons.len-1:
yield (i!=1, t.sons[i])

iterator genericInvocationParams*(t: PType): (bool, PType) =
for i in 1..<t.sons.len:
yield (i!=1, t.sons[i])

iterator genericBodyParams*(t: PType): (bool, PType) =
for i in 0..<t.sons.len-1:
yield (i!=0, t.sons[i])

iterator userTypeClassInstParams*(t: PType): (bool, PType) =
for i in 1..<t.sons.len-1:
yield (i!=1, t.sons[i])

iterator ikids*(t: PType): (int, PType) =
for i in 0..<t.sons.len: yield (i, t.sons[i])

const
FirstParamAt* = 1

iterator paramTypes*(t: PType): (int, PType) =
for i in FirstParamAt..<t.sons.len: yield (i, t.sons[i])

template paramTypeToNodeIndex*(x: int): int = x

iterator kids*(t: PType): PType =
for i in 0..<t.sons.len: yield t.sons[i]

iterator pairs*(n: PType): tuple[i: int, n: PType] =
for i in 0..<n.sons.len: yield (i, n.sons[i])
iterator signature*(t: PType): PType =
# yields return type + parameter types
for i in 0..<t.sons.len: yield t.sons[i]

proc newType*(kind: TTypeKind; idgen: IdGenerator; owner: PSym; son: sink PType = nil): PType =
let id = nextTypeId idgen
Expand Down Expand Up @@ -1624,8 +1684,8 @@ proc assignType*(dest, src: PType) =
mergeLoc(dest.sym.loc, src.sym.loc)
else:
dest.sym = src.sym
newSons(dest, src.len)
for i in 0..<src.len: dest[i] = src[i]
newSons(dest, src.sons.len)
for i in 0..<src.sons.len: dest[i] = src[i]

proc copyType*(t: PType, idgen: IdGenerator, owner: PSym): PType =
result = newType(t.kind, idgen, owner)
Expand Down Expand Up @@ -1705,7 +1765,7 @@ proc skipTypesOrNil*(t: PType, kinds: TTypeKinds): PType =
## same as skipTypes but handles 'nil'
result = t
while result != nil and result.kind in kinds:
if result.len == 0: return nil
if result.sons.len == 0: return nil
result = last(result)

proc isGCedMem*(t: PType): bool {.inline.} =
Expand Down Expand Up @@ -2084,7 +2144,7 @@ proc findUnresolvedStatic*(n: PNode): PNode =
return n
if n.typ != nil and n.typ.kind == tyTypeDesc:
let t = skipTypes(n.typ, {tyTypeDesc})
if t.kind == tyGenericParam and t.len == 0:
if t.kind == tyGenericParam and not t.genericParamHasConstraints:
return n
for son in n:
let n = son.findUnresolvedStatic
Expand Down Expand Up @@ -2145,7 +2205,7 @@ proc newProcType*(info: TLineInfo; idgen: IdGenerator; owner: PSym): PType =
result.n.add newNodeI(nkEffectList, info)

proc addParam*(procType: PType; param: PSym) =
param.position = procType.len-1
param.position = procType.sons.len-1
procType.n.add newSymNode(param)
rawAddSon(procType, param.typ)

Expand Down
69 changes: 29 additions & 40 deletions compiler/astalgo.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,6 @@ proc debug*(n: PSym; conf: ConfigRef = nil) {.exportc: "debugSym", deprecated.}
proc debug*(n: PType; conf: ConfigRef = nil) {.exportc: "debugType", deprecated.}
proc debug*(n: PNode; conf: ConfigRef = nil) {.exportc: "debugNode", deprecated.}

proc typekinds*(t: PType) {.deprecated.} =
var t = t
var s = ""
while t != nil and t.len > 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)
Expand Down Expand Up @@ -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..<n.len:
if i > 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)])
Expand Down Expand Up @@ -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..<value.len:
this.value value[i]
if i != value.len - 1:
this.comma
this.closeBracket
this.key "sons"
this.openBracket
for i, a in value.ikids:
if i > 0: this.comma
this.value a
this.closeBracket

if value.n != nil:
this.key "n"
Expand Down Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions compiler/docgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion compiler/expanddefaults.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion compiler/ic/ic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
16 changes: 9 additions & 7 deletions compiler/isolation_check.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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..<ret.len:
result = canAlias(arg, ret[i], marker)
for r in ret.kids:
result = canAlias(arg, r, marker)
if result: break
of tyArray, tySequence, tyDistinct, tyGenericInst,
tyAlias, tyInferred, tySink, tyLent, tyOwned, tyRef:
Expand Down Expand Up @@ -124,9 +124,11 @@ proc containsDangerousRefAux(t: PType; marker: var IntSet): SearchResult =
if result == NotFound: result = containsDangerousRefAux(t.n, marker)
of tyGenericInst, tyDistinct, tyAlias, tySink:
result = containsDangerousRefAux(skipModifier(t), marker)
of tyArray, tySet, tyTuple, tySequence:
for i in 0..<t.len:
result = containsDangerousRefAux(t[i], marker)
of tyArray, tySet, tySequence:
result = containsDangerousRefAux(t.elementType, marker)
of tyTuple:
for a in t.kids:
result = containsDangerousRefAux(a, marker)
if result == Found: return result
else:
discard
Expand Down
2 changes: 1 addition & 1 deletion compiler/semdata.nim
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ proc makeOrType*(c: PContext, t1, t2: PType): PType =
result = newTypeS(tyOr, c)
template addOr(t1) =
if t1.kind == tyOr:
for x in t1: result.rawAddSon x
for x in t1.kids: result.rawAddSon x
else:
result.rawAddSon t1
addOr(t1)
Expand Down
2 changes: 1 addition & 1 deletion compiler/sempass2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1421,7 +1421,7 @@ proc track(tracked: PEffects, n: PNode) =
proc subtypeRelation(g: ModuleGraph; spec, real: PNode): bool =
if spec.typ.kind == tyOr:
result = false
for t in spec.typ:
for t in spec.typ.kids:
if safeInheritanceDiff(g.excType(real), t) <= 0:
return true
else:
Expand Down
12 changes: 6 additions & 6 deletions compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ proc hasEmpty(typ: PType): bool =
result = typ.elementType.kind == tyEmpty
elif typ.kind == tyTuple:
result = false
for s in typ:
for s in typ.kids:
result = result or hasEmpty(s)
else:
result = false
Expand Down Expand Up @@ -1362,7 +1362,7 @@ proc checkCovariantParamsUsages(c: PContext; genericType: PType) =
of tyArray:
return traverseSubTypes(c, t.elementType)
of tyProc:
for subType in t:
for subType in t.signature:
if subType != nil:
subresult traverseSubTypes(c, subType)
if result:
Expand Down Expand Up @@ -1395,11 +1395,11 @@ proc checkCovariantParamsUsages(c: PContext; genericType: PType) =
of tyUserTypeClass, tyUserTypeClassInst:
error("non-invariant type parameters are not supported in concepts")
of tyTuple:
for fieldType in t:
for fieldType in t.kids:
subresult traverseSubTypes(c, fieldType)
of tyPtr, tyRef, tyVar, tyLent:
if t.base.kind == tyGenericParam: return true
return traverseSubTypes(c, t.base)
if t.elementType.kind == tyGenericParam: return true
return traverseSubTypes(c, t.elementType)
of tyDistinct, tyAlias, tySink, tyOwned:
return traverseSubTypes(c, t.skipModifier)
of tyGenericInst:
Expand Down Expand Up @@ -2086,7 +2086,7 @@ proc semCppMember(c: PContext; s: PSym; n: PNode) =
if c.config.backend == backendCpp:
if s.typ.len < 2 and not isCtor:
localError(c.config, n.info, pragmaName & " must have at least one parameter")
for son in s.typ:
for son in s.typ.signature:
if son!=nil and son.isMetaType:
localError(c.config, n.info, pragmaName & " unsupported for generic routine")
var typ: PType
Expand Down
2 changes: 1 addition & 1 deletion compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ proc findEnforcedStaticType(t: PType): PType =
if t == nil: return nil
if t.kind == tyStatic: return t
if t.kind == tyAnd:
for s in t:
for s in t.kids:
let t = findEnforcedStaticType(s)
if t != nil: return t

Expand Down
Loading

0 comments on commit 6ed33b6

Please sign in to comment.