preparations for language extensions: 'sink' and 'lent' types
This commit is contained in:
parent
3af73682e5
commit
e4081a7201
34 changed files with 183 additions and 178 deletions
|
|
@ -49,7 +49,7 @@ 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, tyAlias:
|
of tyGenericInst, tyDistinct, tyAlias, tySink:
|
||||||
result = isPartOfAux(lastSon(a), b, marker)
|
result = isPartOfAux(lastSon(a), b, marker)
|
||||||
of tyArray, tySet, tyTuple:
|
of tyArray, tySet, tyTuple:
|
||||||
for i in countup(0, sonsLen(a) - 1):
|
for i in countup(0, sonsLen(a) - 1):
|
||||||
|
|
|
||||||
|
|
@ -640,7 +640,7 @@ type
|
||||||
mNHint, mNWarning, mNError,
|
mNHint, mNWarning, mNError,
|
||||||
mInstantiationInfo, mGetTypeInfo, mNGenSym,
|
mInstantiationInfo, mGetTypeInfo, mNGenSym,
|
||||||
mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
|
mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
|
||||||
mException, mBultinType
|
mException, mBuiltinType
|
||||||
|
|
||||||
# things that we can evaluate safely at compile time, even if not asked for it:
|
# things that we can evaluate safely at compile time, even if not asked for it:
|
||||||
const
|
const
|
||||||
|
|
@ -940,13 +940,13 @@ const
|
||||||
tyGenericParam}
|
tyGenericParam}
|
||||||
|
|
||||||
StructuralEquivTypes*: TTypeKinds = {tyNil, tyTuple, tyArray,
|
StructuralEquivTypes*: TTypeKinds = {tyNil, tyTuple, tyArray,
|
||||||
tySet, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, tyOpenArray,
|
tySet, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc, tyOpenArray,
|
||||||
tyVarargs}
|
tyVarargs}
|
||||||
|
|
||||||
ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in::
|
ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in::
|
||||||
# var x = expr
|
# var x = expr
|
||||||
tyBool, tyChar, tyEnum, tyArray, tyObject,
|
tyBool, tyChar, tyEnum, tyArray, tyObject,
|
||||||
tySet, tyTuple, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc,
|
tySet, tyTuple, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc,
|
||||||
tyPointer,
|
tyPointer,
|
||||||
tyOpenArray, tyString, tyCString, tyInt..tyInt64, tyFloat..tyFloat128,
|
tyOpenArray, tyString, tyCString, tyInt..tyInt64, tyFloat..tyFloat128,
|
||||||
tyUInt..tyUInt64}
|
tyUInt..tyUInt64}
|
||||||
|
|
@ -1427,7 +1427,7 @@ 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 = owner.skipTypes({tyGenericInst, tyAlias})
|
let o2 = owner.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
if o2.kind in {tyTuple, tyObject, tyArray,
|
if o2.kind in {tyTuple, tyObject, tyArray,
|
||||||
tySequence, tyOpt, tySet, tyDistinct}:
|
tySequence, tyOpt, tySet, tyDistinct}:
|
||||||
o2.flags.incl tfHasAsgn
|
o2.flags.incl tfHasAsgn
|
||||||
|
|
@ -1435,7 +1435,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, tyAlias})
|
let elemB = elem.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
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.
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ proc isInCurrentFrame(p: BProc, n: PNode): bool =
|
||||||
if n.sym.kind in {skVar, skResult, skTemp, skLet} and p.prc != nil:
|
if n.sym.kind in {skVar, skResult, skTemp, skLet} and p.prc != nil:
|
||||||
result = p.prc.id == n.sym.owner.id
|
result = p.prc.id == n.sym.owner.id
|
||||||
of nkDotExpr, nkBracketExpr:
|
of nkDotExpr, nkBracketExpr:
|
||||||
if skipTypes(n.sons[0].typ, abstractInst).kind notin {tyVar,tyPtr,tyRef}:
|
if skipTypes(n.sons[0].typ, abstractInst).kind notin {tyVar,tyLent,tyPtr,tyRef}:
|
||||||
result = isInCurrentFrame(p, n.sons[0])
|
result = isInCurrentFrame(p, n.sons[0])
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||||
result = isInCurrentFrame(p, n.sons[1])
|
result = isInCurrentFrame(p, n.sons[1])
|
||||||
|
|
@ -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, tyAlias})
|
let t = typ.sons[i].skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
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, tyAlias}).callConv == ccClosure:
|
if e.sons[0].typ.skipTypes({tyGenericInst, tyAlias, tySink}).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, tyAlias}).callConv == ccClosure:
|
if ri.sons[0].typ.skipTypes({tyGenericInst, tyAlias, tySink}).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)
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ proc getStorageLoc(n: PNode): TStorageLoc =
|
||||||
else: result = OnUnknown
|
else: result = OnUnknown
|
||||||
of nkDerefExpr, nkHiddenDeref:
|
of nkDerefExpr, nkHiddenDeref:
|
||||||
case n.sons[0].typ.kind
|
case n.sons[0].typ.kind
|
||||||
of tyVar: result = OnUnknown
|
of tyVar, tyLent: result = OnUnknown
|
||||||
of tyPtr: result = OnStack
|
of tyPtr: result = OnStack
|
||||||
of tyRef: result = OnHeap
|
of tyRef: result = OnHeap
|
||||||
else: internalError(n.info, "getStorageLoc")
|
else: internalError(n.info, "getStorageLoc")
|
||||||
|
|
@ -368,7 +368,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||||
of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString,
|
of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString,
|
||||||
tyInt..tyUInt64, tyRange, tyVar:
|
tyInt..tyUInt64, tyRange, tyVar, tyLent:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||||
else: internalError("genAssignment: " & $ty.kind)
|
else: internalError("genAssignment: " & $ty.kind)
|
||||||
|
|
||||||
|
|
@ -1707,7 +1707,7 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
|
||||||
rope(magic)]), a.storage)
|
rope(magic)]), a.storage)
|
||||||
|
|
||||||
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, tyAlias})
|
let destType = e.typ.skipTypes({tyVar, tyGenericInst, tyAlias, tySink})
|
||||||
if sameBackendType(destType, e.sons[1].typ):
|
if sameBackendType(destType, e.sons[1].typ):
|
||||||
expr(p, e.sons[1], d)
|
expr(p, e.sons[1], d)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1783,7 +1783,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, tyAlias, tyVar, tyRange})
|
let underlying = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tySink, 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:
|
||||||
|
|
@ -1793,7 +1793,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, tyAlias, tyVar})
|
let ranged = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent})
|
||||||
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, e.sons[1], "($#)($#)" % [
|
putIntoDest(p, a, e.sons[1], "($#)($#)" % [
|
||||||
|
|
@ -2021,9 +2021,9 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
var r = rdLoc(a)
|
var r = rdLoc(a)
|
||||||
var nilCheck: Rope = nil
|
var nilCheck: Rope = nil
|
||||||
var t = skipTypes(a.t, abstractInst)
|
var t = skipTypes(a.t, abstractInst)
|
||||||
while t.kind in {tyVar, tyPtr, tyRef}:
|
while t.kind in {tyVar, tyLent, tyPtr, tyRef}:
|
||||||
if t.kind != tyVar: nilCheck = r
|
if t.kind notin {tyVar, tyLent}: nilCheck = r
|
||||||
if t.kind != tyVar or not p.module.compileToCpp:
|
if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp:
|
||||||
r = "(*$1)" % [r]
|
r = "(*$1)" % [r]
|
||||||
t = skipTypes(t.lastSon, abstractInst)
|
t = skipTypes(t.lastSon, abstractInst)
|
||||||
if not p.module.compileToCpp:
|
if not p.module.compileToCpp:
|
||||||
|
|
@ -2056,7 +2056,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, arg, a)
|
initLocExpr(p, arg, a)
|
||||||
var r = rdLoc(a)
|
var r = rdLoc(a)
|
||||||
let isRef = skipTypes(arg.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}
|
let isRef = skipTypes(arg.typ, abstractInst).kind in {tyRef, tyPtr, tyVar, tyLent}
|
||||||
if isRef:
|
if isRef:
|
||||||
add(r, "->Sup")
|
add(r, "->Sup")
|
||||||
else:
|
else:
|
||||||
|
|
@ -2068,7 +2068,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
# (see bug #837). However sometimes using a temporary is not correct:
|
# (see bug #837). However sometimes using a temporary is not correct:
|
||||||
# init(TFigure(my)) # where it is passed to a 'var TFigure'. We test
|
# init(TFigure(my)) # where it is passed to a 'var TFigure'. We test
|
||||||
# this by ensuring the destination is also a pointer:
|
# this by ensuring the destination is also a pointer:
|
||||||
if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}:
|
if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar, tyLent}:
|
||||||
getTemp(p, n.typ, d)
|
getTemp(p, n.typ, d)
|
||||||
linefmt(p, cpsStmts, "$1 = &$2;$n", rdLoc(d), r)
|
linefmt(p, cpsStmts, "$1 = &$2;$n", rdLoc(d), r)
|
||||||
else:
|
else:
|
||||||
|
|
@ -2307,7 +2307,7 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope =
|
||||||
of tyBool: result = rope"NIM_FALSE"
|
of tyBool: result = rope"NIM_FALSE"
|
||||||
of tyEnum, tyChar, tyInt..tyInt64, tyUInt..tyUInt64: result = rope"0"
|
of tyEnum, tyChar, tyInt..tyInt64, tyUInt..tyUInt64: result = rope"0"
|
||||||
of tyFloat..tyFloat128: result = rope"0.0"
|
of tyFloat..tyFloat128: result = rope"0.0"
|
||||||
of tyCString, tyString, tyVar, tyPointer, tyPtr, tySequence, tyExpr,
|
of tyCString, tyString, tyVar, tyLent, tyPointer, tyPtr, tySequence, tyExpr,
|
||||||
tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil:
|
tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil:
|
||||||
result = rope"NIM_NIL"
|
result = rope"NIM_NIL"
|
||||||
of tyProc:
|
of tyProc:
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,8 @@ 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, tyAlias, tyDistinct, tyInferred:
|
of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred,
|
||||||
|
tySink:
|
||||||
genTraverseProc(c, accessor, lastSon(typ))
|
genTraverseProc(c, accessor, lastSon(typ))
|
||||||
of tyArray:
|
of tyArray:
|
||||||
let arraySize = lengthOrd(typ.sons[0])
|
let arraySize = lengthOrd(typ.sons[0])
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ proc scopeMangledParam(p: BProc; param: PSym) =
|
||||||
|
|
||||||
const
|
const
|
||||||
irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation,
|
irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation,
|
||||||
tyDistinct, tyRange, tyStatic, tyAlias, tyInferred}
|
tyDistinct, tyRange, tyStatic, tyAlias, tySink, tyInferred}
|
||||||
|
|
||||||
proc typeName(typ: PType): Rope =
|
proc typeName(typ: PType): Rope =
|
||||||
let typ = typ.skipTypes(irrelevantForBackend)
|
let typ = typ.skipTypes(irrelevantForBackend)
|
||||||
|
|
@ -139,7 +139,7 @@ proc getTypeName(m: BModule; typ: PType; sig: SigHash): Rope =
|
||||||
t = t.lastSon
|
t = t.lastSon
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
let typ = if typ.kind == tyAlias: typ.lastSon else: typ
|
let typ = if typ.kind in {tyAlias, tySink}: typ.lastSon else: typ
|
||||||
if typ.loc.r == nil:
|
if typ.loc.r == nil:
|
||||||
typ.loc.r = typ.typeName & $sig
|
typ.loc.r = typ.typeName & $sig
|
||||||
else:
|
else:
|
||||||
|
|
@ -170,7 +170,7 @@ proc mapType(typ: PType): TCTypeKind =
|
||||||
internalAssert typ.isResolvedUserTypeClass
|
internalAssert typ.isResolvedUserTypeClass
|
||||||
return mapType(typ.lastSon)
|
return mapType(typ.lastSon)
|
||||||
of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal,
|
of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal,
|
||||||
tyTypeDesc, tyAlias, tyInferred:
|
tyTypeDesc, tyAlias, tySink, tyInferred:
|
||||||
result = mapType(lastSon(typ))
|
result = mapType(lastSon(typ))
|
||||||
of tyEnum:
|
of tyEnum:
|
||||||
if firstOrd(typ) < 0:
|
if firstOrd(typ) < 0:
|
||||||
|
|
@ -183,7 +183,7 @@ proc mapType(typ: PType): TCTypeKind =
|
||||||
of 8: result = ctInt64
|
of 8: result = ctInt64
|
||||||
else: internalError("mapType")
|
else: internalError("mapType")
|
||||||
of tyRange: result = mapType(typ.sons[0])
|
of tyRange: result = mapType(typ.sons[0])
|
||||||
of tyPtr, tyVar, tyRef, tyOptAsRef:
|
of tyPtr, tyVar, tyLent, tyRef, tyOptAsRef:
|
||||||
var base = skipTypes(typ.lastSon, typedescInst)
|
var base = skipTypes(typ.lastSon, typedescInst)
|
||||||
case base.kind
|
case base.kind
|
||||||
of tyOpenArray, tyArray, tyVarargs: result = ctPtrToArray
|
of tyOpenArray, tyArray, tyVarargs: result = ctPtrToArray
|
||||||
|
|
@ -242,7 +242,7 @@ proc isInvalidReturnType(rettype: PType): bool =
|
||||||
case mapType(rettype)
|
case mapType(rettype)
|
||||||
of ctArray:
|
of ctArray:
|
||||||
result = not (skipTypes(rettype, typedescInst).kind in
|
result = not (skipTypes(rettype, typedescInst).kind in
|
||||||
{tyVar, tyRef, tyPtr})
|
{tyVar, tyLent, tyRef, tyPtr})
|
||||||
of ctStruct:
|
of ctStruct:
|
||||||
let t = skipTypes(rettype, typedescInst)
|
let t = skipTypes(rettype, typedescInst)
|
||||||
if rettype.isImportedCppType or t.isImportedCppType: return false
|
if rettype.isImportedCppType or t.isImportedCppType: return false
|
||||||
|
|
@ -328,7 +328,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, tyAlias:
|
of tyGenericInst, tyAlias, tySink:
|
||||||
result = getSimpleTypeDesc(m, lastSon typ)
|
result = getSimpleTypeDesc(m, lastSon typ)
|
||||||
else: result = nil
|
else: result = nil
|
||||||
|
|
||||||
|
|
@ -348,7 +348,7 @@ proc getTypePre(m: BModule, typ: PType; sig: SigHash): Rope =
|
||||||
if result == nil: result = cacheGetType(m.typeCache, sig)
|
if result == nil: result = cacheGetType(m.typeCache, sig)
|
||||||
|
|
||||||
proc structOrUnion(t: PType): Rope =
|
proc structOrUnion(t: PType): Rope =
|
||||||
let t = t.skipTypes({tyAlias})
|
let t = t.skipTypes({tyAlias, tySink})
|
||||||
(if tfUnion in t.flags: rope("union") else: rope("struct"))
|
(if tfUnion in t.flags: rope("union") else: rope("struct"))
|
||||||
|
|
||||||
proc getForwardStructFormat(m: BModule): string =
|
proc getForwardStructFormat(m: BModule): string =
|
||||||
|
|
@ -396,7 +396,7 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): Rope =
|
||||||
result = getTypeDescAux(m, t, check)
|
result = getTypeDescAux(m, t, check)
|
||||||
|
|
||||||
proc paramStorageLoc(param: PSym): TStorageLoc =
|
proc paramStorageLoc(param: PSym): TStorageLoc =
|
||||||
if param.typ.skipTypes({tyVar, tyTypeDesc}).kind notin {
|
if param.typ.skipTypes({tyVar, tyLent, tyTypeDesc}).kind notin {
|
||||||
tyArray, tyOpenArray, tyVarargs}:
|
tyArray, tyOpenArray, tyVarargs}:
|
||||||
result = OnStack
|
result = OnStack
|
||||||
else:
|
else:
|
||||||
|
|
@ -430,11 +430,11 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
|
||||||
add(params, param.loc.r)
|
add(params, param.loc.r)
|
||||||
# declare the len field for open arrays:
|
# declare the len field for open arrays:
|
||||||
var arr = param.typ
|
var arr = param.typ
|
||||||
if arr.kind == tyVar: arr = arr.sons[0]
|
if arr.kind in {tyVar, tyLent}: arr = arr.lastSon
|
||||||
var j = 0
|
var j = 0
|
||||||
while arr.kind in {tyOpenArray, tyVarargs}:
|
while arr.kind in {tyOpenArray, tyVarargs}:
|
||||||
# this fixes the 'sort' bug:
|
# this fixes the 'sort' bug:
|
||||||
if param.typ.kind == tyVar: param.loc.storage = OnUnknown
|
if param.typ.kind in {tyVar, tyLent}: param.loc.storage = OnUnknown
|
||||||
# need to pass hidden parameter:
|
# need to pass hidden parameter:
|
||||||
addf(params, ", NI $1Len_$2", [param.loc.r, j.rope])
|
addf(params, ", NI $1Len_$2", [param.loc.r, j.rope])
|
||||||
inc(j)
|
inc(j)
|
||||||
|
|
@ -641,7 +641,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
excl(check, t.id)
|
excl(check, t.id)
|
||||||
return
|
return
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyRef, tyOptAsRef, tyPtr, tyVar:
|
of tyRef, tyOptAsRef, tyPtr, tyVar, tyLent:
|
||||||
var star = if t.kind == tyVar and tfVarIsPtr notin origTyp.flags and
|
var star = if t.kind == tyVar and tfVarIsPtr notin origTyp.flags and
|
||||||
compileToCpp(m): "&" else: "*"
|
compileToCpp(m): "&" else: "*"
|
||||||
var et = origTyp.skipTypes(abstractInst).lastSon
|
var et = origTyp.skipTypes(abstractInst).lastSon
|
||||||
|
|
@ -872,7 +872,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, tyAlias,
|
of tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias, tySink,
|
||||||
tyUserTypeClass, tyUserTypeClassInst, tyInferred:
|
tyUserTypeClass, tyUserTypeClassInst, tyInferred:
|
||||||
result = getTypeDescAux(m, lastSon(t), check)
|
result = getTypeDescAux(m, lastSon(t), check)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1227,7 +1227,7 @@ proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||||
m.g.typeInfoMarker[sig] = result
|
m.g.typeInfoMarker[sig] = result
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyEmpty, tyVoid: result = rope"0"
|
of tyEmpty, tyVoid: result = rope"0"
|
||||||
of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar:
|
of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar, tyLent:
|
||||||
genTypeInfoAuxBase(m, t, t, result, rope"0", info)
|
genTypeInfoAuxBase(m, t, t, result, rope"0", info)
|
||||||
of tyStatic:
|
of tyStatic:
|
||||||
if t.n != nil: result = genTypeInfo(m, lastSon t, info)
|
if t.n != nil: result = genTypeInfo(m, lastSon t, info)
|
||||||
|
|
|
||||||
|
|
@ -110,13 +110,13 @@ 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, tyAlias, tyInferred:
|
of tyGenericInst, tyOrdinal, tyStatic, tyAlias, tySink, tyInferred:
|
||||||
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":
|
||||||
# echo "for ", typeToString(key), " I returned "
|
# echo "for ", typeToString(key), " I returned "
|
||||||
# debug result
|
# debug result
|
||||||
of tyPtr, tyRef, tyVar:
|
of tyPtr, tyRef, tyVar, tyLent:
|
||||||
let elemType = lastSon(key)
|
let elemType = lastSon(key)
|
||||||
if elemType.kind in {tyBool, tyChar, tyInt..tyUInt64}:
|
if elemType.kind in {tyBool, tyChar, tyInt..tyUInt64}:
|
||||||
# no canonicalization for integral types, so that e.g. ``ptr pid_t`` is
|
# no canonicalization for integral types, so that e.g. ``ptr pid_t`` is
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ proc sameMethodBucket(a, b: PSym): MethodResult =
|
||||||
while true:
|
while true:
|
||||||
aa = skipTypes(aa, {tyGenericInst, tyAlias})
|
aa = skipTypes(aa, {tyGenericInst, tyAlias})
|
||||||
bb = skipTypes(bb, {tyGenericInst, tyAlias})
|
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, tyLent}:
|
||||||
aa = aa.lastSon
|
aa = aa.lastSon
|
||||||
bb = bb.lastSon
|
bb = bb.lastSon
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ proc patchHead(n: PNode) =
|
||||||
if n[1].typ.isNil:
|
if n[1].typ.isNil:
|
||||||
# XXX toptree crashes without this workaround. Figure out why.
|
# XXX toptree crashes without this workaround. Figure out why.
|
||||||
return
|
return
|
||||||
let t = n[1].typ.skipTypes({tyVar, tyGenericInst, tyAlias, tyInferred})
|
let t = n[1].typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
|
||||||
template patch(op, field) =
|
template patch(op, field) =
|
||||||
if s.name.s == op and field != nil and field != s:
|
if s.name.s == op and field != nil and field != s:
|
||||||
n.sons[0].sym = field
|
n.sons[0].sym = field
|
||||||
|
|
@ -198,15 +198,15 @@ template genOp(opr, opname) =
|
||||||
result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest))
|
result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest))
|
||||||
|
|
||||||
proc genSink(t: PType; dest: PNode): PNode =
|
proc genSink(t: PType; dest: PNode): PNode =
|
||||||
let t = t.skipTypes({tyGenericInst, tyAlias})
|
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
genOp(if t.sink != nil: t.sink else: t.assignment, "=sink")
|
genOp(if t.sink != nil: t.sink else: t.assignment, "=sink")
|
||||||
|
|
||||||
proc genCopy(t: PType; dest: PNode): PNode =
|
proc genCopy(t: PType; dest: PNode): PNode =
|
||||||
let t = t.skipTypes({tyGenericInst, tyAlias})
|
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
genOp(t.assignment, "=")
|
genOp(t.assignment, "=")
|
||||||
|
|
||||||
proc genDestroy(t: PType; dest: PNode): PNode =
|
proc genDestroy(t: PType; dest: PNode): PNode =
|
||||||
let t = t.skipTypes({tyGenericInst, tyAlias})
|
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
genOp(t.destructor, "=destroy")
|
genOp(t.destructor, "=destroy")
|
||||||
|
|
||||||
proc addTopVar(c: var Con; v: PNode) =
|
proc addTopVar(c: var Con; v: PNode) =
|
||||||
|
|
|
||||||
|
|
@ -86,10 +86,10 @@ proc mapType(t: ast.PType): ptr libffi.TType =
|
||||||
else: result = nil
|
else: result = nil
|
||||||
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, tyLent, tyPointer, tyPtr, tyRef, tyCString, tySequence, tyString, tyExpr,
|
||||||
tyStmt, tyTypeDesc, tyProc, tyArray, tyStatic, tyNil:
|
tyStmt, tyTypeDesc, tyProc, tyArray, tyStatic, tyNil:
|
||||||
result = addr libffi.type_pointer
|
result = addr libffi.type_pointer
|
||||||
of tyDistinct, tyAlias:
|
of tyDistinct, tyAlias, tySink:
|
||||||
result = mapType(t.sons[0])
|
result = mapType(t.sons[0])
|
||||||
else:
|
else:
|
||||||
result = nil
|
result = nil
|
||||||
|
|
@ -112,12 +112,12 @@ template `+!`(x, y: untyped): untyped =
|
||||||
proc packSize(v: PNode, typ: PType): int =
|
proc packSize(v: PNode, typ: PType): int =
|
||||||
## computes the size of the blob
|
## computes the size of the blob
|
||||||
case typ.kind
|
case typ.kind
|
||||||
of tyPtr, tyRef, tyVar:
|
of tyPtr, tyRef, tyVar, tyLent:
|
||||||
if v.kind in {nkNilLit, nkPtrLit}:
|
if v.kind in {nkNilLit, nkPtrLit}:
|
||||||
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, tyAlias:
|
of tyDistinct, tyGenericInst, tyAlias, tySink:
|
||||||
result = packSize(v, typ.sons[0])
|
result = packSize(v, typ.sons[0])
|
||||||
of tyArray:
|
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;
|
||||||
|
|
@ -209,7 +209,7 @@ proc pack(v: PNode, typ: PType, res: pointer) =
|
||||||
awr(cstring, cstring(v.strVal))
|
awr(cstring, cstring(v.strVal))
|
||||||
else:
|
else:
|
||||||
globalError(v.info, "cannot map pointer/proc value to FFI")
|
globalError(v.info, "cannot map pointer/proc value to FFI")
|
||||||
of tyPtr, tyRef, tyVar:
|
of tyPtr, tyRef, tyVar, tyLent:
|
||||||
if v.kind == nkNilLit:
|
if v.kind == nkNilLit:
|
||||||
# nothing to do since the memory is 0 initialized anyway
|
# nothing to do since the memory is 0 initialized anyway
|
||||||
discard
|
discard
|
||||||
|
|
@ -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, tyAlias:
|
of tyDistinct, tyGenericInst, tyAlias, tySink:
|
||||||
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))
|
||||||
|
|
@ -364,7 +364,7 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
else:
|
else:
|
||||||
awi(nkPtrLit, cast[ByteAddress](p))
|
awi(nkPtrLit, cast[ByteAddress](p))
|
||||||
of tyPtr, tyRef, tyVar:
|
of tyPtr, tyRef, tyVar, tyLent:
|
||||||
let p = rd(pointer, x)
|
let p = rd(pointer, x)
|
||||||
if p.isNil:
|
if p.isNil:
|
||||||
setNil()
|
setNil()
|
||||||
|
|
@ -388,14 +388,14 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
|
||||||
aws(nkStrLit, $p)
|
aws(nkStrLit, $p)
|
||||||
of tyNil:
|
of tyNil:
|
||||||
setNil()
|
setNil()
|
||||||
of tyDistinct, tyGenericInst, tyAlias:
|
of tyDistinct, tyGenericInst, tyAlias, tySink:
|
||||||
result = unpack(x, typ.lastSon, 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))
|
||||||
|
|
||||||
proc fficast*(x: PNode, destTyp: PType): PNode =
|
proc fficast*(x: PNode, destTyp: PType): PNode =
|
||||||
if x.kind == nkPtrLit and x.typ.kind in {tyPtr, tyRef, tyVar, tyPointer,
|
if x.kind == nkPtrLit and x.typ.kind in {tyPtr, tyRef, tyVar, tyLent, tyPointer,
|
||||||
tyProc, tyCString, tyString,
|
tyProc, tyCString, tyString,
|
||||||
tySequence}:
|
tySequence}:
|
||||||
result = newNodeIT(x.kind, x.info, destTyp)
|
result = newNodeIT(x.kind, x.info, destTyp)
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ const
|
||||||
proc mapType(typ: PType): TJSTypeKind =
|
proc mapType(typ: PType): TJSTypeKind =
|
||||||
let t = skipTypes(typ, abstractInst)
|
let t = skipTypes(typ, abstractInst)
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyVar, tyRef, tyPtr:
|
of tyVar, tyRef, tyPtr, tyLent:
|
||||||
if skipTypes(t.lastSon, abstractInst).kind in MappedToObject:
|
if skipTypes(t.lastSon, abstractInst).kind in MappedToObject:
|
||||||
result = etyObject
|
result = etyObject
|
||||||
else:
|
else:
|
||||||
|
|
@ -196,14 +196,15 @@ proc mapType(typ: PType): TJSTypeKind =
|
||||||
tyExpr, tyStmt, tyTypeDesc, tyBuiltInTypeClass, tyCompositeTypeClass,
|
tyExpr, tyStmt, tyTypeDesc, tyBuiltInTypeClass, tyCompositeTypeClass,
|
||||||
tyAnd, tyOr, tyNot, tyAnything, tyVoid:
|
tyAnd, tyOr, tyNot, tyAnything, tyVoid:
|
||||||
result = etyNone
|
result = etyNone
|
||||||
of tyGenericInst, tyInferred, tyAlias, tyUserTypeClass, tyUserTypeClassInst:
|
of tyGenericInst, tyInferred, tyAlias, tyUserTypeClass, tyUserTypeClassInst,
|
||||||
|
tySink:
|
||||||
result = mapType(typ.lastSon)
|
result = mapType(typ.lastSon)
|
||||||
of tyStatic:
|
of tyStatic:
|
||||||
if t.n != nil: result = mapType(lastSon t)
|
if t.n != nil: result = mapType(lastSon t)
|
||||||
else: result = etyNone
|
else: result = etyNone
|
||||||
of tyProc: result = etyProc
|
of tyProc: result = etyProc
|
||||||
of tyCString: result = etyString
|
of tyCString: result = etyString
|
||||||
of tyUnused, tyOptAsRef, tyUnused1, tyUnused2: internalError("mapType")
|
of tyUnused, tyOptAsRef: internalError("mapType")
|
||||||
|
|
||||||
proc mapType(p: PProc; typ: PType): TJSTypeKind =
|
proc mapType(p: PProc; typ: PType): TJSTypeKind =
|
||||||
if p.target == targetPHP: result = etyObject
|
if p.target == targetPHP: result = etyObject
|
||||||
|
|
@ -869,8 +870,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, tyAlias}).kind
|
let k = param.typ.skipTypes({tyGenericInst, tyAlias, tySink}).kind
|
||||||
if k in {tyVar, tyRef, tyPtr, tyPointer}:
|
if k in {tyVar, tyRef, tyPtr, tyLent, tyPointer}:
|
||||||
add(result, "&")
|
add(result, "&")
|
||||||
add(result, "$")
|
add(result, "$")
|
||||||
add(result, name)
|
add(result, name)
|
||||||
|
|
@ -899,7 +900,7 @@ const
|
||||||
|
|
||||||
proc needsNoCopy(p: PProc; y: PNode): bool =
|
proc needsNoCopy(p: PProc; y: PNode): bool =
|
||||||
result = (y.kind in nodeKindsNeedNoCopy) or
|
result = (y.kind in nodeKindsNeedNoCopy) or
|
||||||
(skipTypes(y.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}) or
|
(skipTypes(y.typ, abstractInst).kind in {tyRef, tyPtr, tyLent, tyVar}) or
|
||||||
p.target == targetPHP
|
p.target == targetPHP
|
||||||
|
|
||||||
proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||||
|
|
@ -1077,7 +1078,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
|
|
||||||
proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
|
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, tyLent}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
||||||
case ty.kind
|
case ty.kind
|
||||||
of tyArray, tyOpenArray, tySequence, tyString, tyCString, tyVarargs:
|
of tyArray, tyOpenArray, tySequence, tyString, tyCString, tyVarargs:
|
||||||
genArrayAddr(p, n, r)
|
genArrayAddr(p, n, r)
|
||||||
|
|
@ -1300,7 +1301,7 @@ proc genArg(p: PProc, n: PNode, param: PSym, r: var TCompRes; emitted: ptr int =
|
||||||
add(r.res, ", ")
|
add(r.res, ", ")
|
||||||
add(r.res, a.res)
|
add(r.res, a.res)
|
||||||
if emitted != nil: inc emitted[]
|
if emitted != nil: inc emitted[]
|
||||||
elif n.typ.kind == tyVar and n.kind in nkCallKinds and mapType(param.typ) == etyBaseIndex:
|
elif n.typ.kind in {tyVar, tyLent} and n.kind in nkCallKinds and mapType(param.typ) == etyBaseIndex:
|
||||||
# this fixes bug #5608:
|
# this fixes bug #5608:
|
||||||
let tmp = getTemp(p)
|
let tmp = getTemp(p)
|
||||||
add(r.res, "($1 = $2, $1[0]), $1[1]" % [tmp, a.rdLoc])
|
add(r.res, "($1 = $2, $1[0]), $1[1]" % [tmp, a.rdLoc])
|
||||||
|
|
@ -1499,7 +1500,7 @@ 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, tyAlias:
|
of tyRange, tyGenericInst, tyAlias, tySink:
|
||||||
result = createVar(p, lastSon(typ), indirect)
|
result = createVar(p, lastSon(typ), indirect)
|
||||||
of tySet:
|
of tySet:
|
||||||
result = putToSeq("{}" | "array()", indirect)
|
result = putToSeq("{}" | "array()", indirect)
|
||||||
|
|
@ -1546,7 +1547,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||||
createObjInitList(p, t, initIntSet(), initList)
|
createObjInitList(p, t, initIntSet(), initList)
|
||||||
result = ("{$1}" | "array($#)") % [initList]
|
result = ("{$1}" | "array($#)") % [initList]
|
||||||
if indirect: result = "[$1]" % [result]
|
if indirect: result = "[$1]" % [result]
|
||||||
of tyVar, tyPtr, tyRef:
|
of tyVar, tyPtr, tyLent, tyRef:
|
||||||
if mapType(p, t) == etyBaseIndex:
|
if mapType(p, t) == etyBaseIndex:
|
||||||
result = putToSeq("[null, 0]", indirect)
|
result = putToSeq("[null, 0]", indirect)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1579,7 +1580,7 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
||||||
let mname = mangleName(v, p.target)
|
let mname = mangleName(v, p.target)
|
||||||
lineF(p, varCode & " = $3;$n" | "$$$2 = $3;$n",
|
lineF(p, varCode & " = $3;$n" | "$$$2 = $3;$n",
|
||||||
[returnType, mname, createVar(p, v.typ, isIndirect(v))])
|
[returnType, mname, createVar(p, v.typ, isIndirect(v))])
|
||||||
if v.typ.kind in { tyVar, tyPtr, tyRef } and mapType(p, v.typ) == etyBaseIndex:
|
if v.typ.kind in {tyVar, tyPtr, tyLent, tyRef} and mapType(p, v.typ) == etyBaseIndex:
|
||||||
lineF(p, "var $1_Idx = 0;$n", [ mname ])
|
lineF(p, "var $1_Idx = 0;$n", [ mname ])
|
||||||
else:
|
else:
|
||||||
discard mangleName(v, p.target)
|
discard mangleName(v, p.target)
|
||||||
|
|
@ -1774,7 +1775,7 @@ proc genRepr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
|
|
||||||
proc genOf(p: PProc, n: PNode, r: var TCompRes) =
|
proc genOf(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var x: TCompRes
|
var x: TCompRes
|
||||||
let t = skipTypes(n.sons[2].typ, abstractVarRange+{tyRef, tyPtr, tyTypeDesc})
|
let t = skipTypes(n.sons[2].typ, abstractVarRange+{tyRef, tyPtr, tyLent, tyTypeDesc})
|
||||||
gen(p, n.sons[1], x)
|
gen(p, n.sons[1], x)
|
||||||
if tfFinal in t.flags:
|
if tfFinal in t.flags:
|
||||||
r.res = "($1.m_type == $2)" % [x.res, genTypeInfo(p, t)]
|
r.res = "($1.m_type == $2)" % [x.res, genTypeInfo(p, t)]
|
||||||
|
|
@ -2161,7 +2162,8 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
|
||||||
let mname = mangleName(resultSym, p.target)
|
let mname = mangleName(resultSym, p.target)
|
||||||
let resVar = createVar(p, resultSym.typ, isIndirect(resultSym))
|
let resVar = createVar(p, resultSym.typ, isIndirect(resultSym))
|
||||||
resultAsgn = p.indentLine(("var $# = $#;$n" | "$$$# = $#;$n") % [mname, resVar])
|
resultAsgn = p.indentLine(("var $# = $#;$n" | "$$$# = $#;$n") % [mname, resVar])
|
||||||
if resultSym.typ.kind in { tyVar, tyPtr, tyRef } and mapType(p, resultSym.typ) == etyBaseIndex:
|
if resultSym.typ.kind in {tyVar, tyPtr, tyLent, tyRef} and
|
||||||
|
mapType(p, resultSym.typ) == etyBaseIndex:
|
||||||
resultAsgn.add p.indentLine("var $#_Idx = 0;$n" % [mname])
|
resultAsgn.add p.indentLine("var $#_Idx = 0;$n" % [mname])
|
||||||
gen(p, prc.ast.sons[resultPos], a)
|
gen(p, prc.ast.sons[resultPos], a)
|
||||||
if mapType(p, resultSym.typ) == etyBaseIndex:
|
if mapType(p, resultSym.typ) == etyBaseIndex:
|
||||||
|
|
@ -2218,10 +2220,10 @@ proc genCast(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if dest.kind == src.kind:
|
if dest.kind == src.kind:
|
||||||
# no-op conversion
|
# no-op conversion
|
||||||
return
|
return
|
||||||
let toInt = (dest.kind in tyInt .. tyInt32)
|
let toInt = (dest.kind in tyInt..tyInt32)
|
||||||
let toUint = (dest.kind in tyUInt .. tyUInt32)
|
let toUint = (dest.kind in tyUInt..tyUInt32)
|
||||||
let fromInt = (src.kind in tyInt .. tyInt32)
|
let fromInt = (src.kind in tyInt..tyInt32)
|
||||||
let fromUint = (src.kind in tyUInt .. tyUInt32)
|
let fromUint = (src.kind in tyUInt..tyUInt32)
|
||||||
|
|
||||||
if toUint and (fromInt or fromUint):
|
if toUint and (fromInt or fromUint):
|
||||||
let trimmer = unsignedTrimmer(dest.size)
|
let trimmer = unsignedTrimmer(dest.size)
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,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, tyAlias})
|
let t = t.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink})
|
||||||
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
|
||||||
|
|
@ -141,7 +141,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, tyAlias})
|
let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink})
|
||||||
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
|
||||||
|
|
@ -152,7 +152,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
|
||||||
"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))]
|
||||||
prepend(p.g.typeInfo, s)
|
prepend(p.g.typeInfo, s)
|
||||||
of tyVar, tyRef, tyPtr, tySequence, tyRange, tySet:
|
of tyVar, tyLent, tyRef, tyPtr, tySequence, tyRange, tySet:
|
||||||
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))]
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ proc interestingVar(s: PSym): bool {.inline.} =
|
||||||
|
|
||||||
proc illegalCapture(s: PSym): bool {.inline.} =
|
proc illegalCapture(s: PSym): bool {.inline.} =
|
||||||
result = skipTypes(s.typ, abstractInst).kind in
|
result = skipTypes(s.typ, abstractInst).kind in
|
||||||
{tyVar, tyOpenArray, tyVarargs} or
|
{tyVar, tyOpenArray, tyVarargs, tyLent} or
|
||||||
s.kind == skResult
|
s.kind == skResult
|
||||||
|
|
||||||
proc isInnerProc(s: PSym): bool =
|
proc isInnerProc(s: PSym): bool =
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,7 @@ proc typeNeedsNoDeepCopy(t: PType): bool =
|
||||||
# note that seq[T] is fine, but 'var seq[T]' is not, so we need to skip 'var'
|
# 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
|
# for the stricter check and likewise we can skip 'seq' for a less
|
||||||
# strict check:
|
# strict check:
|
||||||
if t.kind in {tyVar, tySequence}: t = t.sons[0]
|
if t.kind in {tyVar, tyLent, tySequence}: t = t.lastSon
|
||||||
result = not containsGarbageCollectedRef(t)
|
result = not containsGarbageCollectedRef(t)
|
||||||
|
|
||||||
proc addLocalVar(varSection, varInit: PNode; owner: PSym; typ: PType;
|
proc addLocalVar(varSection, varInit: PNode; owner: PSym; typ: PType;
|
||||||
|
|
@ -469,7 +469,7 @@ proc setupArgsForConcurrency(n: PNode; objType: PType; scratchObj: PSym,
|
||||||
# we pick n's type here, which hopefully is 'tyArray' and not
|
# we pick n's type here, which hopefully is 'tyArray' and not
|
||||||
# 'tyOpenArray':
|
# 'tyOpenArray':
|
||||||
var argType = n[i].typ.skipTypes(abstractInst)
|
var argType = n[i].typ.skipTypes(abstractInst)
|
||||||
if i < formals.len and formals[i].typ.kind == tyVar:
|
if i < formals.len and formals[i].typ.kind in {tyVar, tyLent}:
|
||||||
localError(n[i].info, "'spawn'ed function cannot have a 'var' parameter")
|
localError(n[i].info, "'spawn'ed function cannot have a 'var' parameter")
|
||||||
#elif containsTyRef(argType):
|
#elif containsTyRef(argType):
|
||||||
# localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure")
|
# localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure")
|
||||||
|
|
|
||||||
|
|
@ -325,8 +325,8 @@ proc lsub(g: TSrcGen; n: PNode): int
|
||||||
proc litAux(g: TSrcGen; n: PNode, x: BiggestInt, size: int): string =
|
proc litAux(g: TSrcGen; 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,
|
while result.kind in {tyGenericInst, tyRange, tyVar, tyLent, tyDistinct,
|
||||||
tyOrdinal, tyAlias}:
|
tyOrdinal, tyAlias, tySink}:
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -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, tyAlias})
|
var a = skipTypes(x, {tyGenericInst, tyAlias, tySink})
|
||||||
var b = skipTypes(y, {tyGenericInst, tyAlias})
|
var b = skipTypes(y, {tyGenericInst, tyAlias, tySink})
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -242,9 +242,9 @@ 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, tyInferred,
|
of tyOrdinal, tyRange, tyInferred,
|
||||||
tyGenericInst, tyStatic, tyVar, tyAlias:
|
tyGenericInst, tyStatic, tyVar, tyLent, tyAlias, tySink:
|
||||||
liftBodyAux(c, lastSon(t), body, x, y)
|
liftBodyAux(c, lastSon(t), body, x, y)
|
||||||
of tyUnused, tyOptAsRef, tyUnused1, tyUnused2: internalError("liftBodyAux")
|
of tyUnused, tyOptAsRef: internalError("liftBodyAux")
|
||||||
|
|
||||||
proc newProcType(info: TLineInfo; owner: PSym): PType =
|
proc newProcType(info: TLineInfo; owner: PSym): PType =
|
||||||
result = newType(tyProc, owner)
|
result = newType(tyProc, owner)
|
||||||
|
|
@ -306,7 +306,7 @@ proc liftBody(c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||||
|
|
||||||
|
|
||||||
proc getAsgnOrLiftBody(c: PContext; typ: PType; info: TLineInfo): PSym =
|
proc getAsgnOrLiftBody(c: PContext; typ: PType; info: TLineInfo): PSym =
|
||||||
let t = typ.skipTypes({tyGenericInst, tyVar, tyAlias})
|
let t = typ.skipTypes({tyGenericInst, tyVar, tyLent, tyAlias, tySink})
|
||||||
result = t.assignment
|
result = t.assignment
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
result = liftBody(c, t, attachedAsgn, info)
|
result = liftBody(c, t, attachedAsgn, info)
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,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, tyAlias}).kind in {tyPtr, tyRef})
|
t != nil and t.skipTypes({tyGenericInst, tyAlias, tySink}).kind in {tyPtr, tyRef})
|
||||||
|
|
||||||
proc tryDeref(n: PNode): PNode =
|
proc tryDeref(n: PNode): PNode =
|
||||||
result = newNodeI(nkHiddenDeref, n.info)
|
result = newNodeI(nkHiddenDeref, n.info)
|
||||||
|
|
|
||||||
|
|
@ -259,19 +259,19 @@ proc makePtrType*(c: PContext, baseType: PType): PType =
|
||||||
proc makeTypeWithModifier*(c: PContext,
|
proc makeTypeWithModifier*(c: PContext,
|
||||||
modifier: TTypeKind,
|
modifier: TTypeKind,
|
||||||
baseType: PType): PType =
|
baseType: PType): PType =
|
||||||
assert modifier in {tyVar, tyPtr, tyRef, tyStatic, tyTypeDesc}
|
assert modifier in {tyVar, tyLent, tyPtr, tyRef, tyStatic, tyTypeDesc}
|
||||||
|
|
||||||
if modifier in {tyVar, tyTypeDesc} and baseType.kind == modifier:
|
if modifier in {tyVar, tyLent, tyTypeDesc} and baseType.kind == modifier:
|
||||||
result = baseType
|
result = baseType
|
||||||
else:
|
else:
|
||||||
result = newTypeS(modifier, c)
|
result = newTypeS(modifier, c)
|
||||||
addSonSkipIntLit(result, baseType.assertNotNil)
|
addSonSkipIntLit(result, baseType.assertNotNil)
|
||||||
|
|
||||||
proc makeVarType*(c: PContext, baseType: PType): PType =
|
proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType =
|
||||||
if baseType.kind == tyVar:
|
if baseType.kind == kind:
|
||||||
result = baseType
|
result = baseType
|
||||||
else:
|
else:
|
||||||
result = newTypeS(tyVar, c)
|
result = newTypeS(kind, c)
|
||||||
addSonSkipIntLit(result, baseType.assertNotNil)
|
addSonSkipIntLit(result, baseType.assertNotNil)
|
||||||
|
|
||||||
proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
# XXX tyGenericInst here?
|
# XXX tyGenericInst here?
|
||||||
if result.typ.kind == tyProc and tfUnresolved in result.typ.flags:
|
if result.typ.kind == tyProc and tfUnresolved in result.typ.flags:
|
||||||
localError(n.info, errProcHasNoConcreteType, n.renderTree)
|
localError(n.info, errProcHasNoConcreteType, n.renderTree)
|
||||||
if result.typ.kind == tyVar: result = newDeref(result)
|
if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
|
||||||
elif {efWantStmt, efAllowStmt} * flags != {}:
|
elif {efWantStmt, efAllowStmt} * flags != {}:
|
||||||
result.typ = newTypeS(tyVoid, c)
|
result.typ = newTypeS(tyVoid, c)
|
||||||
else:
|
else:
|
||||||
|
|
@ -52,7 +52,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
result.typ = errorType(c)
|
result.typ = errorType(c)
|
||||||
else:
|
else:
|
||||||
if efNoProcvarCheck notin flags: semProcvarCheck(c, result)
|
if efNoProcvarCheck notin flags: semProcvarCheck(c, result)
|
||||||
if result.typ.kind == tyVar: result = newDeref(result)
|
if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
|
||||||
|
|
||||||
proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
result = semExpr(c, n, flags)
|
result = semExpr(c, n, flags)
|
||||||
|
|
@ -350,7 +350,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, tyAlias})
|
let tup = newType.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
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")
|
||||||
|
|
@ -393,7 +393,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, tyAlias})
|
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
|
||||||
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
|
||||||
|
|
@ -417,7 +417,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
let yy = semExprWithType(c, x)
|
let yy = semExprWithType(c, x)
|
||||||
var typ = yy.typ
|
var typ = yy.typ
|
||||||
addSon(result, yy)
|
addSon(result, yy)
|
||||||
#var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyOrdinal})
|
#var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal})
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
x = n.sons[i]
|
x = n.sons[i]
|
||||||
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
||||||
|
|
@ -471,7 +471,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
|
||||||
of nkSym:
|
of nkSym:
|
||||||
# n.sym.typ can be nil in 'check' mode ...
|
# n.sym.typ can be nil in 'check' mode ...
|
||||||
if n.sym.typ != nil and
|
if n.sym.typ != nil and
|
||||||
skipTypes(n.sym.typ, abstractInst-{tyTypeDesc}).kind != tyVar:
|
skipTypes(n.sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
|
||||||
incl(n.sym.flags, sfAddrTaken)
|
incl(n.sym.flags, sfAddrTaken)
|
||||||
result = newHiddenAddrTaken(c, n)
|
result = newHiddenAddrTaken(c, n)
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
|
|
@ -479,12 +479,12 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
|
||||||
if n.sons[1].kind != nkSym:
|
if n.sons[1].kind != nkSym:
|
||||||
internalError(n.info, "analyseIfAddressTaken")
|
internalError(n.info, "analyseIfAddressTaken")
|
||||||
return
|
return
|
||||||
if skipTypes(n.sons[1].sym.typ, abstractInst-{tyTypeDesc}).kind != tyVar:
|
if skipTypes(n.sons[1].sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
|
||||||
incl(n.sons[1].sym.flags, sfAddrTaken)
|
incl(n.sons[1].sym.flags, sfAddrTaken)
|
||||||
result = newHiddenAddrTaken(c, n)
|
result = newHiddenAddrTaken(c, n)
|
||||||
of nkBracketExpr:
|
of nkBracketExpr:
|
||||||
checkMinSonsLen(n, 1)
|
checkMinSonsLen(n, 1)
|
||||||
if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind != tyVar:
|
if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
|
||||||
if n.sons[0].kind == nkSym: incl(n.sons[0].sym.flags, sfAddrTaken)
|
if n.sons[0].kind == nkSym: incl(n.sons[0].sym.flags, sfAddrTaken)
|
||||||
result = newHiddenAddrTaken(c, n)
|
result = newHiddenAddrTaken(c, n)
|
||||||
else:
|
else:
|
||||||
|
|
@ -499,7 +499,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, tyAlias})
|
var t = n.sons[0].typ.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
|
|
||||||
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!
|
||||||
|
|
@ -692,7 +692,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
else:
|
else:
|
||||||
n.sons[0] = semExpr(c, n.sons[0], {efInCall})
|
n.sons[0] = semExpr(c, n.sons[0], {efInCall})
|
||||||
let t = n.sons[0].typ
|
let t = n.sons[0].typ
|
||||||
if t != nil and t.kind == tyVar:
|
if t != nil and t.kind in {tyVar, tyLent}:
|
||||||
n.sons[0] = newDeref(n.sons[0])
|
n.sons[0] = newDeref(n.sons[0])
|
||||||
elif n.sons[0].kind == nkBracketExpr:
|
elif n.sons[0].kind == nkBracketExpr:
|
||||||
let s = bracketedMacro(n.sons[0])
|
let s = bracketedMacro(n.sons[0])
|
||||||
|
|
@ -865,7 +865,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
|
||||||
|
|
||||||
const
|
const
|
||||||
tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
|
tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
|
||||||
tyDotOpTransparent = {tyVar, tyPtr, tyRef, tyAlias}
|
tyDotOpTransparent = {tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink}
|
||||||
|
|
||||||
proc readTypeParameter(c: PContext, typ: PType,
|
proc readTypeParameter(c: PContext, typ: PType,
|
||||||
paramName: PIdent, info: TLineInfo): PNode =
|
paramName: PIdent, info: TLineInfo): PNode =
|
||||||
|
|
@ -998,8 +998,8 @@ proc semSym(c: PContext, n: PNode, sym: 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, tyLent, tyPtr, tyRef,
|
||||||
tyAlias})
|
tyAlias, tySink})
|
||||||
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:
|
||||||
|
|
@ -1108,7 +1108,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
return nil
|
return nil
|
||||||
if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass:
|
if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass:
|
||||||
ty = ty.lastSon
|
ty = ty.lastSon
|
||||||
ty = skipTypes(ty, {tyGenericInst, tyVar, tyPtr, tyRef, tyAlias})
|
ty = skipTypes(ty, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
|
||||||
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:
|
||||||
|
|
@ -1175,7 +1175,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, tyAlias})
|
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyAlias, tySink})
|
||||||
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
|
||||||
|
|
@ -1195,7 +1195,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
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,
|
let arr = skipTypes(n.sons[0].typ, {tyGenericInst,
|
||||||
tyVar, tyPtr, tyRef, tyAlias})
|
tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
|
||||||
case arr.kind
|
case arr.kind
|
||||||
of tyArray, tyOpenArray, tyVarargs, tySequence, tyString,
|
of tyArray, tyOpenArray, tyVarargs, tySequence, tyString,
|
||||||
tyCString:
|
tyCString:
|
||||||
|
|
@ -1223,7 +1223,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
n.sons[0] = makeDeref(n.sons[0])
|
n.sons[0] = makeDeref(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, tyAlias}).kind in
|
if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal, tyAlias, tySink}).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)]
|
||||||
|
|
@ -1362,7 +1362,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, tyAlias}).kind != tyVar and
|
if (skipTypes(le, {tyGenericInst, tyAlias, tySink}).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!
|
||||||
|
|
@ -1455,18 +1455,18 @@ 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, tyAlias})
|
var t = skipTypes(restype, {tyGenericInst, tyAlias, tySink})
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyVar:
|
of tyVar, tyLent:
|
||||||
t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
if t.kind == tyVar: t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||||
if n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv}:
|
if n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv}:
|
||||||
n.sons[0] = n.sons[0].sons[1]
|
n.sons[0] = n.sons[0].sons[1]
|
||||||
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, tyAlias})
|
var e = skipTypes(t.sons[i], {tyGenericInst, tyAlias, tySink})
|
||||||
if e.kind == tyVar:
|
if e.kind in {tyVar, tyLent}:
|
||||||
e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
if e.kind == tyVar: e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||||
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])
|
||||||
elif n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv} and
|
elif n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv} and
|
||||||
|
|
@ -1956,17 +1956,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, tyAlias})
|
{tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
|
||||||
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, tyAlias})
|
{tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
|
||||||
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, tyAlias})
|
typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -408,7 +408,7 @@ 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, tyAlias}).kind == tyTypeDesc:
|
if x == nil or x.typ.skipTypes({tyGenericInst, tyAlias, tySink}).kind == tyTypeDesc:
|
||||||
return
|
return
|
||||||
|
|
||||||
var y = getConstExpr(m, n.sons[1])
|
var y = getConstExpr(m, n.sons[1])
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ proc uninstantiate(t: PType): PType =
|
||||||
else: t
|
else: t
|
||||||
|
|
||||||
proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode =
|
proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode =
|
||||||
const skippedTypes = {tyTypeDesc, tyAlias}
|
const skippedTypes = {tyTypeDesc, tyAlias, tySink}
|
||||||
let trait = traitCall[0]
|
let trait = traitCall[0]
|
||||||
internalAssert trait.kind == nkSym
|
internalAssert trait.kind == nkSym
|
||||||
var operand = operand.skipTypes(skippedTypes)
|
var operand = operand.skipTypes(skippedTypes)
|
||||||
|
|
@ -145,7 +145,7 @@ proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode =
|
||||||
of "stripGenericParams":
|
of "stripGenericParams":
|
||||||
result = uninstantiate(operand).toNode(traitCall.info)
|
result = uninstantiate(operand).toNode(traitCall.info)
|
||||||
of "supportsCopyMem":
|
of "supportsCopyMem":
|
||||||
let t = operand.skipTypes({tyVar, tyGenericInst, tyAlias, tyInferred})
|
let t = operand.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
|
||||||
let complexObj = containsGarbageCollectedRef(t) or
|
let complexObj = containsGarbageCollectedRef(t) or
|
||||||
hasDestructor(t)
|
hasDestructor(t)
|
||||||
result = newIntNodeT(ord(not complexObj), traitCall)
|
result = newIntNodeT(ord(not complexObj), traitCall)
|
||||||
|
|
|
||||||
|
|
@ -260,8 +260,8 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = newNodeIT(nkObjConstr, n.info, t)
|
result = newNodeIT(nkObjConstr, n.info, t)
|
||||||
for child in n: result.add child
|
for child in n: result.add child
|
||||||
|
|
||||||
t = skipTypes(t, {tyGenericInst, tyAlias})
|
t = skipTypes(t, {tyGenericInst, tyAlias, tySink})
|
||||||
if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias})
|
if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink})
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ proc semExprBranch(c: PContext, n: PNode): PNode =
|
||||||
if result.typ != nil:
|
if result.typ != nil:
|
||||||
# XXX tyGenericInst here?
|
# XXX tyGenericInst here?
|
||||||
semProcvarCheck(c, result)
|
semProcvarCheck(c, result)
|
||||||
if result.typ.kind == tyVar: result = newDeref(result)
|
if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
|
||||||
|
|
||||||
proc semExprBranchScope(c: PContext, n: PNode): PNode =
|
proc semExprBranchScope(c: PContext, n: PNode): PNode =
|
||||||
openScope(c)
|
openScope(c)
|
||||||
|
|
@ -446,18 +446,18 @@ proc makeDeref(n: PNode): PNode =
|
||||||
var t = n.typ
|
var t = n.typ
|
||||||
if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass:
|
if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass:
|
||||||
t = t.lastSon
|
t = t.lastSon
|
||||||
t = skipTypes(t, {tyGenericInst, tyAlias})
|
t = skipTypes(t, {tyGenericInst, tyAlias, tySink})
|
||||||
result = n
|
result = n
|
||||||
if t.kind == tyVar:
|
if t.kind in {tyVar, tyLent}:
|
||||||
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, tyAlias})
|
t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink})
|
||||||
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, tyAlias})
|
t = skipTypes(baseTyp, {tyGenericInst, tyAlias, tySink})
|
||||||
|
|
||||||
proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
|
proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
|
||||||
if n.len == 2:
|
if n.len == 2:
|
||||||
|
|
@ -533,7 +533,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
if typ == nil: continue
|
if typ == nil: continue
|
||||||
typeAllowedCheck(a.info, typ, symkind)
|
typeAllowedCheck(a.info, typ, symkind)
|
||||||
liftTypeBoundOps(c, typ, a.info)
|
liftTypeBoundOps(c, typ, a.info)
|
||||||
var tup = skipTypes(typ, {tyGenericInst, tyAlias})
|
var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
||||||
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")
|
||||||
|
|
@ -649,7 +649,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, tyAlias})
|
var iter = skipTypes(iterBase, {tyGenericInst, tyAlias, tySink})
|
||||||
# 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:
|
||||||
|
|
@ -683,7 +683,7 @@ proc semForVars(c: PContext, n: PNode): PNode =
|
||||||
proc implicitIterator(c: PContext, it: string, arg: PNode): PNode =
|
proc implicitIterator(c: PContext, it: string, arg: PNode): PNode =
|
||||||
result = newNodeI(nkCall, arg.info)
|
result = newNodeI(nkCall, arg.info)
|
||||||
result.add(newIdentNode(it.getIdent, arg.info))
|
result.add(newIdentNode(it.getIdent, arg.info))
|
||||||
if arg.typ != nil and arg.typ.kind == tyVar:
|
if arg.typ != nil and arg.typ.kind in {tyVar, tyLent}:
|
||||||
result.add newDeref(arg)
|
result.add newDeref(arg)
|
||||||
else:
|
else:
|
||||||
result.add arg
|
result.add arg
|
||||||
|
|
@ -880,11 +880,11 @@ proc checkCovariantParamsUsages(genericType: PType) =
|
||||||
for fieldType in t.sons:
|
for fieldType in t.sons:
|
||||||
subresult traverseSubTypes(fieldType)
|
subresult traverseSubTypes(fieldType)
|
||||||
|
|
||||||
of tyPtr, tyRef, tyVar:
|
of tyPtr, tyRef, tyVar, tyLent:
|
||||||
if t.base.kind == tyGenericParam: return true
|
if t.base.kind == tyGenericParam: return true
|
||||||
return traverseSubTypes(t.base)
|
return traverseSubTypes(t.base)
|
||||||
|
|
||||||
of tyDistinct, tyAlias:
|
of tyDistinct, tyAlias, tySink:
|
||||||
return traverseSubTypes(t.lastSon)
|
return traverseSubTypes(t.lastSon)
|
||||||
|
|
||||||
of tyGenericInst:
|
of tyGenericInst:
|
||||||
|
|
@ -994,8 +994,8 @@ proc checkForMetaFields(n: PNode) =
|
||||||
of nkSym:
|
of nkSym:
|
||||||
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, tyLent, tyPtr, tyRef,
|
||||||
tyProc, tyGenericInvocation, tyGenericInst, tyAlias:
|
tyProc, tyGenericInvocation, tyGenericInst, tyAlias, tySink:
|
||||||
let start = int ord(t.kind in {tyGenericInvocation, tyGenericInst})
|
let start = int 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])
|
||||||
|
|
@ -1020,7 +1020,7 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
|
||||||
# type aliases are hard:
|
# type aliases are hard:
|
||||||
var t = semTypeNode(c, x, nil)
|
var t = semTypeNode(c, x, nil)
|
||||||
assert t != nil
|
assert t != nil
|
||||||
if s.typ != nil and s.typ.kind != tyAlias:
|
if s.typ != nil and s.typ.kind notin {tyAlias, tySink}:
|
||||||
if t.kind in {tyProc, tyGenericInst} and not t.isMetaType:
|
if t.kind in {tyProc, tyGenericInst} and not t.isMetaType:
|
||||||
assignType(s.typ, t)
|
assignType(s.typ, t)
|
||||||
s.typ.id = t.id
|
s.typ.id = t.id
|
||||||
|
|
@ -1415,9 +1415,9 @@ proc semMethodPrototype(c: PContext; s: PSym; n: 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,
|
var x = skipTypes(t.sons[0], {tyVar, tyLent, tyPtr, tyRef, tyGenericInst,
|
||||||
tyGenericInvocation, tyGenericBody,
|
tyGenericInvocation, tyGenericBody,
|
||||||
tyAlias})
|
tyAlias, tySink})
|
||||||
if x.kind == tyObject and t.len-1 == n.sons[genericParamsPos].len:
|
if x.kind == tyObject and t.len-1 == n.sons[genericParamsPos].len:
|
||||||
foundObj = true
|
foundObj = true
|
||||||
x.methods.safeAdd((col,s))
|
x.methods.safeAdd((col,s))
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,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 in {tyGenericInst, tyAlias}: base = lastSon(base)
|
if base.kind in {tyGenericInst, tyAlias, tySink}: 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)
|
||||||
|
|
@ -153,7 +153,7 @@ 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, tyAlias}).kind notin {
|
if region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin {
|
||||||
tyError, tyObject}:
|
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)
|
||||||
|
|
@ -286,7 +286,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 in {tyGenericInst, tyAlias}: indxB = lastSon(indxB)
|
if indxB.kind in {tyGenericInst, tyAlias, tySink}: 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)
|
||||||
|
|
@ -673,7 +673,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, tyAlias}:
|
while result.kind in {tyGenericInst, tyGenericBody, tyRef, tyPtr, tyAlias, tySink}:
|
||||||
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,
|
||||||
|
|
@ -836,7 +836,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
result = liftingWalk(paramType.sons[0], true)
|
result = liftingWalk(paramType.sons[0], true)
|
||||||
|
|
||||||
of tySequence, tySet, tyArray, tyOpenArray,
|
of tySequence, tySet, tyArray, tyOpenArray,
|
||||||
tyVar, tyPtr, tyRef, tyProc:
|
tyVar, tyLent, tyPtr, tyRef, tyProc:
|
||||||
# XXX: this is a bit strange, but proc(s: seq)
|
# XXX: this is a bit strange, but proc(s: seq)
|
||||||
# produces tySequence(tyGenericParam, tyNone).
|
# produces tySequence(tyGenericParam, tyNone).
|
||||||
# This also seems to be true when creating aliases
|
# This also seems to be true when creating aliases
|
||||||
|
|
@ -992,7 +992,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, tyAlias}).kind == tyVoid:
|
elif skipTypes(typ, {tyGenericInst, tyAlias, tySink}).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)
|
||||||
|
|
@ -1024,7 +1024,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, tyAlias}).kind != tyVoid:
|
if skipTypes(r, {tyGenericInst, tyAlias, tySink}).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
|
||||||
|
|
@ -1335,7 +1335,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, tyAlias}).kind in NilableTypes+GenericTypes:
|
if result.skipTypes({tyGenericInst, tyAlias, tySink}).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)
|
||||||
|
|
@ -1363,7 +1363,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, tyAlias}).kind in NilableTypes+GenericTypes+{tyForward} and
|
if result.skipTypes({tyGenericInst, tyAlias, tySink}).kind in NilableTypes+GenericTypes+{tyForward} 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)
|
||||||
|
|
@ -1416,7 +1416,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
of mVar:
|
of mVar:
|
||||||
result = newOrPrevType(tyVar, prev, c)
|
result = newOrPrevType(tyVar, prev, c)
|
||||||
var base = semTypeNode(c, n.sons[1], nil)
|
var base = semTypeNode(c, n.sons[1], nil)
|
||||||
if base.kind == tyVar:
|
if base.kind in {tyVar, tyLent}:
|
||||||
localError(n.info, errVarVarTypeNotAllowed)
|
localError(n.info, errVarVarTypeNotAllowed)
|
||||||
base = base.sons[0]
|
base = base.sons[0]
|
||||||
addSonSkipIntLit(result, base)
|
addSonSkipIntLit(result, base)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ const
|
||||||
proc checkPartialConstructedType(info: TLineInfo, t: PType) =
|
proc checkPartialConstructedType(info: TLineInfo, t: PType) =
|
||||||
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
||||||
localError(info, errInvalidPragmaX, "acyclic")
|
localError(info, errInvalidPragmaX, "acyclic")
|
||||||
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
elif t.kind in {tyVar, tyLent} and t.sons[0].kind in {tyVar, tyLent}:
|
||||||
localError(info, errVarVarTypeNotAllowed)
|
localError(info, errVarVarTypeNotAllowed)
|
||||||
|
|
||||||
proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
||||||
|
|
@ -25,7 +25,7 @@ proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
||||||
if t.kind in tyTypeClasses: discard
|
if t.kind in tyTypeClasses: discard
|
||||||
elif tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
elif tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
||||||
localError(info, errInvalidPragmaX, "acyclic")
|
localError(info, errInvalidPragmaX, "acyclic")
|
||||||
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
elif t.kind in {tyVar, tyLent} and t.sons[0].kind in {tyVar, tyLent}:
|
||||||
localError(info, errVarVarTypeNotAllowed)
|
localError(info, errVarVarTypeNotAllowed)
|
||||||
elif computeSize(t) == szIllegalRecursion:
|
elif computeSize(t) == szIllegalRecursion:
|
||||||
localError(info, errIllegalRecursionInTypeX, typeToString(t))
|
localError(info, errIllegalRecursionInTypeX, typeToString(t))
|
||||||
|
|
@ -518,7 +518,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({tyAlias})
|
let r2 = r.skipTypes({tyAlias, tySink})
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,7 @@ proc suggestField(c: PContext, s: PSym; f: PNode; info: TLineInfo; outputs: var
|
||||||
|
|
||||||
proc getQuality(s: PSym): range[0..100] =
|
proc getQuality(s: PSym): range[0..100] =
|
||||||
if s.typ != nil and s.typ.len > 1:
|
if s.typ != nil and s.typ.len > 1:
|
||||||
var exp = s.typ.sons[1].skipTypes({tyGenericInst, tyVar, tyAlias})
|
var exp = s.typ.sons[1].skipTypes({tyGenericInst, tyVar, tyLent, tyAlias, tySink})
|
||||||
if exp.kind == tyVarargs: exp = elemType(exp)
|
if exp.kind == tyVarargs: exp = elemType(exp)
|
||||||
if exp.kind in {tyExpr, tyStmt, tyGenericParam, tyAnything}: return 50
|
if exp.kind in {tyExpr, tyStmt, tyGenericParam, tyAnything}: return 50
|
||||||
return 100
|
return 100
|
||||||
|
|
@ -309,7 +309,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, tyAlias})
|
var exp = s.typ.sons[1].skipTypes({tyGenericInst, tyVar, tyLent, tyAlias, tySink})
|
||||||
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)
|
||||||
|
|
@ -378,8 +378,8 @@ proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var Suggestions)
|
||||||
t = t.sons[0]
|
t = t.sons[0]
|
||||||
suggestOperations(c, n, field, typ, outputs)
|
suggestOperations(c, n, field, typ, outputs)
|
||||||
else:
|
else:
|
||||||
let orig = typ # skipTypes(typ, {tyGenericInst, tyAlias})
|
let orig = typ # skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
||||||
typ = skipTypes(typ, {tyGenericInst, tyVar, tyPtr, tyRef, tyAlias})
|
typ = skipTypes(typ, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
|
||||||
if typ.kind == tyObject:
|
if typ.kind == tyObject:
|
||||||
var t = typ
|
var t = typ
|
||||||
while true:
|
while true:
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,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, tyAlias})
|
r.typ = typ #skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
||||||
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:
|
||||||
|
|
@ -331,7 +331,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, tyAlias}).kind == tyTuple and
|
if skipTypes(e.typ, {tyGenericInst, tyAlias, tySink}).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:
|
||||||
|
|
@ -506,7 +506,7 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto =
|
||||||
if putArgInto(arg.sons[i], formal) != paDirectMapping: return
|
if putArgInto(arg.sons[i], formal) != paDirectMapping: return
|
||||||
result = paDirectMapping
|
result = paDirectMapping
|
||||||
else:
|
else:
|
||||||
if skipTypes(formal, abstractInst).kind == tyVar: result = paVarAsgn
|
if skipTypes(formal, abstractInst).kind in {tyVar, tyLent}: result = paVarAsgn
|
||||||
else: result = paFastAsgn
|
else: result = paFastAsgn
|
||||||
|
|
||||||
proc findWrongOwners(c: PTransf, n: PNode) =
|
proc findWrongOwners(c: PTransf, n: PNode) =
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,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, tyAlias})
|
let t = n.typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink})
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -51,17 +51,17 @@ 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, tyAlias, tyInferred}
|
tyTypeDesc, tyAlias, tyInferred, tySink, tyLent}
|
||||||
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc,
|
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc,
|
||||||
tyAlias, tyInferred}
|
tyAlias, tyInferred, tySink, tyLent}
|
||||||
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal, tyTypeDesc,
|
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal, tyTypeDesc,
|
||||||
tyAlias, tyInferred}
|
tyAlias, tyInferred, tySink}
|
||||||
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
|
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
|
||||||
tyTypeDesc, tyAlias, tyInferred}
|
tyTypeDesc, tyAlias, tyInferred, tySink}
|
||||||
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias,
|
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias,
|
||||||
tyInferred}
|
tyInferred, tySink}
|
||||||
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyTypeDesc, tyAlias,
|
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyTypeDesc, tyAlias,
|
||||||
tyInferred}
|
tyInferred, tySink, tyLent}
|
||||||
# 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}
|
||||||
|
|
@ -388,8 +388,8 @@ const
|
||||||
"int", "int8", "int16", "int32", "int64",
|
"int", "int8", "int16", "int32", "int64",
|
||||||
"float", "float32", "float64", "float128",
|
"float", "float32", "float64", "float128",
|
||||||
"uint", "uint8", "uint16", "uint32", "uint64",
|
"uint", "uint8", "uint16", "uint32", "uint64",
|
||||||
"unused0", "unused1",
|
"opt", "sink",
|
||||||
"unused2", "varargs[$1]", "unused", "Error Type",
|
"lent", "varargs[$1]", "unused", "Error Type",
|
||||||
"BuiltInTypeClass", "UserTypeClass",
|
"BuiltInTypeClass", "UserTypeClass",
|
||||||
"UserTypeClassInst", "CompositeTypeClass", "inferred",
|
"UserTypeClassInst", "CompositeTypeClass", "inferred",
|
||||||
"and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor",
|
"and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor",
|
||||||
|
|
@ -539,7 +539,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
add(result, typeToString(t.sons[i]))
|
add(result, typeToString(t.sons[i]))
|
||||||
if i < sonsLen(t) - 1: add(result, ", ")
|
if i < sonsLen(t) - 1: add(result, ", ")
|
||||||
add(result, ')')
|
add(result, ')')
|
||||||
of tyPtr, tyRef, tyVar:
|
of tyPtr, tyRef, tyVar, tyLent:
|
||||||
result = typeToStr[t.kind]
|
result = typeToStr[t.kind]
|
||||||
if t.len >= 2:
|
if t.len >= 2:
|
||||||
setLen(result, result.len-1)
|
setLen(result, result.len-1)
|
||||||
|
|
@ -968,7 +968,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,
|
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyLent, tySink,
|
||||||
tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyOpt:
|
tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyOpt:
|
||||||
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
|
||||||
|
|
@ -988,7 +988,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, tyAlias, tyInferred, tyLent, tySink:
|
of tyGenericInst, tyAlias, tyInferred:
|
||||||
cycleCheck()
|
cycleCheck()
|
||||||
result = sameTypeAux(a.lastSon, b.lastSon, c)
|
result = sameTypeAux(a.lastSon, b.lastSon, c)
|
||||||
of tyNone: result = false
|
of tyNone: result = false
|
||||||
|
|
@ -1101,11 +1101,11 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
if containsOrIncl(marker, typ.id): return
|
if containsOrIncl(marker, typ.id): return
|
||||||
var t = skipTypes(typ, abstractInst-{tyTypeDesc})
|
var t = skipTypes(typ, abstractInst-{tyTypeDesc})
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyVar:
|
of tyVar, tyLent:
|
||||||
if kind in {skProc, skFunc, skConst}: return t
|
if kind in {skProc, skFunc, skConst}: return t
|
||||||
var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
|
var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
|
||||||
case t2.kind
|
case t2.kind
|
||||||
of tyVar:
|
of tyVar, tyLent:
|
||||||
if taHeap notin flags: result = t2 # ``var var`` is illegal on the heap
|
if taHeap notin flags: result = t2 # ``var var`` is illegal on the heap
|
||||||
of tyOpenArray:
|
of tyOpenArray:
|
||||||
if kind != skParam: result = t
|
if kind != skParam: result = t
|
||||||
|
|
@ -1143,7 +1143,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
of tyRange:
|
of tyRange:
|
||||||
if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
|
if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
|
||||||
{tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t
|
{tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs, tySink:
|
||||||
if kind != skParam: result = t
|
if kind != skParam: result = t
|
||||||
else: result = typeAllowedAux(marker, t.sons[0], skVar, flags)
|
else: result = typeAllowedAux(marker, t.sons[0], skVar, flags)
|
||||||
of tySequence, tyOpt:
|
of tySequence, tyOpt:
|
||||||
|
|
@ -1174,7 +1174,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
# for now same as error node; we say it's a valid type as it should
|
# for now same as error node; we say it's a valid type as it should
|
||||||
# prevent cascading errors:
|
# prevent cascading errors:
|
||||||
result = nil
|
result = nil
|
||||||
of tyUnused, tyOptAsRef, tyUnused1, tyUnused2: internalError("typeAllowedAux")
|
of tyUnused, tyOptAsRef: internalError("typeAllowedAux")
|
||||||
|
|
||||||
proc typeAllowed*(t: PType, kind: TSymKind): PType =
|
proc typeAllowed*(t: PType, kind: TSymKind): PType =
|
||||||
# returns 'nil' on success and otherwise the part of the type that is
|
# returns 'nil' on success and otherwise the part of the type that is
|
||||||
|
|
@ -1322,7 +1322,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
|
||||||
if typ.callConv == ccClosure: result = 2 * ptrSize
|
if typ.callConv == ccClosure: result = 2 * ptrSize
|
||||||
else: result = ptrSize
|
else: result = ptrSize
|
||||||
a = ptrSize
|
a = ptrSize
|
||||||
of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyOpenArray:
|
of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyLent, tyOpenArray:
|
||||||
let base = typ.lastSon
|
let base = typ.lastSon
|
||||||
if base == typ or (base.kind == tyTuple and base.size==szIllegalRecursion):
|
if base == typ or (base.kind == tyTuple and base.size==szIllegalRecursion):
|
||||||
result = szIllegalRecursion
|
result = szIllegalRecursion
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,8 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
|
||||||
else:
|
else:
|
||||||
result = mapTypeToBracket("ref", mRef, t, info)
|
result = mapTypeToBracket("ref", mRef, t, info)
|
||||||
of tyVar: result = mapTypeToBracket("var", mVar, t, info)
|
of tyVar: result = mapTypeToBracket("var", mVar, t, info)
|
||||||
|
of tyLent: result = mapTypeToBracket("lent", mBuiltinType, t, info)
|
||||||
|
of tySink: result = mapTypeToBracket("sink", mBuiltinType, t, info)
|
||||||
of tySequence: result = mapTypeToBracket("seq", mSeq, t, info)
|
of tySequence: result = mapTypeToBracket("seq", mSeq, t, info)
|
||||||
of tyOpt: result = mapTypeToBracket("opt", mOpt, t, info)
|
of tyOpt: result = mapTypeToBracket("opt", mOpt, t, info)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
|
|
@ -274,7 +276,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
|
||||||
result.add atomicType("static", mNone)
|
result.add atomicType("static", mNone)
|
||||||
if t.n != nil:
|
if t.n != nil:
|
||||||
result.add t.n.copyTree
|
result.add t.n.copyTree
|
||||||
of tyUnused, tyOptAsRef, tyUnused1, tyUnused2: internalError("mapTypeToAstX")
|
of tyUnused, tyOptAsRef: internalError("mapTypeToAstX")
|
||||||
|
|
||||||
proc opMapTypeToAst*(t: PType; info: TLineInfo): PNode =
|
proc opMapTypeToAst*(t: PType; info: TLineInfo): PNode =
|
||||||
result = mapTypeToAstX(t, info, false, true)
|
result = mapTypeToAstX(t, info, false, true)
|
||||||
|
|
|
||||||
|
|
@ -1288,7 +1288,7 @@ proc whichAsgnOpc(n: PNode): TOpcode =
|
||||||
opcAsgnStr
|
opcAsgnStr
|
||||||
of tyFloat..tyFloat128:
|
of tyFloat..tyFloat128:
|
||||||
opcAsgnFloat
|
opcAsgnFloat
|
||||||
of tyRef, tyNil, tyVar:
|
of tyRef, tyNil, tyVar, tyLent:
|
||||||
opcAsgnRef
|
opcAsgnRef
|
||||||
else:
|
else:
|
||||||
opcAsgnComplex
|
opcAsgnComplex
|
||||||
|
|
@ -1481,7 +1481,7 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||||
cannotEval(n)
|
cannotEval(n)
|
||||||
|
|
||||||
template needsRegLoad(): untyped =
|
template needsRegLoad(): untyped =
|
||||||
gfAddrOf notin flags and fitsRegister(n.typ.skipTypes({tyVar}))
|
gfAddrOf notin flags and fitsRegister(n.typ.skipTypes({tyVar, tyLent}))
|
||||||
|
|
||||||
proc genArrAccess2(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
|
proc genArrAccess2(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
|
||||||
flags: TGenFlags) =
|
flags: TGenFlags) =
|
||||||
|
|
@ -1553,7 +1553,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||||
result = newNodeIT(nkFloatLit, info, t)
|
result = newNodeIT(nkFloatLit, info, t)
|
||||||
of tyCString, tyString:
|
of tyCString, tyString:
|
||||||
result = newNodeIT(nkStrLit, info, t)
|
result = newNodeIT(nkStrLit, info, t)
|
||||||
of tyVar, tyPointer, tyPtr, tySequence, tyExpr,
|
of tyVar, tyLent, tyPointer, tyPtr, tySequence, tyExpr,
|
||||||
tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil:
|
tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil:
|
||||||
result = newNodeIT(nkNilLit, info, t)
|
result = newNodeIT(nkNilLit, info, t)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
|
|
|
||||||
|
|
@ -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, tyAlias: storeAny(s, t.lastSon, a, stored)
|
of tyRange, tyGenericInst, tyAlias, tySink: 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, tyAlias: result = loadAny(p, t.lastSon, tab)
|
of tyRange, tyGenericInst, tyAlias, tySink: result = loadAny(p, t.lastSon, tab)
|
||||||
else:
|
else:
|
||||||
internalError "cannot marshal at compile-time " & t.typeToString
|
internalError "cannot marshal at compile-time " & t.typeToString
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ type
|
||||||
when defined(nimHasOpt):
|
when defined(nimHasOpt):
|
||||||
type opt*{.magic: "Opt".}[T]
|
type opt*{.magic: "Opt".}[T]
|
||||||
|
|
||||||
when defined(nimHasSink):
|
when defined(nimNewRuntime):
|
||||||
type sink*{.magic: "BuiltinType".}[T]
|
type sink*{.magic: "BuiltinType".}[T]
|
||||||
type lent*{.magic: "BuiltinType".}[T]
|
type lent*{.magic: "BuiltinType".}[T]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue