mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
type graph refactor; part 3 (#23064)
This commit is contained in:
@@ -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 = "<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
|
||||
@@ -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)
|
||||
@@ -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.} =
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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)])
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ proc sumGeneric(t: PType): int =
|
||||
inc result
|
||||
of tyOr:
|
||||
var maxBranch = 0
|
||||
for branch in t:
|
||||
for branch in t.kids:
|
||||
let branchSum = sumGeneric(branch)
|
||||
if branchSum > 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..<t.len:
|
||||
if t[i] != nil:
|
||||
result += sumGeneric(t[i])
|
||||
for a in t.kids:
|
||||
if a != nil:
|
||||
result += sumGeneric(a)
|
||||
break
|
||||
of tyProc:
|
||||
result += sumGeneric(t.returnType)
|
||||
for _, a in t.paramTypes:
|
||||
result += sumGeneric(a)
|
||||
break
|
||||
of tyStatic:
|
||||
return sumGeneric(t.skipModifier) + 1
|
||||
@@ -1146,7 +1151,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
# both int and string must match against number
|
||||
# but ensure that '[T: A|A]' matches as good as '[T: A]' (bug #2219):
|
||||
result = isGeneric
|
||||
for branch in a:
|
||||
for branch in a.kids:
|
||||
let x = typeRel(c, f, branch, flags + {trDontBind})
|
||||
if x == isNone: return isNone
|
||||
if x < result: result = x
|
||||
@@ -1156,7 +1161,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
c.typedescMatched = true
|
||||
# seq[Sortable and Iterable] vs seq[Sortable]
|
||||
# only one match is enough
|
||||
for branch in a:
|
||||
for branch in a.kids:
|
||||
let x = typeRel(c, f, branch, flags + {trDontBind})
|
||||
if x != isNone:
|
||||
return if x >= 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
|
||||
|
||||
@@ -332,8 +332,7 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
|
||||
of tyTuple:
|
||||
try:
|
||||
var accum = OffsetAccum(maxAlign: 1)
|
||||
for i in 0..<typ.len:
|
||||
let child = typ[i]
|
||||
for i, child in typ.ikids:
|
||||
computeSizeAlign(conf, child)
|
||||
accum.align(child.align)
|
||||
if typ.n != nil: # is named tuple (has field symbols)?
|
||||
@@ -403,16 +402,16 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
|
||||
typ.align = szIllegalRecursion
|
||||
typ.paddingAtEnd = szIllegalRecursion
|
||||
of tyInferred:
|
||||
if typ.len > 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:
|
||||
|
||||
@@ -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..<t.len:
|
||||
for _, a in t.paramTypes:
|
||||
if result != nil: break
|
||||
result = typeAllowedAux(marker, t[i], skParam, c, f-{taIsOpenArray})
|
||||
result = typeAllowedAux(marker, a, skParam, c, f-{taIsOpenArray})
|
||||
if result.isNil and t.returnType != nil:
|
||||
result = typeAllowedAux(marker, t.returnType, skResult, c, flags)
|
||||
of tyTypeDesc:
|
||||
@@ -179,17 +179,22 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||
result = typeAllowedAux(marker, t.elementType, kind, c, flags+{taHeap})
|
||||
of tySet:
|
||||
result = typeAllowedAux(marker, t.elementType, kind, c, flags)
|
||||
of tyObject, tyTuple:
|
||||
of tyObject:
|
||||
if kind in {skProc, skFunc, skConst} and
|
||||
t.kind == tyObject and t.baseClass != nil and taIsDefaultField notin flags:
|
||||
t.baseClass != nil and taIsDefaultField notin flags:
|
||||
result = t
|
||||
else:
|
||||
let flags = flags+{taField}
|
||||
for i in 0..<t.len:
|
||||
result = typeAllowedAux(marker, t[i], kind, c, flags)
|
||||
if result != nil: break
|
||||
result = typeAllowedAux(marker, t.baseClass, kind, c, flags)
|
||||
if result.isNil and t.n != nil:
|
||||
result = typeAllowedNode(marker, t.n, kind, c, flags)
|
||||
of tyTuple:
|
||||
let flags = flags+{taField}
|
||||
for a in t.kids:
|
||||
result = typeAllowedAux(marker, a, kind, c, flags)
|
||||
if result != nil: break
|
||||
if result.isNil and t.n != nil:
|
||||
result = typeAllowedNode(marker, t.n, kind, c, flags)
|
||||
of tyEmpty:
|
||||
if kind in {skVar, skLet}: result = t
|
||||
of tyProxy:
|
||||
@@ -197,7 +202,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||
# prevent cascading errors:
|
||||
result = nil
|
||||
of tyOwned:
|
||||
if t.len == 1 and t.skipModifier.skipTypes(abstractInst).kind in {tyRef, tyPtr, tyProc}:
|
||||
if t.hasElementType and t.skipModifier.skipTypes(abstractInst).kind in {tyRef, tyPtr, tyProc}:
|
||||
result = typeAllowedAux(marker, t.skipModifier, kind, c, flags+{taHeap})
|
||||
else:
|
||||
result = t
|
||||
@@ -247,14 +252,14 @@ proc classifyViewTypeAux(marker: var IntSet, t: PType): ViewTypeKind =
|
||||
tyUncheckedArray, tySequence, tyArray, tyRef, tyStatic:
|
||||
result = classifyViewTypeAux(marker, skipModifier(t))
|
||||
of tyFromExpr:
|
||||
if t.len > 0:
|
||||
if t.hasElementType:
|
||||
result = classifyViewTypeAux(marker, skipModifier(t))
|
||||
else:
|
||||
result = noView
|
||||
of tyTuple:
|
||||
result = noView
|
||||
for i in 0..<t.len:
|
||||
result.combine classifyViewTypeAux(marker, t[i])
|
||||
for a in t.kids:
|
||||
result.combine classifyViewTypeAux(marker, a)
|
||||
if result == mutableView: break
|
||||
of tyObject:
|
||||
result = noView
|
||||
|
||||
@@ -68,13 +68,10 @@ template `$`*(typ: PType): string = typeToString(typ)
|
||||
# ------------------- type iterator: ----------------------------------------
|
||||
type
|
||||
TTypeIter* = proc (t: PType, closure: RootRef): bool {.nimcall.} # true if iteration should stop
|
||||
TTypeMutator* = proc (t: PType, closure: RootRef): PType {.nimcall.} # copy t and mutate it
|
||||
TTypePredicate* = proc (t: PType): bool {.nimcall.}
|
||||
|
||||
proc iterOverType*(t: PType, iter: TTypeIter, closure: RootRef): bool
|
||||
# Returns result of `iter`.
|
||||
proc mutateType*(t: PType, iter: TTypeMutator, closure: RootRef): PType
|
||||
# Returns result of `iter`.
|
||||
|
||||
type
|
||||
TParamsEquality* = enum # they are equal, but their
|
||||
@@ -228,8 +225,8 @@ proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
|
||||
of tyGenericInst, tyGenericBody, tyAlias, tySink, tyInferred:
|
||||
result = iterOverTypeAux(marker, skipModifier(t), iter, closure)
|
||||
else:
|
||||
for i in 0..<t.len:
|
||||
result = iterOverTypeAux(marker, t[i], iter, closure)
|
||||
for a in t.kids:
|
||||
result = iterOverTypeAux(marker, a, iter, closure)
|
||||
if result: return
|
||||
if t.n != nil and t.kind != tyProc: result = iterOverNode(marker, t.n, iter, closure)
|
||||
|
||||
@@ -278,8 +275,8 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate,
|
||||
of tyGenericInst, tyDistinct, tyAlias, tySink:
|
||||
result = searchTypeForAux(skipModifier(t), predicate, marker)
|
||||
of tyArray, tySet, tyTuple:
|
||||
for i in 0..<t.len:
|
||||
result = searchTypeForAux(t[i], predicate, marker)
|
||||
for a in t.kids:
|
||||
result = searchTypeForAux(a, predicate, marker)
|
||||
if result: return
|
||||
else:
|
||||
discard
|
||||
@@ -307,7 +304,6 @@ type
|
||||
|
||||
proc analyseObjectWithTypeFieldAux(t: PType,
|
||||
marker: var IntSet): TTypeFieldResult =
|
||||
var res: TTypeFieldResult
|
||||
result = frNone
|
||||
if t == nil: return
|
||||
case t.kind
|
||||
@@ -315,20 +311,19 @@ proc analyseObjectWithTypeFieldAux(t: PType,
|
||||
if t.n != nil:
|
||||
if searchTypeNodeForAux(t.n, isObjectWithTypeFieldPredicate, marker):
|
||||
return frEmbedded
|
||||
for i in 0..<t.len:
|
||||
var x = t[i]
|
||||
if x != nil: x = x.skipTypes(skipPtrs)
|
||||
res = analyseObjectWithTypeFieldAux(x, marker)
|
||||
if res == frEmbedded:
|
||||
return frEmbedded
|
||||
if res == frHeader: result = frHeader
|
||||
var x = t.baseClass
|
||||
if x != nil: x = x.skipTypes(skipPtrs)
|
||||
let res = analyseObjectWithTypeFieldAux(x, marker)
|
||||
if res == frEmbedded:
|
||||
return frEmbedded
|
||||
if res == frHeader: result = frHeader
|
||||
if result == frNone:
|
||||
if isObjectWithTypeFieldPredicate(t): result = frHeader
|
||||
of tyGenericInst, tyDistinct, tyAlias, tySink:
|
||||
result = analyseObjectWithTypeFieldAux(skipModifier(t), marker)
|
||||
of tyArray, tyTuple:
|
||||
for i in 0..<t.len:
|
||||
res = analyseObjectWithTypeFieldAux(t[i], marker)
|
||||
for a in t.kids:
|
||||
let res = analyseObjectWithTypeFieldAux(a, marker)
|
||||
if res != frNone:
|
||||
return frEmbedded
|
||||
else:
|
||||
@@ -405,9 +400,7 @@ proc canFormAcycleAux(g: ModuleGraph, marker: var IntSet, typ: PType, orig: PTyp
|
||||
if withRef and sameBackendType(t, orig):
|
||||
result = true
|
||||
elif not containsOrIncl(marker, t.id):
|
||||
for i in 0..<t.len:
|
||||
result = canFormAcycleAux(g, marker, t[i], orig, withRef or t.kind != tyUncheckedArray, hasTrace)
|
||||
if result: return
|
||||
result = canFormAcycleAux(g, marker, t.elementType, orig, withRef or t.kind != tyUncheckedArray, hasTrace)
|
||||
of tyObject:
|
||||
if withRef and sameBackendType(t, orig):
|
||||
result = true
|
||||
@@ -416,8 +409,8 @@ proc canFormAcycleAux(g: ModuleGraph, marker: var IntSet, typ: PType, orig: PTyp
|
||||
let op = getAttachedOp(g, t.skipTypes({tyRef}), attachedTrace)
|
||||
if op != nil and sfOverridden in op.flags:
|
||||
hasTrace = true
|
||||
for i in 0..<t.len:
|
||||
result = canFormAcycleAux(g, marker, t[i], orig, withRef, hasTrace)
|
||||
if t.baseClass != nil:
|
||||
result = canFormAcycleAux(g, marker, t.baseClass, orig, withRef, hasTrace)
|
||||
if result: return
|
||||
if t.n != nil: result = canFormAcycleNode(g, marker, t.n, orig, withRef, hasTrace)
|
||||
# Inheritance can introduce cyclic types, however this is not relevant
|
||||
@@ -426,13 +419,18 @@ proc canFormAcycleAux(g: ModuleGraph, marker: var IntSet, typ: PType, orig: PTyp
|
||||
if tfFinal notin t.flags:
|
||||
# damn inheritance may introduce cycles:
|
||||
result = true
|
||||
of tyTuple, tySequence, tyArray, tyOpenArray, tyVarargs:
|
||||
of tyTuple:
|
||||
if withRef and sameBackendType(t, orig):
|
||||
result = true
|
||||
elif not containsOrIncl(marker, t.id):
|
||||
for i in 0..<t.len:
|
||||
result = canFormAcycleAux(g, marker, t[i], orig, withRef, hasTrace)
|
||||
for a in t.kids:
|
||||
result = canFormAcycleAux(g, marker, a, orig, withRef, hasTrace)
|
||||
if result: return
|
||||
of tySequence, tyArray, tyOpenArray, tyVarargs:
|
||||
if withRef and sameBackendType(t, orig):
|
||||
result = true
|
||||
elif not containsOrIncl(marker, t.id):
|
||||
result = canFormAcycleAux(g, marker, t.elementType, orig, withRef, hasTrace)
|
||||
of tyProc: result = typ.callConv == ccClosure
|
||||
else: discard
|
||||
|
||||
@@ -445,37 +443,6 @@ proc canFormAcycle*(g: ModuleGraph, typ: PType): bool =
|
||||
let t = skipTypes(typ, abstractInst+{tyOwned}-{tyTypeDesc})
|
||||
result = canFormAcycleAux(g, marker, t, t, false, false)
|
||||
|
||||
proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator,
|
||||
closure: RootRef): PType
|
||||
proc mutateNode(marker: var IntSet, n: PNode, iter: TTypeMutator,
|
||||
closure: RootRef): PNode =
|
||||
result = nil
|
||||
if n != nil:
|
||||
result = copyNode(n)
|
||||
result.typ = mutateTypeAux(marker, n.typ, iter, closure)
|
||||
case n.kind
|
||||
of nkNone..nkNilLit:
|
||||
# a leaf
|
||||
discard
|
||||
else:
|
||||
for i in 0..<n.len:
|
||||
result.add mutateNode(marker, n[i], iter, closure)
|
||||
|
||||
proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator,
|
||||
closure: RootRef): PType =
|
||||
result = nil
|
||||
if t == nil: return
|
||||
result = iter(t, closure)
|
||||
if not containsOrIncl(marker, t.id):
|
||||
for i in 0..<t.len:
|
||||
result[i] = mutateTypeAux(marker, result[i], iter, closure)
|
||||
if t.n != nil: result.n = mutateNode(marker, t.n, iter, closure)
|
||||
assert(result != nil)
|
||||
|
||||
proc mutateType(t: PType, iter: TTypeMutator, closure: RootRef): PType =
|
||||
var marker = initIntSet()
|
||||
result = mutateTypeAux(marker, t, iter, closure)
|
||||
|
||||
proc valueToString(a: PNode): string =
|
||||
case a.kind
|
||||
of nkCharLit, nkUIntLit..nkUInt64Lit:
|
||||
@@ -566,13 +533,9 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
elif prefer in {preferName, preferTypeName, preferInlayHint} or t.sym.owner.isNil:
|
||||
# note: should probably be: {preferName, preferTypeName, preferGenericArg}
|
||||
result = t.sym.name.s
|
||||
if t.kind == tyGenericParam and t.len > 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..<t.len-ord(t.kind != tyGenericInvocation):
|
||||
if i > 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..<t.len-1:
|
||||
if i > 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..<t.len - 1:
|
||||
if i > 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..<t.n.len:
|
||||
assert(t.n[i].kind == nkSym)
|
||||
result.add(t.n[i].sym.name.s & ": " & typeToString(t[i]))
|
||||
result.add(t.n[i].sym.name.s & ": " & typeToString(t.n[i].sym.typ))
|
||||
if i < t.n.len - 1: result.add(", ")
|
||||
result.add(']')
|
||||
elif t.len == 0:
|
||||
elif t.isEmptyTupleType:
|
||||
result = "tuple[]"
|
||||
elif t.isSingletonTupleType:
|
||||
result = "("
|
||||
for son in t.kids:
|
||||
result.add(typeToString(son))
|
||||
result.add(",)")
|
||||
else:
|
||||
result = "("
|
||||
for i in 0..<t.len:
|
||||
result.add(typeToString(t[i]))
|
||||
if i < t.len - 1: result.add(", ")
|
||||
elif t.len == 1: result.add(",")
|
||||
for i, son in t.ikids:
|
||||
if i > 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..<t.len:
|
||||
result.add(typeToString(t[i]))
|
||||
if i < t.len - 1: result.add(", ")
|
||||
result.add ']'
|
||||
else:
|
||||
result.add typeToString(t.elementType)
|
||||
result.add typeToString(t.elementType)
|
||||
of tyRange:
|
||||
result = "range "
|
||||
if t.n != nil and t.n.kind == nkRange:
|
||||
@@ -751,14 +713,15 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
"proc "
|
||||
if tfUnresolved in t.flags: result.add "[*missing parameters*]"
|
||||
result.add "("
|
||||
for i in 1..<t.len:
|
||||
if t.n != nil and i < t.n.len and t.n[i].kind == nkSym:
|
||||
result.add(t.n[i].sym.name.s)
|
||||
for i, a in t.paramTypes:
|
||||
if i > 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:
|
||||
var x = a[i]
|
||||
var y = b[i]
|
||||
for i, aa, bb in tupleTypePairs(a, b):
|
||||
var x = aa
|
||||
var y = bb
|
||||
if IgnoreTupleFields in c.flags:
|
||||
x = skipTypes(x, {tyRange, tyGenericInst, tyAlias})
|
||||
y = skipTypes(y, {tyRange, tyGenericInst, tyAlias})
|
||||
@@ -1184,18 +1147,16 @@ proc sameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool =
|
||||
result = false
|
||||
|
||||
proc sameObjectStructures(a, b: PType, c: var TSameTypeClosure): bool =
|
||||
# check base types:
|
||||
if a.len != b.len: return
|
||||
for i in 0..<a.len:
|
||||
if not sameTypeOrNilAux(a[i], b[i], c): return
|
||||
if not sameObjectTree(a.n, b.n, c): return
|
||||
if not sameTypeOrNilAux(a.baseClass, b.baseClass, c): return false
|
||||
if not sameObjectTree(a.n, b.n, c): return false
|
||||
result = true
|
||||
|
||||
proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool =
|
||||
if a.len != b.len: return false
|
||||
if not sameTupleLengths(a, b): return false
|
||||
# XXX This is not tuple specific.
|
||||
result = true
|
||||
for i in 0..<a.len:
|
||||
result = sameTypeOrNilAux(a[i], b[i], c)
|
||||
for _, x, y in tupleTypePairs(a, b):
|
||||
result = sameTypeOrNilAux(x, y, c)
|
||||
if not result: return
|
||||
|
||||
proc isGenericAlias*(t: PType): bool =
|
||||
@@ -1253,15 +1214,13 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||
objects ie `type A[T] = SomeObject`
|
||||
]#
|
||||
# this is required by tunique_type but makes no sense really:
|
||||
if tyDistinct notin {x.kind, y.kind} and x.kind == tyGenericInst and IgnoreTupleFields notin c.flags:
|
||||
if x.kind == tyGenericInst and IgnoreTupleFields notin c.flags and tyDistinct != y.kind:
|
||||
let
|
||||
lhs = x.skipGenericAlias
|
||||
rhs = y.skipGenericAlias
|
||||
if rhs.kind != tyGenericInst or lhs.base != rhs.base:
|
||||
return false
|
||||
for i in 1..<lhs.len - 1:
|
||||
let ff = rhs[i]
|
||||
let aa = lhs[i]
|
||||
for ff, aa in underspecifiedPairs(rhs, lhs, 1, -1):
|
||||
if not sameTypeAux(ff, aa, c): return false
|
||||
return true
|
||||
|
||||
@@ -1279,7 +1238,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||
|
||||
of tyStatic, tyFromExpr:
|
||||
result = exprStructuralEquivalent(a.n, b.n) and sameFlags(a, b)
|
||||
if result and a.len == b.len and a.len == 1:
|
||||
if result and sameTupleLengths(a, b) and a.hasElementType:
|
||||
cycleCheck()
|
||||
result = sameTypeAux(a.skipModifier, b.skipModifier, c)
|
||||
of tyObject:
|
||||
@@ -1314,15 +1273,11 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||
if result and {ExactGenericParams, ExactTypeDescValues} * c.flags != {}:
|
||||
result = a.sym.position == b.sym.position
|
||||
of tyBuiltInTypeClass:
|
||||
assert a.len == 1
|
||||
assert a[0].len == 0
|
||||
assert b.len == 1
|
||||
assert b[0].len == 0
|
||||
result = a[0].kind == b[0].kind and sameFlags(a[0], b[0])
|
||||
if result and a[0].kind == tyProc and IgnoreCC notin c.flags:
|
||||
let ecc = a[0].flags * {tfExplicitCallConv}
|
||||
result = ecc == b[0].flags * {tfExplicitCallConv} and
|
||||
(ecc == {} or a[0].callConv == b[0].callConv)
|
||||
result = a.elementType.kind == b.elementType.kind and sameFlags(a.elementType, b.elementType)
|
||||
if result and a.elementType.kind == tyProc and IgnoreCC notin c.flags:
|
||||
let ecc = a.elementType.flags * {tfExplicitCallConv}
|
||||
result = ecc == b.elementType.flags * {tfExplicitCallConv} and
|
||||
(ecc == {} or a.elementType.callConv == b.elementType.callConv)
|
||||
of tyGenericInvocation, tyGenericBody, tySequence, tyOpenArray, tySet, tyRef,
|
||||
tyPtr, tyVar, tyLent, tySink, tyUncheckedArray, tyArray, tyProc, tyVarargs,
|
||||
tyOrdinal, tyCompositeTypeClass, tyUserTypeClass, tyUserTypeClassInst,
|
||||
@@ -1418,15 +1373,6 @@ proc commonSuperclass*(a, b: PType): PType =
|
||||
return t
|
||||
y = y.baseClass
|
||||
|
||||
proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
|
||||
last: TTypeKind): bool =
|
||||
var a = a
|
||||
for k, i in pattern.items:
|
||||
if a.kind != k: return false
|
||||
if i >= 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..<t.len:
|
||||
if t[i] != nil and isCompileTimeOnly(t[i]):
|
||||
for a in t.kids:
|
||||
if a != nil and isCompileTimeOnly(a):
|
||||
return true
|
||||
return false
|
||||
|
||||
@@ -1787,9 +1733,9 @@ proc isTupleRecursive(t: PType, cycleDetector: var IntSet): bool =
|
||||
of tyTuple:
|
||||
result = false
|
||||
var cycleDetectorCopy: IntSet
|
||||
for i in 0..<t.len:
|
||||
for a in t.kids:
|
||||
cycleDetectorCopy = cycleDetector
|
||||
if isTupleRecursive(t[i], cycleDetectorCopy):
|
||||
if isTupleRecursive(a, cycleDetectorCopy):
|
||||
return true
|
||||
of tyRef, tyPtr, tyVar, tyLent, tySink,
|
||||
tyArray, tyUncheckedArray, tySequence, tyDistinct:
|
||||
|
||||
@@ -400,11 +400,10 @@ proc allRoots(n: PNode; result: var seq[(PSym, int)]; level: int) =
|
||||
if typ != nil:
|
||||
typ = skipTypes(typ, abstractInst)
|
||||
if typ.kind != tyProc: typ = nil
|
||||
else: assert(typ.len == typ.n.len)
|
||||
|
||||
for i in 1 ..< n.len:
|
||||
let it = n[i]
|
||||
if typ != nil and i < typ.len:
|
||||
if typ != nil and i < typ.n.len:
|
||||
assert(typ.n[i].kind == nkSym)
|
||||
let paramType = typ.n[i].typ
|
||||
if not paramType.isCompileTimeOnly and not typ.returnType.isEmptyType and
|
||||
|
||||
@@ -205,7 +205,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
# only named tuples have a node, unnamed tuples don't
|
||||
if t.n.isNil:
|
||||
result = newNodeX(nkTupleConstr)
|
||||
for subType in t:
|
||||
for subType in t.kids:
|
||||
result.add mapTypeToAst(subType, info)
|
||||
else:
|
||||
result = newNodeX(nkTupleTy)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
discard """
|
||||
errormsg: "type mismatch: got <BPtr> 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
|
||||
Reference in New Issue
Block a user