preparations for language extensions: 'sink' and 'lent' types

This commit is contained in:
Andreas Rumpf 2018-01-07 23:09:26 +01:00
commit e4081a7201
34 changed files with 183 additions and 178 deletions

View file

@ -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):

View file

@ -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.

View file

@ -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)

View file

@ -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:

View file

@ -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])

View file

@ -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)

View file

@ -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

View file

@ -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:

View file

@ -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) =

View file

@ -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)

View file

@ -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)

View file

@ -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))]

View file

@ -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 =

View file

@ -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")

View file

@ -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

View file

@ -102,8 +102,8 @@ proc commonType*(x, y: PType): PType =
# if expressions, etc.: # if expressions, etc.:
if x == nil: return x if x == nil: return x
if y == nil: return y if y == nil: return y
var a = skipTypes(x, {tyGenericInst, 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

View file

@ -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)

View file

@ -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)

View file

@ -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 =

View file

@ -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)

View file

@ -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])

View file

@ -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)

View file

@ -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

View file

@ -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))

View file

@ -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)

View file

@ -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

View file

@ -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:

View file

@ -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) =

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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:

View file

@ -102,7 +102,7 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet) =
else: else:
storeAny(s, t.lastSon, a[i], stored) storeAny(s, t.lastSon, a[i], stored)
s.add("]") s.add("]")
of tyRange, tyGenericInst, 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

View file

@ -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]