mirror of
https://github.com/nim-lang/Nim.git
synced 2026-09-19 11:28:17 +00:00
Types: Refactorings; step 1 (#23055)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.} =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 & ')')
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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``.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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) =
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 & "'")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import ast, idents, lineinfos, astalgo
|
||||
import ast except elementType
|
||||
import idents, lineinfos, astalgo
|
||||
import vmdef
|
||||
import std/times
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user