removed tyArrayConstr completely from the compiler; introduced tyAlias instead in preparation for further bugfixes

This commit is contained in:
Araq 2016-11-14 23:18:30 +01:00
commit e6c5622aa7
35 changed files with 201 additions and 206 deletions

View file

@ -49,9 +49,9 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
if a.sons[0] != nil: if a.sons[0] != nil:
result = isPartOfAux(a.sons[0].skipTypes(skipPtrs), b, marker) result = isPartOfAux(a.sons[0].skipTypes(skipPtrs), b, marker)
if result == arNo: result = isPartOfAux(a.n, b, marker) if result == arNo: result = isPartOfAux(a.n, b, marker)
of tyGenericInst, tyDistinct: of tyGenericInst, tyDistinct, tyAlias:
result = isPartOfAux(lastSon(a), b, marker) result = isPartOfAux(lastSon(a), b, marker)
of tyArray, tyArrayConstr, tySet, tyTuple: of tyArray, tySet, tyTuple:
for i in countup(0, sonsLen(a) - 1): for i in countup(0, sonsLen(a) - 1):
result = isPartOfAux(a.sons[i], b, marker) result = isPartOfAux(a.sons[i], b, marker)
if result == arYes: return if result == arYes: return

View file

@ -322,7 +322,7 @@ type
# (apparently something with bootstrapping) # (apparently something with bootstrapping)
# if you need to add a type, they can apparently be reused # if you need to add a type, they can apparently be reused
tyNone, tyBool, tyChar, tyNone, tyBool, tyChar,
tyEmpty, tyArrayConstr, tyNil, tyExpr, tyStmt, tyTypeDesc, tyEmpty, tyAlias, tyNil, tyExpr, tyStmt, tyTypeDesc,
tyGenericInvocation, # ``T[a, b]`` for types to invoke tyGenericInvocation, # ``T[a, b]`` for types to invoke
tyGenericBody, # ``T[a, b, body]`` last parameter is the body tyGenericBody, # ``T[a, b, body]`` last parameter is the body
tyGenericInst, # ``T[a, b, realInstance]`` instantiated generic type tyGenericInst, # ``T[a, b, realInstance]`` instantiated generic type
@ -907,7 +907,7 @@ const
GenericTypes*: TTypeKinds = {tyGenericInvocation, tyGenericBody, GenericTypes*: TTypeKinds = {tyGenericInvocation, tyGenericBody,
tyGenericParam} tyGenericParam}
StructuralEquivTypes*: TTypeKinds = {tyArrayConstr, tyNil, tyTuple, tyArray, StructuralEquivTypes*: TTypeKinds = {tyNil, tyTuple, tyArray,
tySet, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, tyOpenArray, tySet, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, tyOpenArray,
tyVarargs} tyVarargs}
@ -920,7 +920,7 @@ const
tyUInt..tyUInt64} tyUInt..tyUInt64}
IntegralTypes* = {tyBool, tyChar, tyEnum, tyInt..tyInt64, IntegralTypes* = {tyBool, tyChar, tyEnum, tyInt..tyInt64,
tyFloat..tyFloat128, tyUInt..tyUInt64} tyFloat..tyFloat128, tyUInt..tyUInt64}
ConstantDataTypes*: TTypeKinds = {tyArrayConstr, tyArray, tySet, ConstantDataTypes*: TTypeKinds = {tyArray, tySet,
tyTuple, tySequence} tyTuple, tySequence}
NilableTypes*: TTypeKinds = {tyPointer, tyCString, tyRef, tyPtr, tySequence, NilableTypes*: TTypeKinds = {tyPointer, tyCString, tyRef, tyPtr, tySequence,
tyProc, tyString, tyError} tyProc, tyString, tyError}
@ -1370,8 +1370,8 @@ proc propagateToOwner*(owner, elem: PType) =
owner.flags.incl tfHasMeta owner.flags.incl tfHasMeta
if tfHasAsgn in elem.flags: if tfHasAsgn in elem.flags:
let o2 = elem.skipTypes({tyGenericInst}) let o2 = elem.skipTypes({tyGenericInst, tyAlias})
if o2.kind in {tyTuple, tyObject, tyArray, tyArrayConstr, if o2.kind in {tyTuple, tyObject, tyArray,
tySequence, tySet, tyDistinct}: tySequence, tySet, tyDistinct}:
o2.flags.incl tfHasAsgn o2.flags.incl tfHasAsgn
owner.flags.incl tfHasAsgn owner.flags.incl tfHasAsgn
@ -1381,7 +1381,7 @@ proc propagateToOwner*(owner, elem: PType) =
if owner.kind notin {tyProc, tyGenericInst, tyGenericBody, if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
tyGenericInvocation, tyPtr}: tyGenericInvocation, tyPtr}:
let elemB = elem.skipTypes({tyGenericInst}) let elemB = elem.skipTypes({tyGenericInst, tyAlias})
if elemB.isGCedMem or tfHasGCedMem in elemB.flags: if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
# for simplicity, we propagate this flag even to generics. We then # for simplicity, we propagate this flag even to generics. We then
# ensure this doesn't bite us in sempass2. # ensure this doesn't bite us in sempass2.

View file

@ -132,7 +132,7 @@ proc hashType(c: var MD5Context, t: PType) =
c.hashType t.sons[i] c.hashType t.sons[i]
of tyFromExpr, tyFieldAccessor: of tyFromExpr, tyFieldAccessor:
c.hashTree(t.n) c.hashTree(t.n)
of tyArrayConstr: of tyArray:
c.hashTree(t.sons[0].n) c.hashTree(t.sons[0].n)
c.hashType(t.sons[1]) c.hashType(t.sons[1])
of tyTuple: of tyTuple:

View file

@ -95,7 +95,7 @@ proc openArrayLoc(p: BProc, n: PNode): Rope =
initLocExpr(p, q[3], c) initLocExpr(p, q[3], c)
let fmt = let fmt =
case skipTypes(a.t, abstractVar+{tyPtr}).kind case skipTypes(a.t, abstractVar+{tyPtr}).kind
of tyOpenArray, tyVarargs, tyArray, tyArrayConstr: of tyOpenArray, tyVarargs, tyArray:
"($1)+($2), ($3)-($2)+1" "($1)+($2), ($3)-($2)+1"
of tyString, tySequence: of tyString, tySequence:
if skipTypes(n.typ, abstractInst).kind == tyVar and if skipTypes(n.typ, abstractInst).kind == tyVar and
@ -116,13 +116,13 @@ proc openArrayLoc(p: BProc, n: PNode): Rope =
result = "(*$1)->data, (*$1)->$2" % [a.rdLoc, lenField(p)] result = "(*$1)->data, (*$1)->$2" % [a.rdLoc, lenField(p)]
else: else:
result = "$1->data, $1->$2" % [a.rdLoc, lenField(p)] result = "$1->data, $1->$2" % [a.rdLoc, lenField(p)]
of tyArray, tyArrayConstr: of tyArray:
result = "$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))] result = "$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))]
of tyPtr, tyRef: of tyPtr, tyRef:
case lastSon(a.t).kind case lastSon(a.t).kind
of tyString, tySequence: of tyString, tySequence:
result = "(*$1)->data, (*$1)->$2" % [a.rdLoc, lenField(p)] result = "(*$1)->data, (*$1)->$2" % [a.rdLoc, lenField(p)]
of tyArray, tyArrayConstr: of tyArray:
result = "$1, $2" % [rdLoc(a), rope(lengthOrd(lastSon(a.t)))] result = "$1, $2" % [rdLoc(a), rope(lengthOrd(lastSon(a.t)))]
else: else:
internalError("openArrayLoc: " & typeToString(a.t)) internalError("openArrayLoc: " & typeToString(a.t))
@ -331,7 +331,7 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): Rope =
# skip the deref: # skip the deref:
var ri = ri[i] var ri = ri[i]
while ri.kind == nkObjDownConv: ri = ri[0] while ri.kind == nkObjDownConv: ri = ri[0]
let t = typ.sons[i].skipTypes({tyGenericInst}) let t = typ.sons[i].skipTypes({tyGenericInst, tyAlias})
if t.kind == tyVar: if t.kind == tyVar:
let x = if ri.kind == nkHiddenAddr: ri[0] else: ri let x = if ri.kind == nkHiddenAddr: ri[0] else: ri
if x.typ.kind == tyPtr: if x.typ.kind == tyPtr:
@ -527,7 +527,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
line(p, cpsStmts, pl) line(p, cpsStmts, pl)
proc genCall(p: BProc, e: PNode, d: var TLoc) = proc genCall(p: BProc, e: PNode, d: var TLoc) =
if e.sons[0].typ.skipTypes({tyGenericInst}).callConv == ccClosure: if e.sons[0].typ.skipTypes({tyGenericInst, tyAlias}).callConv == ccClosure:
genClosureCall(p, nil, e, d) genClosureCall(p, nil, e, d)
elif e.sons[0].kind == nkSym and sfInfixCall in e.sons[0].sym.flags: elif e.sons[0].kind == nkSym and sfInfixCall in e.sons[0].sym.flags:
genInfixCall(p, nil, e, d) genInfixCall(p, nil, e, d)
@ -538,7 +538,7 @@ proc genCall(p: BProc, e: PNode, d: var TLoc) =
postStmtActions(p) postStmtActions(p)
proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) = proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) =
if ri.sons[0].typ.skipTypes({tyGenericInst}).callConv == ccClosure: if ri.sons[0].typ.skipTypes({tyGenericInst, tyAlias}).callConv == ccClosure:
genClosureCall(p, le, ri, d) genClosureCall(p, le, ri, d)
elif ri.sons[0].kind == nkSym and sfInfixCall in ri.sons[0].sym.flags: elif ri.sons[0].kind == nkSym and sfInfixCall in ri.sons[0].sym.flags:
genInfixCall(p, le, ri, d) genInfixCall(p, le, ri, d)

View file

@ -322,7 +322,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
genGenericAsgn(p, dest, src, flags) genGenericAsgn(p, dest, src, flags)
else: else:
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
of tyArray, tyArrayConstr: of tyArray:
if needsComplexAssignment(dest.t): if needsComplexAssignment(dest.t):
genGenericAsgn(p, dest, src, flags) genGenericAsgn(p, dest, src, flags)
else: else:
@ -357,7 +357,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
proc genDeepCopy(p: BProc; dest, src: TLoc) = proc genDeepCopy(p: BProc; dest, src: TLoc) =
var ty = skipTypes(dest.t, abstractVarRange) var ty = skipTypes(dest.t, abstractVarRange)
case ty.kind case ty.kind
of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray, tyArrayConstr: of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray:
# XXX optimize this # XXX optimize this
linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n", linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n",
addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)) addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
@ -871,7 +871,7 @@ proc genBracketExpr(p: BProc; n: PNode; d: var TLoc) =
var ty = skipTypes(n.sons[0].typ, abstractVarRange) var ty = skipTypes(n.sons[0].typ, abstractVarRange)
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange) if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
case ty.kind case ty.kind
of tyArray, tyArrayConstr: genArrayElem(p, n.sons[0], n.sons[1], d) of tyArray: genArrayElem(p, n.sons[0], n.sons[1], d)
of tyOpenArray, tyVarargs: genOpenArrayElem(p, n.sons[0], n.sons[1], d) of tyOpenArray, tyVarargs: genOpenArrayElem(p, n.sons[0], n.sons[1], d)
of tySequence, tyString: genSeqElem(p, n.sons[0], n.sons[1], d) of tySequence, tyString: genSeqElem(p, n.sons[0], n.sons[1], d)
of tyCString: genCStringElem(p, n.sons[0], n.sons[1], d) of tyCString: genCStringElem(p, n.sons[0], n.sons[1], d)
@ -1301,15 +1301,14 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
of tyString, tySequence: of tyString, tySequence:
putIntoDest(p, b, e.typ, putIntoDest(p, b, e.typ,
"$1->data, $1->$2" % [rdLoc(a), lenField(p)], a.s) "$1->data, $1->$2" % [rdLoc(a), lenField(p)], a.s)
of tyArray, tyArrayConstr: of tyArray:
putIntoDest(p, b, e.typ, putIntoDest(p, b, e.typ,
"$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))], a.s) "$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))], a.s)
else: internalError(e.sons[0].info, "genRepr()") else: internalError(e.sons[0].info, "genRepr()")
putIntoDest(p, d, e.typ, putIntoDest(p, d, e.typ,
ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b), ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b),
genTypeInfo(p.module, elemType(t))]), a.s) genTypeInfo(p.module, elemType(t))]), a.s)
of tyCString, tyArray, tyArrayConstr, tyRef, tyPtr, tyPointer, tyNil, of tyCString, tyArray, tyRef, tyPtr, tyPointer, tyNil, tySequence:
tySequence:
putIntoDest(p, d, e.typ, putIntoDest(p, d, e.typ,
ropecg(p.module, "#reprAny($1, $2)", [ ropecg(p.module, "#reprAny($1, $2)", [
rdLoc(a), genTypeInfo(p.module, t)]), a.s) rdLoc(a), genTypeInfo(p.module, t)]), a.s)
@ -1351,7 +1350,7 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
else: else:
if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->len-1) : -1)") if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->len-1) : -1)")
else: unaryExpr(p, e, d, "($1 ? $1->len : 0)") else: unaryExpr(p, e, d, "($1 ? $1->len : 0)")
of tyArray, tyArrayConstr: of tyArray:
# YYY: length(sideeffect) is optimized away incorrectly? # YYY: length(sideeffect) is optimized away incorrectly?
if op == mHigh: putIntoDest(p, d, e.typ, rope(lastOrd(typ))) if op == mHigh: putIntoDest(p, d, e.typ, rope(lastOrd(typ)))
else: putIntoDest(p, d, e.typ, rope(lengthOrd(typ))) else: putIntoDest(p, d, e.typ, rope(lengthOrd(typ)))
@ -1531,8 +1530,7 @@ proc genOrd(p: BProc, e: PNode, d: var TLoc) =
proc genSomeCast(p: BProc, e: PNode, d: var TLoc) = proc genSomeCast(p: BProc, e: PNode, d: var TLoc) =
const const
ValueTypes = {tyTuple, tyObject, tyArray, tyOpenArray, tyVarargs, ValueTypes = {tyTuple, tyObject, tyArray, tyOpenArray, tyVarargs}
tyArrayConstr}
# we use whatever C gives us. Except if we have a value-type, we need to go # we use whatever C gives us. Except if we have a value-type, we need to go
# through its address: # through its address:
var a: TLoc var a: TLoc
@ -1549,8 +1547,7 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) =
[getTypeDesc(p.module, e.typ), rdCharLoc(a)], a.s) [getTypeDesc(p.module, e.typ), rdCharLoc(a)], a.s)
proc genCast(p: BProc, e: PNode, d: var TLoc) = proc genCast(p: BProc, e: PNode, d: var TLoc) =
const ValueTypes = {tyFloat..tyFloat128, tyTuple, tyObject, const ValueTypes = {tyFloat..tyFloat128, tyTuple, tyObject, tyArray}
tyArray, tyArrayConstr}
let let
destt = skipTypes(e.typ, abstractRange) destt = skipTypes(e.typ, abstractRange)
srct = skipTypes(e.sons[1].typ, abstractRange) srct = skipTypes(e.sons[1].typ, abstractRange)
@ -1590,7 +1587,7 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
rope(magic)]), a.s) rope(magic)]), a.s)
proc genConv(p: BProc, e: PNode, d: var TLoc) = proc genConv(p: BProc, e: PNode, d: var TLoc) =
let destType = e.typ.skipTypes({tyVar, tyGenericInst}) let destType = e.typ.skipTypes({tyVar, tyGenericInst, tyAlias})
if compareTypes(destType, e.sons[1].typ, dcEqIgnoreDistinct): if compareTypes(destType, e.sons[1].typ, dcEqIgnoreDistinct):
expr(p, e.sons[1], d) expr(p, e.sons[1], d)
else: else:
@ -1664,7 +1661,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
"$# = #subInt64($#, $#);$n"] "$# = #subInt64($#, $#);$n"]
const fun: array[mInc..mDec, string] = ["$# = #addInt($#, $#);$n", const fun: array[mInc..mDec, string] = ["$# = #addInt($#, $#);$n",
"$# = #subInt($#, $#);$n"] "$# = #subInt($#, $#);$n"]
let underlying = skipTypes(e.sons[1].typ, {tyGenericInst, tyVar, tyRange}) let underlying = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tyVar, tyRange})
if optOverflowCheck notin p.options or underlying.kind in {tyUInt..tyUInt64}: if optOverflowCheck notin p.options or underlying.kind in {tyUInt..tyUInt64}:
binaryStmt(p, e, d, opr[op]) binaryStmt(p, e, d, opr[op])
else: else:
@ -1674,7 +1671,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[1], a)
initLocExpr(p, e.sons[2], b) initLocExpr(p, e.sons[2], b)
let ranged = skipTypes(e.sons[1].typ, {tyGenericInst, tyVar}) let ranged = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tyVar})
let res = binaryArithOverflowRaw(p, ranged, a, b, let res = binaryArithOverflowRaw(p, ranged, a, b,
if underlying.kind == tyInt64: fun64[op] else: fun[op]) if underlying.kind == tyInt64: fun64[op] else: fun[op])
putIntoDest(p, a, ranged, "($#)($#)" % [ putIntoDest(p, a, ranged, "($#)($#)" % [

View file

@ -60,9 +60,9 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, typ: PType) =
var p = c.p var p = c.p
case typ.kind case typ.kind
of tyGenericInst, tyGenericBody, tyTypeDesc: of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias:
genTraverseProc(c, accessor, lastSon(typ)) genTraverseProc(c, accessor, lastSon(typ))
of tyArrayConstr, tyArray: of tyArray:
let arraySize = lengthOrd(typ.sons[0]) let arraySize = lengthOrd(typ.sons[0])
var i: TLoc var i: TLoc
getTemp(p, getSysType(tyInt), i) getTemp(p, getSysType(tyInt), i)

View file

@ -133,10 +133,10 @@ proc mapType(typ: PType): TCTypeKind =
of tyBool: result = ctBool of tyBool: result = ctBool
of tyChar: result = ctChar of tyChar: result = ctChar
of tySet: result = mapSetType(typ) of tySet: result = mapSetType(typ)
of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctArray of tyOpenArray, tyArray, tyVarargs: result = ctArray
of tyObject, tyTuple: result = ctStruct of tyObject, tyTuple: result = ctStruct
of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal, of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal,
tyTypeDesc: tyTypeDesc, tyAlias:
result = mapType(lastSon(typ)) result = mapType(lastSon(typ))
of tyEnum: of tyEnum:
if firstOrd(typ) < 0: if firstOrd(typ) < 0:
@ -152,7 +152,7 @@ proc mapType(typ: PType): TCTypeKind =
of tyPtr, tyVar, tyRef: of tyPtr, tyVar, tyRef:
var base = skipTypes(typ.lastSon, typedescInst) var base = skipTypes(typ.lastSon, typedescInst)
case base.kind case base.kind
of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctPtrToArray of tyOpenArray, tyArray, tyVarargs: result = ctPtrToArray
#of tySet: #of tySet:
# if mapSetType(base) == ctArray: result = ctPtrToArray # if mapSetType(base) == ctArray: result = ctPtrToArray
# else: result = ctPtr # else: result = ctPtr
@ -277,7 +277,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
of tyStatic: of tyStatic:
if typ.n != nil: result = getSimpleTypeDesc(m, lastSon typ) if typ.n != nil: result = getSimpleTypeDesc(m, lastSon typ)
else: internalError("tyStatic for getSimpleTypeDesc") else: internalError("tyStatic for getSimpleTypeDesc")
of tyGenericInst: of tyGenericInst, tyAlias:
result = getSimpleTypeDesc(m, lastSon typ) result = getSimpleTypeDesc(m, lastSon typ)
else: result = nil else: result = nil
@ -334,7 +334,7 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): Rope =
proc paramStorageLoc(param: PSym): TStorageLoc = proc paramStorageLoc(param: PSym): TStorageLoc =
if param.typ.skipTypes({tyVar, tyTypeDesc}).kind notin { if param.typ.skipTypes({tyVar, tyTypeDesc}).kind notin {
tyArray, tyOpenArray, tyVarargs, tyArrayConstr}: tyArray, tyOpenArray, tyVarargs}:
result = OnStack result = OnStack
else: else:
result = OnUnknown result = OnUnknown
@ -543,7 +543,7 @@ proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
const const
irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation, irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation,
tyDistinct, tyRange, tyStatic} tyDistinct, tyRange, tyStatic, tyAlias}
proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
# returns only the type's name # returns only the type's name
@ -565,7 +565,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
compileToCpp(m): "&" else: "*" compileToCpp(m): "&" else: "*"
var et = origTyp.skipTypes(abstractInst).lastSon var et = origTyp.skipTypes(abstractInst).lastSon
var etB = et.skipTypes(abstractInst) var etB = et.skipTypes(abstractInst)
if etB.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}: if etB.kind in {tyArray, tyOpenArray, tyVarargs}:
# this is correct! sets have no proper base type, so we treat # this is correct! sets have no proper base type, so we treat
# ``var set[char]`` in `getParamTypeDesc` # ``var set[char]`` in `getParamTypeDesc`
et = elemType(etB) et = elemType(etB)
@ -742,7 +742,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
of 1, 2, 4, 8: addf(m.s[cfsTypes], "typedef NU$2 $1;$n", [result, rope(s*8)]) of 1, 2, 4, 8: addf(m.s[cfsTypes], "typedef NU$2 $1;$n", [result, rope(s*8)])
else: addf(m.s[cfsTypes], "typedef NU8 $1[$2];$n", else: addf(m.s[cfsTypes], "typedef NU8 $1[$2];$n",
[result, rope(getSize(t))]) [result, rope(getSize(t))])
of tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc: of tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias:
result = getTypeDescAux(m, lastSon(t), check) result = getTypeDescAux(m, lastSon(t), check)
else: else:
internalError("getTypeDescAux(" & $t.kind & ')') internalError("getTypeDescAux(" & $t.kind & ')')
@ -1073,7 +1073,7 @@ proc genTypeInfo(m: BModule, t: PType): Rope =
let markerProc = genTraverseProc(m, origType, sig, tiNew) let markerProc = genTraverseProc(m, origType, sig, tiNew)
addf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc]) addf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
of tyPtr, tyRange: genTypeInfoAux(m, t, t, result) of tyPtr, tyRange: genTypeInfoAux(m, t, t, result)
of tyArrayConstr, tyArray: genArrayInfo(m, t, result) of tyArray: genArrayInfo(m, t, result)
of tySet: genSetInfo(m, t, result) of tySet: genSetInfo(m, t, result)
of tyEnum: genEnumInfo(m, t, result) of tyEnum: genEnumInfo(m, t, result)
of tyObject: genObjectInfo(m, t, origType, result) of tyObject: genObjectInfo(m, t, origType, result)

View file

@ -108,7 +108,7 @@ proc getUniqueType*(key: PType): PType =
of tyDistinct: of tyDistinct:
if key.deepCopy != nil: result = key if key.deepCopy != nil: result = key
else: result = getUniqueType(lastSon(key)) else: result = getUniqueType(lastSon(key))
of tyGenericInst, tyOrdinal, tyStatic: of tyGenericInst, tyOrdinal, tyStatic, tyAlias:
result = getUniqueType(lastSon(key)) result = getUniqueType(lastSon(key))
#let obj = lastSon(key) #let obj = lastSon(key)
#if obj.sym != nil and obj.sym.name.s == "TOption": #if obj.sym != nil and obj.sym.name.s == "TOption":
@ -122,7 +122,7 @@ proc getUniqueType*(key: PType): PType =
result = key result = key
else: else:
result = slowSearch(key, k) result = slowSearch(key, k)
of tyArrayConstr, tyGenericInvocation, tyGenericBody, of tyGenericInvocation, tyGenericBody,
tyOpenArray, tyArray, tySet, tyRange, tyTuple, tyOpenArray, tyArray, tySet, tyRange, tyTuple,
tySequence, tyForward, tyVarargs, tyProxy: tySequence, tyForward, tyVarargs, tyProxy:
# we have to do a slow linear search because types may need # we have to do a slow linear search because types may need

View file

@ -62,7 +62,7 @@ proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: Rope, s: TStorageLoc) =
proc isSimpleConst(typ: PType): bool = proc isSimpleConst(typ: PType): bool =
let t = skipTypes(typ, abstractVar) let t = skipTypes(typ, abstractVar)
result = t.kind notin result = t.kind notin
{tyTuple, tyObject, tyArray, tyArrayConstr, tySet, tySequence} and not {tyTuple, tyObject, tyArray, tySet, tySequence} and not
(t.kind == tyProc and t.callConv == ccClosure) (t.kind == tyProc and t.callConv == ccClosure)
proc useStringh(m: BModule) = proc useStringh(m: BModule) =
@ -264,7 +264,7 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags)
proc isComplexValueType(t: PType): bool {.inline.} = proc isComplexValueType(t: PType): bool {.inline.} =
let t = t.skipTypes(abstractInst) let t = t.skipTypes(abstractInst)
result = t.kind in {tyArray, tyArrayConstr, tySet, tyTuple, tyObject} or result = t.kind in {tyArray, tySet, tyTuple, tyObject} or
(t.kind == tyProc and t.callConv == ccClosure) (t.kind == tyProc and t.callConv == ccClosure)
proc resetLoc(p: BProc, loc: var TLoc) = proc resetLoc(p: BProc, loc: var TLoc) =

View file

@ -61,8 +61,8 @@ proc sameMethodBucket(a, b: PSym): MethodResult =
var aa = a.typ.sons[i] var aa = a.typ.sons[i]
var bb = b.typ.sons[i] var bb = b.typ.sons[i]
while true: while true:
aa = skipTypes(aa, {tyGenericInst}) aa = skipTypes(aa, {tyGenericInst, tyAlias})
bb = skipTypes(bb, {tyGenericInst}) bb = skipTypes(bb, {tyGenericInst, tyAlias})
if aa.kind == bb.kind and aa.kind in {tyVar, tyPtr, tyRef}: if aa.kind == bb.kind and aa.kind in {tyVar, tyPtr, tyRef}:
aa = aa.lastSon aa = aa.lastSon
bb = bb.lastSon bb = bb.lastSon

View file

@ -87,9 +87,9 @@ proc mapType(t: ast.PType): ptr libffi.TType =
of tyFloat, tyFloat64: result = addr libffi.type_double of tyFloat, tyFloat64: result = addr libffi.type_double
of tyFloat32: result = addr libffi.type_float of tyFloat32: result = addr libffi.type_float
of tyVar, tyPointer, tyPtr, tyRef, tyCString, tySequence, tyString, tyExpr, of tyVar, tyPointer, tyPtr, tyRef, tyCString, tySequence, tyString, tyExpr,
tyStmt, tyTypeDesc, tyProc, tyArray, tyArrayConstr, tyStatic, tyNil: tyStmt, tyTypeDesc, tyProc, tyArray, tyStatic, tyNil:
result = addr libffi.type_pointer result = addr libffi.type_pointer
of tyDistinct: of tyDistinct, tyAlias:
result = mapType(t.sons[0]) result = mapType(t.sons[0])
else: else:
result = nil result = nil
@ -117,9 +117,9 @@ proc packSize(v: PNode, typ: PType): int =
result = sizeof(pointer) result = sizeof(pointer)
else: else:
result = sizeof(pointer) + packSize(v.sons[0], typ.lastSon) result = sizeof(pointer) + packSize(v.sons[0], typ.lastSon)
of tyDistinct, tyGenericInst: of tyDistinct, tyGenericInst, tyAlias:
result = packSize(v, typ.sons[0]) result = packSize(v, typ.sons[0])
of tyArray, tyArrayConstr: of tyArray:
# consider: ptr array[0..1000_000, int] which is common for interfacing; # consider: ptr array[0..1000_000, int] which is common for interfacing;
# we use the real length here instead # we use the real length here instead
if v.kind in {nkNilLit, nkPtrLit}: if v.kind in {nkNilLit, nkPtrLit}:
@ -223,7 +223,7 @@ proc pack(v: PNode, typ: PType, res: pointer) =
pack(v.sons[0], typ.lastSon, res +! sizeof(pointer)) pack(v.sons[0], typ.lastSon, res +! sizeof(pointer))
dec packRecCheck dec packRecCheck
awr(pointer, res +! sizeof(pointer)) awr(pointer, res +! sizeof(pointer))
of tyArray, tyArrayConstr: of tyArray:
let baseSize = typ.sons[1].getSize let baseSize = typ.sons[1].getSize
for i in 0 .. <v.len: for i in 0 .. <v.len:
pack(v.sons[i], typ.sons[1], res +! i * baseSize) pack(v.sons[i], typ.sons[1], res +! i * baseSize)
@ -231,7 +231,7 @@ proc pack(v: PNode, typ: PType, res: pointer) =
packObject(v, typ, res) packObject(v, typ, res)
of tyNil: of tyNil:
discard discard
of tyDistinct, tyGenericInst: of tyDistinct, tyGenericInst, tyAlias:
pack(v, typ.sons[0], res) pack(v, typ.sons[0], res)
else: else:
globalError(v.info, "cannot map value to FFI " & typeToString(v.typ)) globalError(v.info, "cannot map value to FFI " & typeToString(v.typ))
@ -378,7 +378,7 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
globalError(n.info, "cannot map value from FFI " & typeToString(typ)) globalError(n.info, "cannot map value from FFI " & typeToString(typ))
of tyObject, tyTuple: of tyObject, tyTuple:
result = unpackObject(x, typ, n) result = unpackObject(x, typ, n)
of tyArray, tyArrayConstr: of tyArray:
result = unpackArray(x, typ, n) result = unpackArray(x, typ, n)
of tyCString, tyString: of tyCString, tyString:
let p = rd(cstring, x) let p = rd(cstring, x)
@ -388,8 +388,8 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
aws(nkStrLit, $p) aws(nkStrLit, $p)
of tyNil: of tyNil:
setNil() setNil()
of tyDistinct, tyGenericInst: of tyDistinct, tyGenericInst, tyAlias:
result = unpack(x, typ.sons[0], n) result = unpack(x, typ.lastSon, n)
else: else:
# XXX what to do with 'array' here? # XXX what to do with 'array' here?
globalError(n.info, "cannot map value from FFI " & typeToString(typ)) globalError(n.info, "cannot map value from FFI " & typeToString(typ))

View file

@ -207,7 +207,7 @@ proc lowBound*(x: PNode): PNode =
proc highBound*(x: PNode): PNode = proc highBound*(x: PNode): PNode =
let typ = x.typ.skipTypes(abstractInst) let typ = x.typ.skipTypes(abstractInst)
result = if typ.kind in {tyArrayConstr, tyArray}: result = if typ.kind == tyArray:
nkIntLit.newIntNode(lastOrd(typ)) nkIntLit.newIntNode(lastOrd(typ))
elif typ.kind == tySequence and x.kind == nkSym and elif typ.kind == tySequence and x.kind == nkSym and
x.sym.kind == skConst: x.sym.kind == skConst:

View file

@ -139,7 +139,7 @@ proc declareGlobal(p: PProc; id: int; r: Rope) =
p.locals.addf("global $1;$n", [r]) p.locals.addf("global $1;$n", [r])
const const
MappedToObject = {tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray, MappedToObject = {tyObject, tyArray, tyTuple, tyOpenArray,
tySet, tyVarargs} tySet, tyVarargs}
proc mapType(typ: PType): TJSTypeKind = proc mapType(typ: PType): TJSTypeKind =
@ -153,18 +153,19 @@ proc mapType(typ: PType): TJSTypeKind =
of tyPointer: of tyPointer:
# treat a tyPointer like a typed pointer to an array of bytes # treat a tyPointer like a typed pointer to an array of bytes
result = etyBaseIndex result = etyBaseIndex
of tyRange, tyDistinct, tyOrdinal, tyProxy: result = mapType(t.sons[0]) of tyRange, tyDistinct, tyOrdinal, tyProxy:
result = mapType(t.sons[0])
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
of tyBool: result = etyBool of tyBool: result = etyBool
of tyFloat..tyFloat128: result = etyFloat of tyFloat..tyFloat128: result = etyFloat
of tySet: result = etyObject # map a set to a table of tySet: result = etyObject # map a set to a table
of tyString, tySequence: result = etySeq of tyString, tySequence: result = etySeq
of tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray, tyVarargs: of tyObject, tyArray, tyTuple, tyOpenArray, tyVarargs:
result = etyObject result = etyObject
of tyNil: result = etyNull of tyNil: result = etyNull
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvocation, of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvocation,
tyNone, tyFromExpr, tyForward, tyEmpty, tyFieldAccessor, tyNone, tyFromExpr, tyForward, tyEmpty, tyFieldAccessor,
tyExpr, tyStmt, tyTypeDesc, tyTypeClasses, tyVoid: tyExpr, tyStmt, tyTypeDesc, tyTypeClasses, tyVoid, tyAlias:
result = etyNone result = etyNone
of tyStatic: of tyStatic:
if t.n != nil: result = mapType(lastSon t) if t.n != nil: result = mapType(lastSon t)
@ -796,8 +797,8 @@ proc generateHeader(p: PProc, typ: PType): Rope =
add(result, name) add(result, name)
add(result, "_Idx") add(result, "_Idx")
elif not (i == 1 and param.name.s == "this"): elif not (i == 1 and param.name.s == "this"):
let k = param.typ.skipTypes({tyGenericInst}).kind let k = param.typ.skipTypes({tyGenericInst, tyAlias}).kind
if k in { tyVar, tyRef, tyPtr, tyPointer }: if k in {tyVar, tyRef, tyPtr, tyPointer}:
add(result, "&") add(result, "&")
add(result, "$") add(result, "$")
add(result, name) add(result, name)
@ -964,7 +965,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
internalAssert a.typ != etyBaseIndex and b.typ != etyBaseIndex internalAssert a.typ != etyBaseIndex and b.typ != etyBaseIndex
r.address = a.res r.address = a.res
var typ = skipTypes(m.sons[0].typ, abstractPtrs) var typ = skipTypes(m.sons[0].typ, abstractPtrs)
if typ.kind in {tyArray, tyArrayConstr}: first = firstOrd(typ.sons[0]) if typ.kind == tyArray: first = firstOrd(typ.sons[0])
else: first = 0 else: first = 0
if optBoundsCheck in p.options and not isConstExpr(m.sons[1]): if optBoundsCheck in p.options and not isConstExpr(m.sons[1]):
useMagic(p, "chckIndx") useMagic(p, "chckIndx")
@ -985,8 +986,7 @@ proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
var ty = skipTypes(n.sons[0].typ, abstractVarRange) var ty = skipTypes(n.sons[0].typ, abstractVarRange)
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange) if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
case ty.kind case ty.kind
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString, of tyArray, tyOpenArray, tySequence, tyString, tyCString, tyVarargs:
tyVarargs:
genArrayAddr(p, n, r) genArrayAddr(p, n, r)
of tyTuple: of tyTuple:
if p.target == targetPHP: if p.target == targetPHP:
@ -1066,8 +1066,7 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
else: else:
let kindOfIndexedExpr = skipTypes(n.sons[0].sons[0].typ, abstractVarRange).kind let kindOfIndexedExpr = skipTypes(n.sons[0].sons[0].typ, abstractVarRange).kind
case kindOfIndexedExpr case kindOfIndexedExpr
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString, of tyArray, tyOpenArray, tySequence, tyString, tyCString, tyVarargs:
tyVarargs:
genArrayAddr(p, n.sons[0], r) genArrayAddr(p, n.sons[0], r)
of tyTuple: of tyTuple:
genFieldAddr(p, n.sons[0], r) genFieldAddr(p, n.sons[0], r)
@ -1387,13 +1386,13 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
result = putToSeq("0", indirect) result = putToSeq("0", indirect)
of tyFloat..tyFloat128: of tyFloat..tyFloat128:
result = putToSeq("0.0", indirect) result = putToSeq("0.0", indirect)
of tyRange, tyGenericInst: of tyRange, tyGenericInst, tyAlias:
result = createVar(p, lastSon(typ), indirect) result = createVar(p, lastSon(typ), indirect)
of tySet: of tySet:
result = putToSeq("{}" | "array()", indirect) result = putToSeq("{}" | "array()", indirect)
of tyBool: of tyBool:
result = putToSeq("false", indirect) result = putToSeq("false", indirect)
of tyArray, tyArrayConstr: of tyArray:
let length = int(lengthOrd(t)) let length = int(lengthOrd(t))
let e = elemType(t) let e = elemType(t)
let jsTyp = arrayTypeForElemType(e) let jsTyp = arrayTypeForElemType(e)

View file

@ -118,7 +118,7 @@ proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
[name, genTypeInfo(p, typ.sons[0])]) [name, genTypeInfo(p, typ.sons[0])])
proc genEnumInfoPHP(p: PProc; t: PType): Rope = proc genEnumInfoPHP(p: PProc; t: PType): Rope =
let t = t.skipTypes({tyGenericInst, tyDistinct}) let t = t.skipTypes({tyGenericInst, tyDistinct, tyAlias})
result = "$$NTI$1" % [rope(t.id)] result = "$$NTI$1" % [rope(t.id)]
p.declareGlobal(t.id, result) p.declareGlobal(t.id, result)
if containsOrIncl(p.g.typeInfoGenerated, t.id): return if containsOrIncl(p.g.typeInfoGenerated, t.id): return
@ -137,7 +137,7 @@ proc genEnumInfoPHP(p: PProc; t: PType): Rope =
proc genTypeInfo(p: PProc, typ: PType): Rope = proc genTypeInfo(p: PProc, typ: PType): Rope =
if p.target == targetPHP: if p.target == targetPHP:
return makeJSString(typeToString(typ, preferModuleInfo)) return makeJSString(typeToString(typ, preferModuleInfo))
let t = typ.skipTypes({tyGenericInst, tyDistinct}) let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias})
result = "NTI$1" % [rope(t.id)] result = "NTI$1" % [rope(t.id)]
if containsOrIncl(p.g.typeInfoGenerated, t.id): return if containsOrIncl(p.g.typeInfoGenerated, t.id): return
case t.kind case t.kind
@ -155,7 +155,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
prepend(p.g.typeInfo, s) prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "$1.base = $2;$n", addf(p.g.typeInfo, "$1.base = $2;$n",
[result, genTypeInfo(p, t.lastSon)]) [result, genTypeInfo(p, t.lastSon)])
of tyArrayConstr, tyArray: of tyArray:
var s = var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" % "var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
[result, rope(ord(t.kind))] [result, rope(ord(t.kind))]

View file

@ -441,7 +441,7 @@ proc newIntLit*(value: BiggestInt): PNode =
result.typ = getSysType(tyInt) result.typ = getSysType(tyInt)
proc genHigh*(n: PNode): PNode = proc genHigh*(n: PNode): PNode =
if skipTypes(n.typ, abstractVar).kind in {tyArrayConstr, tyArray}: if skipTypes(n.typ, abstractVar).kind == tyArray:
result = newIntLit(lastOrd(skipTypes(n.typ, abstractVar))) result = newIntLit(lastOrd(skipTypes(n.typ, abstractVar)))
else: else:
result = newNodeI(nkCall, n.info, 2) result = newNodeI(nkCall, n.info, 2)

View file

@ -287,7 +287,8 @@ proc lsub(n: PNode): int
proc litAux(n: PNode, x: BiggestInt, size: int): string = proc litAux(n: PNode, x: BiggestInt, size: int): string =
proc skip(t: PType): PType = proc skip(t: PType): PType =
result = t result = t
while result.kind in {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal}: while result.kind in {tyGenericInst, tyRange, tyVar, tyDistinct,
tyOrdinal, tyAlias}:
result = lastSon(result) result = lastSon(result)
if n.typ != nil and n.typ.skip.kind in {tyBool, tyEnum}: if n.typ != nil and n.typ.skip.kind in {tyBool, tyEnum}:
let enumfields = n.typ.skip.n let enumfields = n.typ.skip.n

View file

@ -102,8 +102,8 @@ proc commonType*(x, y: PType): PType =
# if expressions, etc.: # if expressions, etc.:
if x == nil: return x if x == nil: return x
if y == nil: return y if y == nil: return y
var a = skipTypes(x, {tyGenericInst}) var a = skipTypes(x, {tyGenericInst, tyAlias})
var b = skipTypes(y, {tyGenericInst}) var b = skipTypes(y, {tyGenericInst, tyAlias})
result = x result = x
if a.kind in {tyExpr, tyNil}: result = y if a.kind in {tyExpr, tyNil}: result = y
elif b.kind in {tyExpr, tyNil}: result = x elif b.kind in {tyExpr, tyNil}: result = x
@ -115,10 +115,10 @@ proc commonType*(x, y: PType): PType =
else: else:
result = newType(tyTypeDesc, a.owner) result = newType(tyTypeDesc, a.owner)
rawAddSon(result, newType(tyNone, a.owner)) rawAddSon(result, newType(tyNone, a.owner))
elif b.kind in {tyArray, tyArrayConstr, tySet, tySequence} and elif b.kind in {tyArray, tySet, tySequence} and
a.kind == b.kind: a.kind == b.kind:
# check for seq[empty] vs. seq[int] # check for seq[empty] vs. seq[int]
let idx = ord(b.kind in {tyArray, tyArrayConstr}) let idx = ord(b.kind == tyArray)
if a.sons[idx].kind == tyEmpty: return y if a.sons[idx].kind == tyEmpty: return y
elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len: elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len:
var nt: PType var nt: PType

View file

@ -187,7 +187,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString, of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString,
tyPtr, tyString, tyRef: tyPtr, tyString, tyRef:
defaultOp(c, t, body, x, y) defaultOp(c, t, body, x, y)
of tyArrayConstr, tyArray, tySequence: of tyArray, tySequence:
if tfHasAsgn in t.flags: if tfHasAsgn in t.flags:
if t.kind == tySequence: if t.kind == tySequence:
# XXX add 'nil' handling here # XXX add 'nil' handling here
@ -227,7 +227,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
tyTypeDesc, tyGenericInvocation, tyForward: tyTypeDesc, tyGenericInvocation, tyForward:
internalError(c.info, "assignment requested for type: " & typeToString(t)) internalError(c.info, "assignment requested for type: " & typeToString(t))
of tyOrdinal, tyRange, of tyOrdinal, tyRange,
tyGenericInst, tyFieldAccessor, tyStatic, tyVar: tyGenericInst, tyFieldAccessor, tyStatic, tyVar, tyAlias:
liftBodyAux(c, lastSon(t), body, x, y) liftBodyAux(c, lastSon(t), body, x, y)
of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("liftBodyAux") of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("liftBodyAux")
@ -276,7 +276,7 @@ proc liftBody(c: PContext; typ: PType; info: TLineInfo): PSym =
#echo "Produced this ", n #echo "Produced this ", n
proc getAsgnOrLiftBody(c: PContext; typ: PType; info: TLineInfo): PSym = proc getAsgnOrLiftBody(c: PContext; typ: PType; info: TLineInfo): PSym =
let t = typ.skipTypes({tyGenericInst, tyVar}) let t = typ.skipTypes({tyGenericInst, tyVar, tyAlias})
result = t.assignment result = t.assignment
if result.isNil: if result.isNil:
result = liftBody(c, t, info) result = liftBody(c, t, info)

View file

@ -370,7 +370,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
proc canDeref(n: PNode): bool {.inline.} = proc canDeref(n: PNode): bool {.inline.} =
result = n.len >= 2 and (let t = n[1].typ; result = n.len >= 2 and (let t = n[1].typ;
t != nil and t.skipTypes({tyGenericInst}).kind in {tyPtr, tyRef}) t != nil and t.skipTypes({tyGenericInst, tyAlias}).kind in {tyPtr, tyRef})
proc tryDeref(n: PNode): PNode = proc tryDeref(n: PNode): PNode =
result = newNodeI(nkHiddenDeref, n.info) result = newNodeI(nkHiddenDeref, n.info)

View file

@ -136,9 +136,9 @@ proc instantiateDestructor(c: PContext, typ: PType): PType =
else: else:
return nil return nil
t = t.skipTypes({tyGenericInst}) t = t.skipTypes({tyGenericInst, tyAlias})
case t.kind case t.kind
of tySequence, tyArray, tyArrayConstr, tyOpenArray, tyVarargs: of tySequence, tyArray, tyOpenArray, tyVarargs:
t.destructor = analyzingDestructor t.destructor = analyzingDestructor
if instantiateDestructor(c, t.sons[0]) != nil: if instantiateDestructor(c, t.sons[0]) != nil:
t.destructor = getCompilerProc"nimDestroyRange" t.destructor = getCompilerProc"nimDestroyRange"

View file

@ -238,7 +238,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
case typ.kind case typ.kind
of tySequence, tyString, tyCString, tyOpenArray, tyVarargs: of tySequence, tyString, tyCString, tyOpenArray, tyVarargs:
n.typ = getSysType(tyInt) n.typ = getSysType(tyInt)
of tyArrayConstr, tyArray: of tyArray:
n.typ = typ.sons[0] # indextype n.typ = typ.sons[0] # indextype
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32: of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
# do not skip the range! # do not skip the range!
@ -373,7 +373,7 @@ proc changeType(n: PNode, newType: PType, check: bool) =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
changeType(n.sons[i], elemType(newType), check) changeType(n.sons[i], elemType(newType), check)
of nkPar: of nkPar:
let tup = newType.skipTypes({tyGenericInst}) let tup = newType.skipTypes({tyGenericInst, tyAlias})
if tup.kind != tyTuple: if tup.kind != tyTuple:
if tup.kind == tyObject: return if tup.kind == tyObject: return
globalError(n.info, "no tuple type for constructor") globalError(n.info, "no tuple type for constructor")
@ -416,7 +416,7 @@ proc arrayConstrType(c: PContext, n: PNode): PType =
if sonsLen(n) == 0: if sonsLen(n) == 0:
rawAddSon(typ, newTypeS(tyEmpty, c)) # needs an empty basetype! rawAddSon(typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
else: else:
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyOrdinal}) var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyOrdinal, tyAlias})
addSonSkipIntLit(typ, t) addSonSkipIntLit(typ, t)
typ.sons[0] = makeRangeType(c, 0, sonsLen(n) - 1, n.info) typ.sons[0] = makeRangeType(c, 0, sonsLen(n) - 1, n.info)
result = typ result = typ
@ -522,7 +522,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
# get the real type of the callee # get the real type of the callee
# it may be a proc var with a generic alias type, so we skip over them # it may be a proc var with a generic alias type, so we skip over them
var t = n.sons[0].typ.skipTypes({tyGenericInst}) var t = n.sons[0].typ.skipTypes({tyGenericInst, tyAlias})
if n.sons[0].kind == nkSym and n.sons[0].sym.magic in FakeVarParams: if n.sons[0].kind == nkSym and n.sons[0].sym.magic in FakeVarParams:
# BUGFIX: check for L-Value still needs to be done for the arguments! # BUGFIX: check for L-Value still needs to be done for the arguments!
@ -888,18 +888,18 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
else: illFormedAst(n) else: illFormedAst(n)
proc makeDeref(n: PNode): PNode = proc makeDeref(n: PNode): PNode =
var t = skipTypes(n.typ, {tyGenericInst}) var t = skipTypes(n.typ, {tyGenericInst, tyAlias})
result = n result = n
if t.kind == tyVar: if t.kind == tyVar:
result = newNodeIT(nkHiddenDeref, n.info, t.sons[0]) result = newNodeIT(nkHiddenDeref, n.info, t.sons[0])
addSon(result, n) addSon(result, n)
t = skipTypes(t.sons[0], {tyGenericInst}) t = skipTypes(t.sons[0], {tyGenericInst, tyAlias})
while t.kind in {tyPtr, tyRef}: while t.kind in {tyPtr, tyRef}:
var a = result var a = result
let baseTyp = t.lastSon let baseTyp = t.lastSon
result = newNodeIT(nkHiddenDeref, n.info, baseTyp) result = newNodeIT(nkHiddenDeref, n.info, baseTyp)
addSon(result, a) addSon(result, a)
t = skipTypes(baseTyp, {tyGenericInst}) t = skipTypes(baseTyp, {tyGenericInst, tyAlias})
const const
tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass} tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
@ -1013,7 +1013,8 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
while p != nil and p.selfSym == nil: while p != nil and p.selfSym == nil:
p = p.next p = p.next
if p != nil and p.selfSym != nil: if p != nil and p.selfSym != nil:
var ty = skipTypes(p.selfSym.typ, {tyGenericInst, tyVar, tyPtr, tyRef}) var ty = skipTypes(p.selfSym.typ, {tyGenericInst, tyVar, tyPtr, tyRef,
tyAlias})
while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct}) while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct})
var check: PNode = nil var check: PNode = nil
if ty.kind == tyObject: if ty.kind == tyObject:
@ -1103,7 +1104,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
# reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim": # reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim":
ty = n.sons[0].typ ty = n.sons[0].typ
return nil return nil
ty = skipTypes(ty, {tyGenericInst, tyVar, tyPtr, tyRef}) ty = skipTypes(ty, {tyGenericInst, tyVar, tyPtr, tyRef, tyAlias})
while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct}) while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct})
var check: PNode = nil var check: PNode = nil
if ty.kind == tyObject: if ty.kind == tyObject:
@ -1171,7 +1172,7 @@ proc semDeref(c: PContext, n: PNode): PNode =
checkSonsLen(n, 1) checkSonsLen(n, 1)
n.sons[0] = semExprWithType(c, n.sons[0]) n.sons[0] = semExprWithType(c, n.sons[0])
result = n result = n
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar}) var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyAlias})
case t.kind case t.kind
of tyRef, tyPtr: n.typ = t.lastSon of tyRef, tyPtr: n.typ = t.lastSon
else: result = nil else: result = nil
@ -1190,9 +1191,10 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
# make sure we don't evaluate generic macros/templates # make sure we don't evaluate generic macros/templates
n.sons[0] = semExprWithType(c, n.sons[0], n.sons[0] = semExprWithType(c, n.sons[0],
{efNoProcvarCheck, efNoEvaluateGeneric}) {efNoProcvarCheck, efNoEvaluateGeneric})
let arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef}) let arr = skipTypes(n.sons[0].typ, {tyGenericInst,
tyVar, tyPtr, tyRef, tyAlias})
case arr.kind case arr.kind
of tyArray, tyOpenArray, tyVarargs, tyArrayConstr, tySequence, tyString, of tyArray, tyOpenArray, tyVarargs, tySequence, tyString,
tyCString: tyCString:
if n.len != 2: return nil if n.len != 2: return nil
n.sons[0] = makeDeref(n.sons[0]) n.sons[0] = makeDeref(n.sons[0])
@ -1220,7 +1222,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
c.p.bracketExpr = n.sons[0] c.p.bracketExpr = n.sons[0]
# [] operator for tuples requires constant expression: # [] operator for tuples requires constant expression:
n.sons[1] = semConstExpr(c, n.sons[1]) n.sons[1] = semConstExpr(c, n.sons[1])
if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal}).kind in if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal, tyAlias}).kind in
{tyInt..tyInt64}: {tyInt..tyInt64}:
var idx = getOrdValue(n.sons[1]) var idx = getOrdValue(n.sons[1])
if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)] if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)]
@ -1364,7 +1366,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
# a = b # both are vars, means: a[] = b[] # a = b # both are vars, means: a[] = b[]
# a = b # b no 'var T' means: a = addr(b) # a = b # b no 'var T' means: a = addr(b)
var le = a.typ var le = a.typ
if (skipTypes(le, {tyGenericInst}).kind != tyVar and if (skipTypes(le, {tyGenericInst, tyAlias}).kind != tyVar and
isAssignable(c, a) == arNone) or isAssignable(c, a) == arNone) or
skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}: skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}:
# Direct assignment to a discriminant is allowed! # Direct assignment to a discriminant is allowed!
@ -1456,13 +1458,13 @@ proc semProcBody(c: PContext, n: PNode): PNode =
closeScope(c) closeScope(c)
proc semYieldVarResult(c: PContext, n: PNode, restype: PType) = proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
var t = skipTypes(restype, {tyGenericInst}) var t = skipTypes(restype, {tyGenericInst, tyAlias})
case t.kind case t.kind
of tyVar: of tyVar:
n.sons[0] = takeImplicitAddr(c, n.sons[0]) n.sons[0] = takeImplicitAddr(c, n.sons[0])
of tyTuple: of tyTuple:
for i in 0.. <t.sonsLen: for i in 0.. <t.sonsLen:
var e = skipTypes(t.sons[i], {tyGenericInst}) var e = skipTypes(t.sons[i], {tyGenericInst, tyAlias})
if e.kind == tyVar: if e.kind == tyVar:
if n.sons[0].kind == nkPar: if n.sons[0].kind == nkPar:
n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i]) n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i])
@ -1904,17 +1906,17 @@ proc semSetConstr(c: PContext, n: PNode): PNode =
n.sons[i].sons[2] = semExprWithType(c, n.sons[i].sons[2]) n.sons[i].sons[2] = semExprWithType(c, n.sons[i].sons[2])
if typ == nil: if typ == nil:
typ = skipTypes(n.sons[i].sons[1].typ, typ = skipTypes(n.sons[i].sons[1].typ,
{tyGenericInst, tyVar, tyOrdinal}) {tyGenericInst, tyVar, tyOrdinal, tyAlias})
n.sons[i].typ = n.sons[i].sons[2].typ # range node needs type too n.sons[i].typ = n.sons[i].sons[2].typ # range node needs type too
elif n.sons[i].kind == nkRange: elif n.sons[i].kind == nkRange:
# already semchecked # already semchecked
if typ == nil: if typ == nil:
typ = skipTypes(n.sons[i].sons[0].typ, typ = skipTypes(n.sons[i].sons[0].typ,
{tyGenericInst, tyVar, tyOrdinal}) {tyGenericInst, tyVar, tyOrdinal, tyAlias})
else: else:
n.sons[i] = semExprWithType(c, n.sons[i]) n.sons[i] = semExprWithType(c, n.sons[i])
if typ == nil: if typ == nil:
typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyOrdinal}) typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyOrdinal, tyAlias})
if not isOrdinalType(typ): if not isOrdinalType(typ):
localError(n.info, errOrdinalTypeExpected) localError(n.info, errOrdinalTypeExpected)
typ = makeRangeType(c, 0, MaxSetElements-1, n.info) typ = makeRangeType(c, 0, MaxSetElements-1, n.info)
@ -2046,8 +2048,8 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
result = n result = n
result.typ = t result.typ = t
result.kind = nkObjConstr result.kind = nkObjConstr
t = skipTypes(t, {tyGenericInst}) t = skipTypes(t, {tyGenericInst, tyAlias})
if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst}) if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias})
if t.kind != tyObject: if t.kind != tyObject:
localError(n.info, errGenerated, "object constructor needs an object type") localError(n.info, errGenerated, "object constructor needs an object type")
return return

View file

@ -538,7 +538,8 @@ proc getArrayConstr(m: PSym, n: PNode): PNode =
proc foldArrayAccess(m: PSym, n: PNode): PNode = proc foldArrayAccess(m: PSym, n: PNode): PNode =
var x = getConstExpr(m, n.sons[0]) var x = getConstExpr(m, n.sons[0])
if x == nil or x.typ.skipTypes({tyGenericInst}).kind == tyTypeDesc: return if x == nil or x.typ.skipTypes({tyGenericInst, tyAlias}).kind == tyTypeDesc:
return
var y = getConstExpr(m, n.sons[1]) var y = getConstExpr(m, n.sons[1])
if y == nil: return if y == nil: return

View file

@ -61,7 +61,7 @@ proc annotateType*(n: PNode, t: PType) =
else: else:
globalError(n.info, "() must have a tuple type") globalError(n.info, "() must have a tuple type")
of nkBracket: of nkBracket:
if x.kind in {tyArrayConstr, tyArray, tySequence, tyOpenArray}: if x.kind in {tyArray, tySequence, tyOpenArray}:
n.typ = t n.typ = t
for m in n: annotateType(m, x.elemType) for m in n: annotateType(m, x.elemType)
else: else:

View file

@ -471,7 +471,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
# this can only happen for errornous var statements: # this can only happen for errornous var statements:
if typ == nil: continue if typ == nil: continue
typeAllowedCheck(a.info, typ, symkind) typeAllowedCheck(a.info, typ, symkind)
var tup = skipTypes(typ, {tyGenericInst}) var tup = skipTypes(typ, {tyGenericInst, tyAlias})
if a.kind == nkVarTuple: if a.kind == nkVarTuple:
if tup.kind != tyTuple: if tup.kind != tyTuple:
localError(a.info, errXExpected, "tuple") localError(a.info, errXExpected, "tuple")
@ -583,7 +583,7 @@ proc semForVars(c: PContext, n: PNode): PNode =
result = n result = n
var length = sonsLen(n) var length = sonsLen(n)
let iterBase = n.sons[length-2].typ let iterBase = n.sons[length-2].typ
var iter = skipTypes(iterBase, {tyGenericInst}) var iter = skipTypes(iterBase, {tyGenericInst, tyAlias})
# length == 3 means that there is one for loop variable # length == 3 means that there is one for loop variable
# and thus no tuple unpacking: # and thus no tuple unpacking:
if iter.kind != tyTuple or length == 3: if iter.kind != tyTuple or length == 3:
@ -777,7 +777,7 @@ proc checkForMetaFields(n: PNode) =
let t = n.sym.typ let t = n.sym.typ
case t.kind case t.kind
of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyPtr, tyRef, of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyPtr, tyRef,
tyProc, tyGenericInvocation, tyGenericInst: tyProc, tyGenericInvocation, tyGenericInst, tyAlias:
let start = ord(t.kind in {tyGenericInvocation, tyGenericInst}) let start = ord(t.kind in {tyGenericInvocation, tyGenericInst})
for i in start .. <t.sons.len: for i in start .. <t.sons.len:
checkMeta(t.sons[i]) checkMeta(t.sons[i])
@ -1366,7 +1366,9 @@ proc semMethod(c: PContext, n: PNode): PNode =
for col in countup(1, sonsLen(tt)-1): for col in countup(1, sonsLen(tt)-1):
let t = tt.sons[col] let t = tt.sons[col]
if t != nil and t.kind == tyGenericInvocation: if t != nil and t.kind == tyGenericInvocation:
var x = skipTypes(t.sons[0], {tyVar, tyPtr, tyRef, tyGenericInst, tyGenericInvocation, tyGenericBody}) var x = skipTypes(t.sons[0], {tyVar, tyPtr, tyRef, tyGenericInst,
tyGenericInvocation, tyGenericBody,
tyAlias})
if x.kind == tyObject and t.len-1 == result.sons[genericParamsPos].len: if x.kind == tyObject and t.len-1 == result.sons[genericParamsPos].len:
foundObj = true foundObj = true
x.methods.safeAdd((col,s)) x.methods.safeAdd((col,s))

View file

@ -95,7 +95,7 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType =
if sonsLen(n) == 2: if sonsLen(n) == 2:
var base = semTypeNode(c, n.sons[1], nil) var base = semTypeNode(c, n.sons[1], nil)
addSonSkipIntLit(result, base) addSonSkipIntLit(result, base)
if base.kind == tyGenericInst: base = lastSon(base) if base.kind in {tyGenericInst, tyAlias}: base = lastSon(base)
if base.kind != tyGenericParam: if base.kind != tyGenericParam:
if not isOrdinalType(base): if not isOrdinalType(base):
localError(n.info, errOrdinalTypeExpected) localError(n.info, errOrdinalTypeExpected)
@ -145,7 +145,8 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
isNilable = true isNilable = true
else: else:
let region = semTypeNode(c, ni, nil) let region = semTypeNode(c, ni, nil)
if region.skipTypes({tyGenericInst}).kind notin {tyError, tyObject}: if region.skipTypes({tyGenericInst, tyAlias}).kind notin {
tyError, tyObject}:
message n[i].info, errGenerated, "region needs to be an object type" message n[i].info, errGenerated, "region needs to be an object type"
addSonSkipIntLit(result, region) addSonSkipIntLit(result, region)
addSonSkipIntLit(result, base) addSonSkipIntLit(result, base)
@ -266,7 +267,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
# 3 = length(array indx base) # 3 = length(array indx base)
let indx = semArrayIndex(c, n[1]) let indx = semArrayIndex(c, n[1])
var indxB = indx var indxB = indx
if indxB.kind == tyGenericInst: indxB = lastSon(indxB) if indxB.kind in {tyGenericInst, tyAlias}: indxB = lastSon(indxB)
if indxB.kind notin {tyGenericParam, tyStatic, tyFromExpr}: if indxB.kind notin {tyGenericParam, tyStatic, tyFromExpr}:
if not isOrdinalType(indxB): if not isOrdinalType(indxB):
localError(n.sons[1].info, errOrdinalTypeExpected) localError(n.sons[1].info, errOrdinalTypeExpected)
@ -647,7 +648,7 @@ proc skipGenericInvocation(t: PType): PType {.inline.} =
result = t result = t
if result.kind == tyGenericInvocation: if result.kind == tyGenericInvocation:
result = result.sons[0] result = result.sons[0]
while result.kind in {tyGenericInst, tyGenericBody, tyRef, tyPtr}: while result.kind in {tyGenericInst, tyGenericBody, tyRef, tyPtr, tyAlias}:
result = lastSon(result) result = lastSon(result)
proc addInheritedFields(c: PContext, check: var IntSet, pos: var int, proc addInheritedFields(c: PContext, check: var IntSet, pos: var int,
@ -950,7 +951,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
if isType: localError(a.info, "':' expected") if isType: localError(a.info, "':' expected")
if kind in {skTemplate, skMacro}: if kind in {skTemplate, skMacro}:
typ = newTypeS(tyExpr, c) typ = newTypeS(tyExpr, c)
elif skipTypes(typ, {tyGenericInst}).kind == tyVoid: elif skipTypes(typ, {tyGenericInst, tyAlias}).kind == tyVoid:
continue continue
for j in countup(0, length-3): for j in countup(0, length-3):
var arg = newSymG(skParam, a.sons[j], c) var arg = newSymG(skParam, a.sons[j], c)
@ -982,7 +983,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
if r != nil: if r != nil:
# turn explicit 'void' return type into 'nil' because the rest of the # turn explicit 'void' return type into 'nil' because the rest of the
# compiler only checks for 'nil': # compiler only checks for 'nil':
if skipTypes(r, {tyGenericInst}).kind != tyVoid: if skipTypes(r, {tyGenericInst, tyAlias}).kind != tyVoid:
# 'auto' as a return type does not imply a generic: # 'auto' as a return type does not imply a generic:
if r.kind == tyAnything: if r.kind == tyAnything:
# 'p(): auto' and 'p(): expr' are equivalent, but the rest of the # 'p(): auto' and 'p(): expr' are equivalent, but the rest of the
@ -1180,7 +1181,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result = semRangeAux(c, n, prev) result = semRangeAux(c, n, prev)
elif n[0].kind == nkNilLit and n.len == 2: elif n[0].kind == nkNilLit and n.len == 2:
result = semTypeNode(c, n.sons[1], prev) result = semTypeNode(c, n.sons[1], prev)
if result.skipTypes({tyGenericInst}).kind in NilableTypes+GenericTypes: if result.skipTypes({tyGenericInst, tyAlias}).kind in NilableTypes+GenericTypes:
if tfNotNil in result.flags: if tfNotNil in result.flags:
result = freshType(result, prev) result = freshType(result, prev)
result.flags.excl(tfNotNil) result.flags.excl(tfNotNil)
@ -1208,7 +1209,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
case n.len case n.len
of 3: of 3:
result = semTypeNode(c, n.sons[1], prev) result = semTypeNode(c, n.sons[1], prev)
if result.skipTypes({tyGenericInst}).kind in NilableTypes+GenericTypes and if result.skipTypes({tyGenericInst, tyAlias}).kind in NilableTypes+GenericTypes and
n.sons[2].kind == nkNilLit: n.sons[2].kind == nkNilLit:
result = freshType(result, prev) result = freshType(result, prev)
result.flags.incl(tfNotNil) result.flags.incl(tfNotNil)

View file

@ -459,7 +459,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
var r = replaceTypeVarsT(cl, result.sons[i]) var r = replaceTypeVarsT(cl, result.sons[i])
if result.kind == tyObject: if result.kind == tyObject:
# carefully coded to not skip the precious tyGenericInst: # carefully coded to not skip the precious tyGenericInst:
let r2 = r.skipTypes({tyGenericInst}) let r2 = r.skipTypes({tyGenericInst, tyAlias})
if r2.kind in {tyPtr, tyRef}: if r2.kind in {tyPtr, tyRef}:
r = skipTypes(r2, {tyPtr, tyRef}) r = skipTypes(r2, {tyPtr, tyRef})
result.sons[i] = r result.sons[i] = r

View file

@ -159,7 +159,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
c.hashSym(t.sym) c.hashSym(t.sym)
else: else:
lowlevel(t.id) lowlevel(t.id)
of tyRef, tyPtr, tyGenericBody: of tyRef, tyPtr, tyGenericBody, tyAlias:
c.hashType t.lastSon, flags c.hashType t.lastSon, flags
of tyUserTypeClass: of tyUserTypeClass:
if t.sym != nil and t.sym.owner != nil: if t.sym != nil and t.sym.owner != nil:

View file

@ -158,7 +158,7 @@ proc sumGeneric(t: PType): int =
var isvar = 1 var isvar = 1
while true: while true:
case t.kind case t.kind
of tyGenericInst, tyArray, tyRef, tyPtr, tyDistinct, tyArrayConstr, of tyGenericInst, tyArray, tyRef, tyPtr, tyDistinct,
tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyGenericBody: tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyGenericBody:
t = t.lastSon t = t.lastSon
inc result inc result
@ -175,6 +175,7 @@ proc sumGeneric(t: PType): int =
for i in 0 .. <t.len: result += t.sons[i].sumGeneric for i in 0 .. <t.len: result += t.sons[i].sumGeneric
break break
of tyGenericParam, tyExpr, tyStatic, tyStmt: break of tyGenericParam, tyExpr, tyStatic, tyStmt: break
of tyAlias: t = t.lastSon
of tyBool, tyChar, tyEnum, tyObject, tyPointer, of tyBool, tyChar, tyEnum, tyObject, tyPointer,
tyString, tyCString, tyInt..tyInt64, tyFloat..tyFloat128, tyString, tyCString, tyInt..tyInt64, tyFloat..tyFloat128,
tyUInt..tyUInt64: tyUInt..tyUInt64:
@ -273,11 +274,6 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1;
proc typeRel*(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation proc typeRel*(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation
proc concreteType(c: TCandidate, t: PType): PType = proc concreteType(c: TCandidate, t: PType): PType =
case t.kind case t.kind
of tyArrayConstr:
# make it an array
result = newType(tyArray, t.owner)
addSonSkipIntLit(result, t.sons[0]) # XXX: t.owner is wrong for ID!
addSonSkipIntLit(result, t.sons[1]) # XXX: semantic checking for the type?
of tyNil: of tyNil:
result = nil # what should it be? result = nil # what should it be?
of tyTypeDesc: of tyTypeDesc:
@ -394,7 +390,7 @@ proc skipToObject(t: PType; skipped: var SkippedPtr): PType =
inc ptrs inc ptrs
skipped = skippedPtr skipped = skippedPtr
r = r.lastSon r = r.lastSon
of tyGenericBody, tyGenericInst: of tyGenericBody, tyGenericInst, tyAlias:
r = r.lastSon r = r.lastSon
else: else:
break break
@ -692,7 +688,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
# for example, but unfortunately `prepareOperand` is not called in certain # for example, but unfortunately `prepareOperand` is not called in certain
# situation when nkDotExpr are rotated to nkDotCalls # situation when nkDotExpr are rotated to nkDotCalls
if a.kind == tyGenericInst and if a.kind in {tyGenericInst, tyAlias} and
skipTypes(f, {tyVar}).kind notin { skipTypes(f, {tyVar}).kind notin {
tyGenericBody, tyGenericInvocation, tyGenericBody, tyGenericInvocation,
tyGenericInst, tyGenericParam} + tyTypeClasses: tyGenericInst, tyGenericParam} + tyTypeClasses:
@ -799,11 +795,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
if aOrig.kind == tyVar: result = typeRel(c, f.base, aOrig.base) if aOrig.kind == tyVar: result = typeRel(c, f.base, aOrig.base)
else: result = typeRel(c, f.base, aOrig) else: result = typeRel(c, f.base, aOrig)
subtypeCheck() subtypeCheck()
of tyArray, tyArrayConstr: of tyArray:
# tyArrayConstr cannot happen really, but
# we wanna be safe here
case a.kind case a.kind
of tyArray, tyArrayConstr: of tyArray:
var fRange = f.sons[0] var fRange = f.sons[0]
if fRange.kind == tyGenericParam: if fRange.kind == tyGenericParam:
var prev = PType(idTableGet(c.bindings, fRange)) var prev = PType(idTableGet(c.bindings, fRange))
@ -848,7 +842,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
of tyOpenArray, tyVarargs: of tyOpenArray, tyVarargs:
result = typeRel(c, base(f), base(a)) result = typeRel(c, base(f), base(a))
if result < isGeneric: result = isNone if result < isGeneric: result = isNone
of tyArray, tyArrayConstr: of tyArray:
if (f.sons[0].kind != tyGenericParam) and (a.sons[1].kind == tyEmpty): if (f.sons[0].kind != tyGenericParam) and (a.sons[1].kind == tyEmpty):
result = isSubtype result = isSubtype
elif typeRel(c, base(f), a.sons[1]) >= isGeneric: elif typeRel(c, base(f), a.sons[1]) >= isGeneric:
@ -984,7 +978,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
of tyEmpty, tyVoid: of tyEmpty, tyVoid:
if a.kind == f.kind: result = isEqual if a.kind == f.kind: result = isEqual
of tyGenericInst: of tyGenericInst, tyAlias:
result = typeRel(c, lastSon(f), a) result = typeRel(c, lastSon(f), a)
of tyGenericBody: of tyGenericBody:
@ -1090,7 +1084,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
of tyBuiltInTypeClass: of tyBuiltInTypeClass:
considerPreviousT: considerPreviousT:
let targetKind = f.sons[0].kind let targetKind = f.sons[0].kind
if targetKind == a.skipTypes({tyRange, tyGenericInst, tyBuiltInTypeClass}).kind or if targetKind == a.skipTypes({tyRange, tyGenericInst, tyBuiltInTypeClass, tyAlias}).kind or
(targetKind in {tyProc, tyPointer} and a.kind == tyNil): (targetKind in {tyProc, tyPointer} and a.kind == tyNil):
put(c, f, a) put(c, f, a)
return isGeneric return isGeneric

View file

@ -201,7 +201,7 @@ proc typeFits(c: PContext, s: PSym, firstArg: PType): bool {.inline.} =
let m = s.getModule() let m = s.getModule()
if m != nil and sfSystemModule in m.flags: if m != nil and sfSystemModule in m.flags:
if s.kind == skType: return if s.kind == skType: return
var exp = s.typ.sons[1].skipTypes({tyGenericInst, tyVar}) var exp = s.typ.sons[1].skipTypes({tyGenericInst, tyVar, tyAlias})
if exp.kind == tyVarargs: exp = elemType(exp) if exp.kind == tyVarargs: exp = elemType(exp)
if exp.kind in {tyExpr, tyStmt, tyGenericParam, tyAnything}: return if exp.kind in {tyExpr, tyStmt, tyGenericParam, tyAnything}: return
result = sigmatch.argtypeMatches(c, s.typ.sons[1], firstArg) result = sigmatch.argtypeMatches(c, s.typ.sons[1], firstArg)
@ -267,7 +267,7 @@ proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) =
t = t.sons[0] t = t.sons[0]
suggestOperations(c, n, typ, outputs) suggestOperations(c, n, typ, outputs)
else: else:
typ = skipTypes(typ, {tyGenericInst, tyVar, tyPtr, tyRef}) typ = skipTypes(typ, {tyGenericInst, tyVar, tyPtr, tyRef, tyAlias})
if typ.kind == tyObject: if typ.kind == tyObject:
var t = typ var t = typ
while true: while true:

View file

@ -95,7 +95,7 @@ proc getCurrOwner(c: PTransf): PSym =
proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PNode = proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PNode =
let r = newSym(skTemp, getIdent(genPrefix), getCurrOwner(c), info) let r = newSym(skTemp, getIdent(genPrefix), getCurrOwner(c), info)
r.typ = typ #skipTypes(typ, {tyGenericInst}) r.typ = typ #skipTypes(typ, {tyGenericInst, tyAlias})
incl(r.flags, sfFromGeneric) incl(r.flags, sfFromGeneric)
let owner = getCurrOwner(c) let owner = getCurrOwner(c)
if owner.isIterator and not c.tooEarly: if owner.isIterator and not c.tooEarly:
@ -326,7 +326,7 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
# c.transCon.forStmt.len == 3 means that there is one for loop variable # c.transCon.forStmt.len == 3 means that there is one for loop variable
# and thus no tuple unpacking: # and thus no tuple unpacking:
if e.typ.isNil: return result # can happen in nimsuggest for unknown reasons if e.typ.isNil: return result # can happen in nimsuggest for unknown reasons
if skipTypes(e.typ, {tyGenericInst}).kind == tyTuple and if skipTypes(e.typ, {tyGenericInst, tyAlias}).kind == tyTuple and
c.transCon.forStmt.len != 3: c.transCon.forStmt.len != 3:
e = skipConv(e) e = skipConv(e)
if e.kind == nkPar: if e.kind == nkPar:

View file

@ -101,7 +101,7 @@ proc isDeepConstExpr*(n: PNode): bool =
if not isDeepConstExpr(n.sons[i]): return false if not isDeepConstExpr(n.sons[i]): return false
if n.typ.isNil: result = true if n.typ.isNil: result = true
else: else:
let t = n.typ.skipTypes({tyGenericInst, tyDistinct}) let t = n.typ.skipTypes({tyGenericInst, tyDistinct, tyAlias})
if t.kind in {tyRef, tyPtr}: return false if t.kind in {tyRef, tyPtr}: return false
if t.kind != tyObject or not isCaseObj(t.n): if t.kind != tyObject or not isCaseObj(t.n):
result = true result = true

View file

@ -54,14 +54,16 @@ const
# TODO: Remove tyTypeDesc from each abstractX and (where necessary) # TODO: Remove tyTypeDesc from each abstractX and (where necessary)
# replace with typedescX # replace with typedescX
abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal, abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal,
tyTypeDesc} tyTypeDesc, tyAlias}
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc} abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc,
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal, tyTypeDesc} tyAlias}
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal, tyTypeDesc,
tyAlias}
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal, abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
tyTypeDesc} tyTypeDesc, tyAlias}
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc} abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias}
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyTypeDesc} skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyTypeDesc, tyAlias}
# typedescX is used if we're sure tyTypeDesc should be included (or skipped) # typedescX is used if we're sure tyTypeDesc should be included (or skipped)
typedescPtrs* = abstractPtrs + {tyTypeDesc} typedescPtrs* = abstractPtrs + {tyTypeDesc}
typedescInst* = abstractInst + {tyTypeDesc} typedescInst* = abstractInst + {tyTypeDesc}
@ -115,7 +117,7 @@ proc isFloatLit*(t: PType): bool {.inline.} =
proc isCompatibleToCString(a: PType): bool = proc isCompatibleToCString(a: PType): bool =
if a.kind == tyArray: if a.kind == tyArray:
if (firstOrd(a.sons[0]) == 0) and if (firstOrd(a.sons[0]) == 0) and
(skipTypes(a.sons[0], {tyRange, tyGenericInst}).kind in (skipTypes(a.sons[0], {tyRange, tyGenericInst, tyAlias}).kind in
{tyInt..tyInt64, tyUInt..tyUInt64}) and {tyInt..tyInt64, tyUInt..tyUInt64}) and
(a.sons[1].kind == tyChar): (a.sons[1].kind == tyChar):
result = true result = true
@ -139,8 +141,8 @@ proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string =
proc elemType*(t: PType): PType = proc elemType*(t: PType): PType =
assert(t != nil) assert(t != nil)
case t.kind case t.kind
of tyGenericInst, tyDistinct: result = elemType(lastSon(t)) of tyGenericInst, tyDistinct, tyAlias: result = elemType(lastSon(t))
of tyArray, tyArrayConstr: result = t.sons[1] of tyArray: result = t.sons[1]
else: result = t.lastSon else: result = t.lastSon
assert(result != nil) assert(result != nil)
@ -149,12 +151,12 @@ proc isOrdinalType(t: PType): bool =
const const
# caution: uint, uint64 are no ordinal types! # caution: uint, uint64 are no ordinal types!
baseKinds = {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum} baseKinds = {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum}
parentKinds = {tyRange, tyOrdinal, tyGenericInst, tyDistinct} parentKinds = {tyRange, tyOrdinal, tyGenericInst, tyAlias, tyDistinct}
t.kind in baseKinds or (t.kind in parentKinds and isOrdinalType(t.sons[0])) t.kind in baseKinds or (t.kind in parentKinds and isOrdinalType(t.sons[0]))
proc enumHasHoles(t: PType): bool = proc enumHasHoles(t: PType): bool =
var b = t var b = t
while b.kind in {tyRange, tyGenericInst}: b = b.sons[0] while b.kind in {tyRange, tyGenericInst, tyAlias}: b = b.sons[0]
result = b.kind == tyEnum and tfEnumHasHoles in b.flags result = b.kind == tyEnum and tfEnumHasHoles in b.flags
proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter, proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
@ -179,7 +181,7 @@ proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
if result: return if result: return
if not containsOrIncl(marker, t.id): if not containsOrIncl(marker, t.id):
case t.kind case t.kind
of tyGenericInst, tyGenericBody: of tyGenericInst, tyGenericBody, tyAlias:
result = iterOverTypeAux(marker, lastSon(t), iter, closure) result = iterOverTypeAux(marker, lastSon(t), iter, closure)
else: else:
for i in countup(0, sonsLen(t) - 1): for i in countup(0, sonsLen(t) - 1):
@ -229,9 +231,9 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate,
if t.sons[0] != nil: if t.sons[0] != nil:
result = searchTypeForAux(t.sons[0].skipTypes(skipPtrs), predicate, marker) result = searchTypeForAux(t.sons[0].skipTypes(skipPtrs), predicate, marker)
if not result: result = searchTypeNodeForAux(t.n, predicate, marker) if not result: result = searchTypeNodeForAux(t.n, predicate, marker)
of tyGenericInst, tyDistinct: of tyGenericInst, tyDistinct, tyAlias:
result = searchTypeForAux(lastSon(t), predicate, marker) result = searchTypeForAux(lastSon(t), predicate, marker)
of tyArray, tyArrayConstr, tySet, tyTuple: of tyArray, tySet, tyTuple:
for i in countup(0, sonsLen(t) - 1): for i in countup(0, sonsLen(t) - 1):
result = searchTypeForAux(t.sons[i], predicate, marker) result = searchTypeForAux(t.sons[i], predicate, marker)
if result: return if result: return
@ -272,9 +274,9 @@ proc analyseObjectWithTypeFieldAux(t: PType,
if res == frHeader: result = frHeader if res == frHeader: result = frHeader
if result == frNone: if result == frNone:
if isObjectWithTypeFieldPredicate(t): result = frHeader if isObjectWithTypeFieldPredicate(t): result = frHeader
of tyGenericInst, tyDistinct: of tyGenericInst, tyDistinct, tyAlias:
result = analyseObjectWithTypeFieldAux(lastSon(t), marker) result = analyseObjectWithTypeFieldAux(lastSon(t), marker)
of tyArray, tyArrayConstr, tyTuple: of tyArray, tyTuple:
for i in countup(0, sonsLen(t) - 1): for i in countup(0, sonsLen(t) - 1):
res = analyseObjectWithTypeFieldAux(t.sons[i], marker) res = analyseObjectWithTypeFieldAux(t.sons[i], marker)
if res != frNone: if res != frNone:
@ -331,8 +333,7 @@ proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool =
var t = skipTypes(typ, abstractInst-{tyTypeDesc}) var t = skipTypes(typ, abstractInst-{tyTypeDesc})
if tfAcyclic in t.flags: return if tfAcyclic in t.flags: return
case t.kind case t.kind
of tyTuple, tyObject, tyRef, tySequence, tyArray, tyArrayConstr, tyOpenArray, of tyTuple, tyObject, tyRef, tySequence, tyArray, tyOpenArray, tyVarargs:
tyVarargs:
if not containsOrIncl(marker, t.id): if not containsOrIncl(marker, t.id):
for i in countup(0, sonsLen(t) - 1): for i in countup(0, sonsLen(t) - 1):
result = canFormAcycleAux(marker, t.sons[i], startId) result = canFormAcycleAux(marker, t.sons[i], startId)
@ -499,9 +500,6 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
else: else:
result = "array[" & typeToString(t.sons[0]) & ", " & result = "array[" & typeToString(t.sons[0]) & ", " &
typeToString(t.sons[1]) & ']' typeToString(t.sons[1]) & ']'
of tyArrayConstr:
result = "Array constructor[" & rangeToStr(t.sons[0].n) & ", " &
typeToString(t.sons[1]) & ']'
of tySequence: of tySequence:
result = "seq[" & typeToString(t.sons[0]) & ']' result = "seq[" & typeToString(t.sons[0]) & ']'
of tyOrdinal: of tyOrdinal:
@ -580,7 +578,7 @@ proc firstOrd(t: PType): BiggestInt =
of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy:
result = 0 result = 0
of tySet, tyVar: result = firstOrd(t.sons[0]) of tySet, tyVar: result = firstOrd(t.sons[0])
of tyArray, tyArrayConstr: result = firstOrd(t.sons[0]) of tyArray: result = firstOrd(t.sons[0])
of tyRange: of tyRange:
assert(t.n != nil) # range directly given: assert(t.n != nil) # range directly given:
assert(t.n.kind == nkRange) assert(t.n.kind == nkRange)
@ -600,7 +598,7 @@ proc firstOrd(t: PType): BiggestInt =
else: else:
assert(t.n.sons[0].kind == nkSym) assert(t.n.sons[0].kind == nkSym)
result = t.n.sons[0].sym.position result = t.n.sons[0].sym.position
of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor: of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor, tyAlias:
result = firstOrd(lastSon(t)) result = firstOrd(lastSon(t))
of tyOrdinal: of tyOrdinal:
if t.len > 0: result = firstOrd(lastSon(t)) if t.len > 0: result = firstOrd(lastSon(t))
@ -614,7 +612,7 @@ proc lastOrd(t: PType): BiggestInt =
of tyBool: result = 1 of tyBool: result = 1
of tyChar: result = 255 of tyChar: result = 255
of tySet, tyVar: result = lastOrd(t.sons[0]) of tySet, tyVar: result = lastOrd(t.sons[0])
of tyArray, tyArrayConstr: result = lastOrd(t.sons[0]) of tyArray: result = lastOrd(t.sons[0])
of tyRange: of tyRange:
assert(t.n != nil) # range directly given: assert(t.n != nil) # range directly given:
assert(t.n.kind == nkRange) assert(t.n.kind == nkRange)
@ -636,7 +634,7 @@ proc lastOrd(t: PType): BiggestInt =
of tyEnum: of tyEnum:
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym) assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
result = t.n.sons[sonsLen(t.n) - 1].sym.position result = t.n.sons[sonsLen(t.n) - 1].sym.position
of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor: of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor, tyAlias:
result = lastOrd(lastSon(t)) result = lastOrd(lastSon(t))
of tyProxy: result = 0 of tyProxy: result = 0
of tyOrdinal: of tyOrdinal:
@ -778,8 +776,8 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool =
var x = a.sons[i] var x = a.sons[i]
var y = b.sons[i] var y = b.sons[i]
if IgnoreTupleFields in c.flags: if IgnoreTupleFields in c.flags:
x = skipTypes(x, {tyRange, tyGenericInst}) x = skipTypes(x, {tyRange, tyGenericInst, tyAlias})
y = skipTypes(y, {tyRange, tyGenericInst}) y = skipTypes(y, {tyRange, tyGenericInst, tyAlias})
result = sameTypeAux(x, y, c) result = sameTypeAux(x, y, c)
if not result: return if not result: return
@ -833,8 +831,8 @@ proc sameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool =
var x = a.typ var x = a.typ
var y = b.typ var y = b.typ
if IgnoreTupleFields in c.flags: if IgnoreTupleFields in c.flags:
if x != nil: x = skipTypes(x, {tyRange, tyGenericInst}) if x != nil: x = skipTypes(x, {tyRange, tyGenericInst, tyAlias})
if y != nil: y = skipTypes(y, {tyRange, tyGenericInst}) if y != nil: y = skipTypes(y, {tyRange, tyGenericInst, tyAlias})
if sameTypeOrNilAux(x, y, c): if sameTypeOrNilAux(x, y, c):
case a.kind case a.kind
of nkSym: of nkSym:
@ -888,8 +886,8 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
result = eqTypeFlags*a.flags == eqTypeFlags*b.flags result = eqTypeFlags*a.flags == eqTypeFlags*b.flags
if x == y: return true if x == y: return true
var a = skipTypes(x, {tyGenericInst}) var a = skipTypes(x, {tyGenericInst, tyAlias})
var b = skipTypes(y, {tyGenericInst}) var b = skipTypes(y, {tyGenericInst, tyAlias})
assert(a != nil) assert(a != nil)
assert(b != nil) assert(b != nil)
if a.kind != b.kind: if a.kind != b.kind:
@ -957,7 +955,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
if result and ExactGenericParams in c.flags: if result and ExactGenericParams in c.flags:
result = a.sym.position == b.sym.position result = a.sym.position == b.sym.position
of tyGenericInvocation, tyGenericBody, tySequence, of tyGenericInvocation, tyGenericBody, tySequence,
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyOpenArray, tySet, tyRef, tyPtr, tyVar,
tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyFieldAccessor: tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyFieldAccessor:
cycleCheck() cycleCheck()
if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n
@ -970,7 +968,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and
sameValue(a.n.sons[0], b.n.sons[0]) and sameValue(a.n.sons[0], b.n.sons[0]) and
sameValue(a.n.sons[1], b.n.sons[1]) sameValue(a.n.sons[1], b.n.sons[1])
of tyGenericInst: discard of tyGenericInst, tyAlias: discard
of tyNone: result = false of tyNone: result = false
of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("sameFlags") of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("sameFlags")
@ -1117,7 +1115,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
result = nil result = nil
of tyOrdinal: of tyOrdinal:
if kind != skParam: result = t if kind != skParam: result = t
of tyGenericInst, tyDistinct: of tyGenericInst, tyDistinct, tyAlias:
result = typeAllowedAux(marker, lastSon(t), kind, flags) result = typeAllowedAux(marker, lastSon(t), kind, flags)
of tyRange: of tyRange:
if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
@ -1136,7 +1134,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
else: result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap}) else: result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
of tyPtr: of tyPtr:
result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap}) result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
of tyArrayConstr, tySet: of tySet:
for i in countup(0, sonsLen(t) - 1): for i in countup(0, sonsLen(t) - 1):
result = typeAllowedAux(marker, t.sons[i], kind, flags) result = typeAllowedAux(marker, t.sons[i], kind, flags)
if result != nil: break if result != nil: break
@ -1250,7 +1248,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
result = szIllegalRecursion result = szIllegalRecursion
else: result = ptrSize else: result = ptrSize
a = result a = result
of tyArray, tyArrayConstr: of tyArray:
let elemSize = computeSizeAux(typ.sons[1], a) let elemSize = computeSizeAux(typ.sons[1], a)
if elemSize < 0: return elemSize if elemSize < 0: return elemSize
result = lengthOrd(typ.sons[0]) * elemSize result = lengthOrd(typ.sons[0]) * elemSize
@ -1304,7 +1302,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
if result < 0: return if result < 0: return
if a < maxAlign: a = maxAlign if a < maxAlign: a = maxAlign
result = align(result, a) result = align(result, a)
of tyGenericInst, tyDistinct, tyGenericBody: of tyGenericInst, tyDistinct, tyGenericBody, tyAlias:
result = computeSizeAux(lastSon(typ), a) result = computeSizeAux(lastSon(typ), a)
of tyTypeDesc: of tyTypeDesc:
result = computeSizeAux(typ.base, a) result = computeSizeAux(typ.base, a)
@ -1466,10 +1464,10 @@ proc skipConvTakeType*(n: PNode): PNode =
proc isEmptyContainer*(t: PType): bool = proc isEmptyContainer*(t: PType): bool =
case t.kind case t.kind
of tyExpr, tyNil: result = true of tyExpr, tyNil: result = true
of tyArray, tyArrayConstr: result = t.sons[1].kind == tyEmpty of tyArray: result = t.sons[1].kind == tyEmpty
of tySet, tySequence, tyOpenArray, tyVarargs: of tySet, tySequence, tyOpenArray, tyVarargs:
result = t.sons[0].kind == tyEmpty result = t.sons[0].kind == tyEmpty
of tyGenericInst: result = isEmptyContainer(t.lastSon) of tyGenericInst, tyAlias: result = isEmptyContainer(t.lastSon)
else: result = false else: result = false
proc takeType*(formal, arg: PType): PType = proc takeType*(formal, arg: PType): PType =
@ -1480,8 +1478,8 @@ proc takeType*(formal, arg: PType): PType =
result = formal result = formal
elif formal.kind in {tyOpenArray, tyVarargs, tySequence} and elif formal.kind in {tyOpenArray, tyVarargs, tySequence} and
arg.isEmptyContainer: arg.isEmptyContainer:
let a = copyType(arg.skipTypes({tyGenericInst}), arg.owner, keepId=false) let a = copyType(arg.skipTypes({tyGenericInst, tyAlias}), arg.owner, keepId=false)
a.sons[ord(arg.kind in {tyArray, tyArrayConstr})] = formal.sons[0] a.sons[ord(arg.kind == tyArray)] = formal.sons[0]
result = a result = a
elif formal.kind in {tyTuple, tySet} and arg.kind == formal.kind: elif formal.kind in {tyTuple, tySet} and arg.kind == formal.kind:
result = formal result = formal

View file

@ -136,7 +136,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
of tyStmt: result = atomicType("stmt", mStmt) of tyStmt: result = atomicType("stmt", mStmt)
of tyVoid: result = atomicType("void", mVoid) of tyVoid: result = atomicType("void", mVoid)
of tyEmpty: result = atomicType("empty", mNone) of tyEmpty: result = atomicType("empty", mNone)
of tyArrayConstr, tyArray: of tyArray:
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
result.add atomicType("array", mArray) result.add atomicType("array", mArray)
if inst and t.sons[0].kind == tyRange: if inst and t.sons[0].kind == tyRange:
@ -159,7 +159,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
for i in 0 .. < t.len: for i in 0 .. < t.len:
result.add mapTypeToAst(t.sons[i], info) result.add mapTypeToAst(t.sons[i], info)
of tyGenericInst: of tyGenericInst, tyAlias:
if inst: if inst:
if allowRecursion: if allowRecursion:
result = mapTypeToAstR(t.lastSon, info) result = mapTypeToAstR(t.lastSon, info)

View file

@ -1482,7 +1482,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
getNullValueAux(skipTypes(base, skipPtrs).n, result) getNullValueAux(skipTypes(base, skipPtrs).n, result)
base = base.sons[0] base = base.sons[0]
getNullValueAux(t.n, result) getNullValueAux(t.n, result)
of tyArray, tyArrayConstr: of tyArray:
result = newNodeIT(nkBracket, info, t) result = newNodeIT(nkBracket, info, t)
for i in countup(0, int(lengthOrd(t)) - 1): for i in countup(0, int(lengthOrd(t)) - 1):
addSon(result, getNullValue(elemType(t), info)) addSon(result, getNullValue(elemType(t), info))

View file

@ -102,7 +102,7 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet) =
else: else:
storeAny(s, t.lastSon, a[i], stored) storeAny(s, t.lastSon, a[i], stored)
s.add("]") s.add("]")
of tyRange, tyGenericInst: storeAny(s, t.lastSon, a, stored) of tyRange, tyGenericInst, tyAlias: storeAny(s, t.lastSon, a, stored)
of tyEnum: of tyEnum:
# we need a slow linear search because of enums with holes: # we need a slow linear search because of enums with holes:
for e in items(t.n): for e in items(t.n):
@ -275,7 +275,7 @@ proc loadAny(p: var JsonParser, t: PType,
next(p) next(p)
return return
raiseParseErr(p, "float expected") raiseParseErr(p, "float expected")
of tyRange, tyGenericInst: result = loadAny(p, t.lastSon, tab) of tyRange, tyGenericInst, tyAlias: result = loadAny(p, t.lastSon, tab)
else: else:
internalError "cannot marshal at compile-time " & t.typeToString internalError "cannot marshal at compile-time " & t.typeToString