mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-14 03:25:54 +00:00
preparations for language extensions: 'sink' and 'lent' types
This commit is contained in:
@@ -49,7 +49,7 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
|
||||
if a.sons[0] != nil:
|
||||
result = isPartOfAux(a.sons[0].skipTypes(skipPtrs), 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)
|
||||
of tyArray, tySet, tyTuple:
|
||||
for i in countup(0, sonsLen(a) - 1):
|
||||
|
||||
@@ -640,7 +640,7 @@ type
|
||||
mNHint, mNWarning, mNError,
|
||||
mInstantiationInfo, mGetTypeInfo, mNGenSym,
|
||||
mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
|
||||
mException, mBultinType
|
||||
mException, mBuiltinType
|
||||
|
||||
# things that we can evaluate safely at compile time, even if not asked for it:
|
||||
const
|
||||
@@ -940,13 +940,13 @@ const
|
||||
tyGenericParam}
|
||||
|
||||
StructuralEquivTypes*: TTypeKinds = {tyNil, tyTuple, tyArray,
|
||||
tySet, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, tyOpenArray,
|
||||
tySet, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc, tyOpenArray,
|
||||
tyVarargs}
|
||||
|
||||
ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in::
|
||||
# var x = expr
|
||||
tyBool, tyChar, tyEnum, tyArray, tyObject,
|
||||
tySet, tyTuple, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc,
|
||||
tySet, tyTuple, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc,
|
||||
tyPointer,
|
||||
tyOpenArray, tyString, tyCString, tyInt..tyInt64, tyFloat..tyFloat128,
|
||||
tyUInt..tyUInt64}
|
||||
@@ -1427,7 +1427,7 @@ proc propagateToOwner*(owner, elem: PType) =
|
||||
owner.flags.incl tfHasMeta
|
||||
|
||||
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,
|
||||
tySequence, tyOpt, tySet, tyDistinct}:
|
||||
o2.flags.incl tfHasAsgn
|
||||
@@ -1435,7 +1435,7 @@ proc propagateToOwner*(owner, elem: PType) =
|
||||
|
||||
if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
|
||||
tyGenericInvocation, tyPtr}:
|
||||
let elemB = elem.skipTypes({tyGenericInst, tyAlias})
|
||||
let elemB = elem.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||
if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
|
||||
# for simplicity, we propagate this flag even to generics. We then
|
||||
# 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:
|
||||
result = p.prc.id == n.sym.owner.id
|
||||
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])
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
result = isInCurrentFrame(p, n.sons[1])
|
||||
@@ -331,7 +331,7 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): Rope =
|
||||
# skip the deref:
|
||||
var ri = ri[i]
|
||||
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:
|
||||
let x = if ri.kind == nkHiddenAddr: ri[0] else: ri
|
||||
if x.typ.kind == tyPtr:
|
||||
@@ -527,7 +527,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
|
||||
line(p, cpsStmts, pl)
|
||||
|
||||
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)
|
||||
elif e.sons[0].kind == nkSym and sfInfixCall in e.sons[0].sym.flags:
|
||||
genInfixCall(p, nil, e, d)
|
||||
@@ -538,7 +538,7 @@ proc genCall(p: BProc, e: PNode, d: var TLoc) =
|
||||
postStmtActions(p)
|
||||
|
||||
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)
|
||||
elif ri.sons[0].kind == nkSym and sfInfixCall in ri.sons[0].sym.flags:
|
||||
genInfixCall(p, le, ri, d)
|
||||
|
||||
@@ -149,7 +149,7 @@ proc getStorageLoc(n: PNode): TStorageLoc =
|
||||
else: result = OnUnknown
|
||||
of nkDerefExpr, nkHiddenDeref:
|
||||
case n.sons[0].typ.kind
|
||||
of tyVar: result = OnUnknown
|
||||
of tyVar, tyLent: result = OnUnknown
|
||||
of tyPtr: result = OnStack
|
||||
of tyRef: result = OnHeap
|
||||
else: internalError(n.info, "getStorageLoc")
|
||||
@@ -368,7 +368,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||
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))
|
||||
else: internalError("genAssignment: " & $ty.kind)
|
||||
|
||||
@@ -1707,7 +1707,7 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
|
||||
rope(magic)]), a.storage)
|
||||
|
||||
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):
|
||||
expr(p, e.sons[1], d)
|
||||
else:
|
||||
@@ -1783,7 +1783,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
"$# = #subInt64($#, $#);$n"]
|
||||
const fun: array[mInc..mDec, string] = ["$# = #addInt($#, $#);$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}:
|
||||
binaryStmt(p, e, d, opr[op])
|
||||
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[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,
|
||||
if underlying.kind == tyInt64: fun64[op] else: fun[op])
|
||||
putIntoDest(p, a, e.sons[1], "($#)($#)" % [
|
||||
@@ -2021,9 +2021,9 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||
var r = rdLoc(a)
|
||||
var nilCheck: Rope = nil
|
||||
var t = skipTypes(a.t, abstractInst)
|
||||
while t.kind in {tyVar, tyPtr, tyRef}:
|
||||
if t.kind != tyVar: nilCheck = r
|
||||
if t.kind != tyVar or not p.module.compileToCpp:
|
||||
while t.kind in {tyVar, tyLent, tyPtr, tyRef}:
|
||||
if t.kind notin {tyVar, tyLent}: nilCheck = r
|
||||
if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp:
|
||||
r = "(*$1)" % [r]
|
||||
t = skipTypes(t.lastSon, abstractInst)
|
||||
if not p.module.compileToCpp:
|
||||
@@ -2056,7 +2056,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
||||
var a: TLoc
|
||||
initLocExpr(p, arg, 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:
|
||||
add(r, "->Sup")
|
||||
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:
|
||||
# init(TFigure(my)) # where it is passed to a 'var TFigure'. We test
|
||||
# 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)
|
||||
linefmt(p, cpsStmts, "$1 = &$2;$n", rdLoc(d), r)
|
||||
else:
|
||||
@@ -2307,7 +2307,7 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope =
|
||||
of tyBool: result = rope"NIM_FALSE"
|
||||
of tyEnum, tyChar, tyInt..tyInt64, tyUInt..tyUInt64: result = rope"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:
|
||||
result = rope"NIM_NIL"
|
||||
of tyProc:
|
||||
|
||||
@@ -66,7 +66,8 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, typ: PType) =
|
||||
|
||||
var p = c.p
|
||||
case typ.kind
|
||||
of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred:
|
||||
of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred,
|
||||
tySink:
|
||||
genTraverseProc(c, accessor, lastSon(typ))
|
||||
of tyArray:
|
||||
let arraySize = lengthOrd(typ.sons[0])
|
||||
|
||||
@@ -119,7 +119,7 @@ proc scopeMangledParam(p: BProc; param: PSym) =
|
||||
|
||||
const
|
||||
irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation,
|
||||
tyDistinct, tyRange, tyStatic, tyAlias, tyInferred}
|
||||
tyDistinct, tyRange, tyStatic, tyAlias, tySink, tyInferred}
|
||||
|
||||
proc typeName(typ: PType): Rope =
|
||||
let typ = typ.skipTypes(irrelevantForBackend)
|
||||
@@ -139,7 +139,7 @@ proc getTypeName(m: BModule; typ: PType; sig: SigHash): Rope =
|
||||
t = t.lastSon
|
||||
else:
|
||||
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:
|
||||
typ.loc.r = typ.typeName & $sig
|
||||
else:
|
||||
@@ -170,7 +170,7 @@ proc mapType(typ: PType): TCTypeKind =
|
||||
internalAssert typ.isResolvedUserTypeClass
|
||||
return mapType(typ.lastSon)
|
||||
of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal,
|
||||
tyTypeDesc, tyAlias, tyInferred:
|
||||
tyTypeDesc, tyAlias, tySink, tyInferred:
|
||||
result = mapType(lastSon(typ))
|
||||
of tyEnum:
|
||||
if firstOrd(typ) < 0:
|
||||
@@ -183,7 +183,7 @@ proc mapType(typ: PType): TCTypeKind =
|
||||
of 8: result = ctInt64
|
||||
else: internalError("mapType")
|
||||
of tyRange: result = mapType(typ.sons[0])
|
||||
of tyPtr, tyVar, tyRef, tyOptAsRef:
|
||||
of tyPtr, tyVar, tyLent, tyRef, tyOptAsRef:
|
||||
var base = skipTypes(typ.lastSon, typedescInst)
|
||||
case base.kind
|
||||
of tyOpenArray, tyArray, tyVarargs: result = ctPtrToArray
|
||||
@@ -242,7 +242,7 @@ proc isInvalidReturnType(rettype: PType): bool =
|
||||
case mapType(rettype)
|
||||
of ctArray:
|
||||
result = not (skipTypes(rettype, typedescInst).kind in
|
||||
{tyVar, tyRef, tyPtr})
|
||||
{tyVar, tyLent, tyRef, tyPtr})
|
||||
of ctStruct:
|
||||
let t = skipTypes(rettype, typedescInst)
|
||||
if rettype.isImportedCppType or t.isImportedCppType: return false
|
||||
@@ -328,7 +328,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
|
||||
of tyStatic:
|
||||
if typ.n != nil: result = getSimpleTypeDesc(m, lastSon typ)
|
||||
else: internalError("tyStatic for getSimpleTypeDesc")
|
||||
of tyGenericInst, tyAlias:
|
||||
of tyGenericInst, tyAlias, tySink:
|
||||
result = getSimpleTypeDesc(m, lastSon typ)
|
||||
else: result = nil
|
||||
|
||||
@@ -348,7 +348,7 @@ proc getTypePre(m: BModule, typ: PType; sig: SigHash): Rope =
|
||||
if result == nil: result = cacheGetType(m.typeCache, sig)
|
||||
|
||||
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"))
|
||||
|
||||
proc getForwardStructFormat(m: BModule): string =
|
||||
@@ -396,7 +396,7 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): Rope =
|
||||
result = getTypeDescAux(m, t, check)
|
||||
|
||||
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}:
|
||||
result = OnStack
|
||||
else:
|
||||
@@ -430,11 +430,11 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
|
||||
add(params, param.loc.r)
|
||||
# declare the len field for open arrays:
|
||||
var arr = param.typ
|
||||
if arr.kind == tyVar: arr = arr.sons[0]
|
||||
if arr.kind in {tyVar, tyLent}: arr = arr.lastSon
|
||||
var j = 0
|
||||
while arr.kind in {tyOpenArray, tyVarargs}:
|
||||
# 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:
|
||||
addf(params, ", NI $1Len_$2", [param.loc.r, j.rope])
|
||||
inc(j)
|
||||
@@ -641,7 +641,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||
excl(check, t.id)
|
||||
return
|
||||
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
|
||||
compileToCpp(m): "&" else: "*"
|
||||
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)])
|
||||
else: addf(m.s[cfsTypes], "typedef NU8 $1[$2];$n",
|
||||
[result, rope(getSize(t))])
|
||||
of tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias,
|
||||
of tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias, tySink,
|
||||
tyUserTypeClass, tyUserTypeClassInst, tyInferred:
|
||||
result = getTypeDescAux(m, lastSon(t), check)
|
||||
else:
|
||||
@@ -1227,7 +1227,7 @@ proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||
m.g.typeInfoMarker[sig] = result
|
||||
case t.kind
|
||||
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)
|
||||
of tyStatic:
|
||||
if t.n != nil: result = genTypeInfo(m, lastSon t, info)
|
||||
|
||||
@@ -110,13 +110,13 @@ proc getUniqueType*(key: PType): PType =
|
||||
of tyDistinct:
|
||||
if key.deepCopy != nil: result = key
|
||||
else: result = getUniqueType(lastSon(key))
|
||||
of tyGenericInst, tyOrdinal, tyStatic, tyAlias, tyInferred:
|
||||
of tyGenericInst, tyOrdinal, tyStatic, tyAlias, tySink, tyInferred:
|
||||
result = getUniqueType(lastSon(key))
|
||||
#let obj = lastSon(key)
|
||||
#if obj.sym != nil and obj.sym.name.s == "TOption":
|
||||
# echo "for ", typeToString(key), " I returned "
|
||||
# debug result
|
||||
of tyPtr, tyRef, tyVar:
|
||||
of tyPtr, tyRef, tyVar, tyLent:
|
||||
let elemType = lastSon(key)
|
||||
if elemType.kind in {tyBool, tyChar, tyInt..tyUInt64}:
|
||||
# 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:
|
||||
aa = skipTypes(aa, {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
|
||||
bb = bb.lastSon
|
||||
else:
|
||||
|
||||
@@ -174,7 +174,7 @@ proc patchHead(n: PNode) =
|
||||
if n[1].typ.isNil:
|
||||
# XXX toptree crashes without this workaround. Figure out why.
|
||||
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) =
|
||||
if s.name.s == op and field != nil and field != s:
|
||||
n.sons[0].sym = field
|
||||
@@ -198,15 +198,15 @@ template genOp(opr, opname) =
|
||||
result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest))
|
||||
|
||||
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")
|
||||
|
||||
proc genCopy(t: PType; dest: PNode): PNode =
|
||||
let t = t.skipTypes({tyGenericInst, tyAlias})
|
||||
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||
genOp(t.assignment, "=")
|
||||
|
||||
proc genDestroy(t: PType; dest: PNode): PNode =
|
||||
let t = t.skipTypes({tyGenericInst, tyAlias})
|
||||
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||
genOp(t.destructor, "=destroy")
|
||||
|
||||
proc addTopVar(c: var Con; v: PNode) =
|
||||
|
||||
@@ -86,10 +86,10 @@ proc mapType(t: ast.PType): ptr libffi.TType =
|
||||
else: result = nil
|
||||
of tyFloat, tyFloat64: result = addr libffi.type_double
|
||||
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:
|
||||
result = addr libffi.type_pointer
|
||||
of tyDistinct, tyAlias:
|
||||
of tyDistinct, tyAlias, tySink:
|
||||
result = mapType(t.sons[0])
|
||||
else:
|
||||
result = nil
|
||||
@@ -112,12 +112,12 @@ template `+!`(x, y: untyped): untyped =
|
||||
proc packSize(v: PNode, typ: PType): int =
|
||||
## computes the size of the blob
|
||||
case typ.kind
|
||||
of tyPtr, tyRef, tyVar:
|
||||
of tyPtr, tyRef, tyVar, tyLent:
|
||||
if v.kind in {nkNilLit, nkPtrLit}:
|
||||
result = sizeof(pointer)
|
||||
else:
|
||||
result = sizeof(pointer) + packSize(v.sons[0], typ.lastSon)
|
||||
of tyDistinct, tyGenericInst, tyAlias:
|
||||
of tyDistinct, tyGenericInst, tyAlias, tySink:
|
||||
result = packSize(v, typ.sons[0])
|
||||
of tyArray:
|
||||
# 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))
|
||||
else:
|
||||
globalError(v.info, "cannot map pointer/proc value to FFI")
|
||||
of tyPtr, tyRef, tyVar:
|
||||
of tyPtr, tyRef, tyVar, tyLent:
|
||||
if v.kind == nkNilLit:
|
||||
# nothing to do since the memory is 0 initialized anyway
|
||||
discard
|
||||
@@ -231,7 +231,7 @@ proc pack(v: PNode, typ: PType, res: pointer) =
|
||||
packObject(v, typ, res)
|
||||
of tyNil:
|
||||
discard
|
||||
of tyDistinct, tyGenericInst, tyAlias:
|
||||
of tyDistinct, tyGenericInst, tyAlias, tySink:
|
||||
pack(v, typ.sons[0], res)
|
||||
else:
|
||||
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
|
||||
else:
|
||||
awi(nkPtrLit, cast[ByteAddress](p))
|
||||
of tyPtr, tyRef, tyVar:
|
||||
of tyPtr, tyRef, tyVar, tyLent:
|
||||
let p = rd(pointer, x)
|
||||
if p.isNil:
|
||||
setNil()
|
||||
@@ -388,14 +388,14 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
|
||||
aws(nkStrLit, $p)
|
||||
of tyNil:
|
||||
setNil()
|
||||
of tyDistinct, tyGenericInst, tyAlias:
|
||||
of tyDistinct, tyGenericInst, tyAlias, tySink:
|
||||
result = unpack(x, typ.lastSon, n)
|
||||
else:
|
||||
# XXX what to do with 'array' here?
|
||||
globalError(n.info, "cannot map value from FFI " & typeToString(typ))
|
||||
|
||||
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,
|
||||
tySequence}:
|
||||
result = newNodeIT(x.kind, x.info, destTyp)
|
||||
|
||||
@@ -173,7 +173,7 @@ const
|
||||
proc mapType(typ: PType): TJSTypeKind =
|
||||
let t = skipTypes(typ, abstractInst)
|
||||
case t.kind
|
||||
of tyVar, tyRef, tyPtr:
|
||||
of tyVar, tyRef, tyPtr, tyLent:
|
||||
if skipTypes(t.lastSon, abstractInst).kind in MappedToObject:
|
||||
result = etyObject
|
||||
else:
|
||||
@@ -196,14 +196,15 @@ proc mapType(typ: PType): TJSTypeKind =
|
||||
tyExpr, tyStmt, tyTypeDesc, tyBuiltInTypeClass, tyCompositeTypeClass,
|
||||
tyAnd, tyOr, tyNot, tyAnything, tyVoid:
|
||||
result = etyNone
|
||||
of tyGenericInst, tyInferred, tyAlias, tyUserTypeClass, tyUserTypeClassInst:
|
||||
of tyGenericInst, tyInferred, tyAlias, tyUserTypeClass, tyUserTypeClassInst,
|
||||
tySink:
|
||||
result = mapType(typ.lastSon)
|
||||
of tyStatic:
|
||||
if t.n != nil: result = mapType(lastSon t)
|
||||
else: result = etyNone
|
||||
of tyProc: result = etyProc
|
||||
of tyCString: result = etyString
|
||||
of tyUnused, tyOptAsRef, tyUnused1, tyUnused2: internalError("mapType")
|
||||
of tyUnused, tyOptAsRef: internalError("mapType")
|
||||
|
||||
proc mapType(p: PProc; typ: PType): TJSTypeKind =
|
||||
if p.target == targetPHP: result = etyObject
|
||||
@@ -869,8 +870,8 @@ proc generateHeader(p: PProc, typ: PType): Rope =
|
||||
add(result, name)
|
||||
add(result, "_Idx")
|
||||
elif not (i == 1 and param.name.s == "this"):
|
||||
let k = param.typ.skipTypes({tyGenericInst, tyAlias}).kind
|
||||
if k in {tyVar, tyRef, tyPtr, tyPointer}:
|
||||
let k = param.typ.skipTypes({tyGenericInst, tyAlias, tySink}).kind
|
||||
if k in {tyVar, tyRef, tyPtr, tyLent, tyPointer}:
|
||||
add(result, "&")
|
||||
add(result, "$")
|
||||
add(result, name)
|
||||
@@ -899,7 +900,7 @@ const
|
||||
|
||||
proc needsNoCopy(p: PProc; y: PNode): bool =
|
||||
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
|
||||
|
||||
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) =
|
||||
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
|
||||
of tyArray, tyOpenArray, tySequence, tyString, tyCString, tyVarargs:
|
||||
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, a.res)
|
||||
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:
|
||||
let tmp = getTemp(p)
|
||||
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)
|
||||
of tyFloat..tyFloat128:
|
||||
result = putToSeq("0.0", indirect)
|
||||
of tyRange, tyGenericInst, tyAlias:
|
||||
of tyRange, tyGenericInst, tyAlias, tySink:
|
||||
result = createVar(p, lastSon(typ), indirect)
|
||||
of tySet:
|
||||
result = putToSeq("{}" | "array()", indirect)
|
||||
@@ -1546,7 +1547,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||
createObjInitList(p, t, initIntSet(), initList)
|
||||
result = ("{$1}" | "array($#)") % [initList]
|
||||
if indirect: result = "[$1]" % [result]
|
||||
of tyVar, tyPtr, tyRef:
|
||||
of tyVar, tyPtr, tyLent, tyRef:
|
||||
if mapType(p, t) == etyBaseIndex:
|
||||
result = putToSeq("[null, 0]", indirect)
|
||||
else:
|
||||
@@ -1579,7 +1580,7 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
||||
let mname = mangleName(v, p.target)
|
||||
lineF(p, varCode & " = $3;$n" | "$$$2 = $3;$n",
|
||||
[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 ])
|
||||
else:
|
||||
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) =
|
||||
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)
|
||||
if tfFinal in t.flags:
|
||||
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 resVar = createVar(p, resultSym.typ, isIndirect(resultSym))
|
||||
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])
|
||||
gen(p, prc.ast.sons[resultPos], a)
|
||||
if mapType(p, resultSym.typ) == etyBaseIndex:
|
||||
@@ -2218,10 +2220,10 @@ proc genCast(p: PProc, n: PNode, r: var TCompRes) =
|
||||
if dest.kind == src.kind:
|
||||
# no-op conversion
|
||||
return
|
||||
let toInt = (dest.kind in tyInt .. tyInt32)
|
||||
let toUint = (dest.kind in tyUInt .. tyUInt32)
|
||||
let fromInt = (src.kind in tyInt .. tyInt32)
|
||||
let fromUint = (src.kind in tyUInt .. tyUInt32)
|
||||
let toInt = (dest.kind in tyInt..tyInt32)
|
||||
let toUint = (dest.kind in tyUInt..tyUInt32)
|
||||
let fromInt = (src.kind in tyInt..tyInt32)
|
||||
let fromUint = (src.kind in tyUInt..tyUInt32)
|
||||
|
||||
if toUint and (fromInt or fromUint):
|
||||
let trimmer = unsignedTrimmer(dest.size)
|
||||
|
||||
@@ -122,7 +122,7 @@ proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
|
||||
[name, genTypeInfo(p, typ.sons[0])])
|
||||
|
||||
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)]
|
||||
p.declareGlobal(t.id, result)
|
||||
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 =
|
||||
if p.target == targetPHP:
|
||||
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)]
|
||||
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
|
||||
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" %
|
||||
[result, rope(ord(t.kind))]
|
||||
prepend(p.g.typeInfo, s)
|
||||
of tyVar, tyRef, tyPtr, tySequence, tyRange, tySet:
|
||||
of tyVar, tyLent, tyRef, tyPtr, tySequence, tyRange, tySet:
|
||||
var s =
|
||||
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
|
||||
[result, rope(ord(t.kind))]
|
||||
|
||||
@@ -190,7 +190,7 @@ proc interestingVar(s: PSym): bool {.inline.} =
|
||||
|
||||
proc illegalCapture(s: PSym): bool {.inline.} =
|
||||
result = skipTypes(s.typ, abstractInst).kind in
|
||||
{tyVar, tyOpenArray, tyVarargs} or
|
||||
{tyVar, tyOpenArray, tyVarargs, tyLent} or
|
||||
s.kind == skResult
|
||||
|
||||
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'
|
||||
# for the stricter check and likewise we can skip 'seq' for a less
|
||||
# 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)
|
||||
|
||||
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
|
||||
# 'tyOpenArray':
|
||||
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")
|
||||
#elif containsTyRef(argType):
|
||||
# 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 skip(t: PType): PType =
|
||||
result = t
|
||||
while result.kind in {tyGenericInst, tyRange, tyVar, tyDistinct,
|
||||
tyOrdinal, tyAlias}:
|
||||
while result.kind in {tyGenericInst, tyRange, tyVar, tyLent, tyDistinct,
|
||||
tyOrdinal, tyAlias, tySink}:
|
||||
result = lastSon(result)
|
||||
if n.typ != nil and n.typ.skip.kind in {tyBool, tyEnum}:
|
||||
let enumfields = n.typ.skip.n
|
||||
|
||||
@@ -102,8 +102,8 @@ proc commonType*(x, y: PType): PType =
|
||||
# if expressions, etc.:
|
||||
if x == nil: return x
|
||||
if y == nil: return y
|
||||
var a = skipTypes(x, {tyGenericInst, tyAlias})
|
||||
var b = skipTypes(y, {tyGenericInst, tyAlias})
|
||||
var a = skipTypes(x, {tyGenericInst, tyAlias, tySink})
|
||||
var b = skipTypes(y, {tyGenericInst, tyAlias, tySink})
|
||||
result = x
|
||||
if a.kind in {tyExpr, tyNil}: result = y
|
||||
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:
|
||||
internalError(c.info, "assignment requested for type: " & typeToString(t))
|
||||
of tyOrdinal, tyRange, tyInferred,
|
||||
tyGenericInst, tyStatic, tyVar, tyAlias:
|
||||
tyGenericInst, tyStatic, tyVar, tyLent, tyAlias, tySink:
|
||||
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 =
|
||||
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 =
|
||||
let t = typ.skipTypes({tyGenericInst, tyVar, tyAlias})
|
||||
let t = typ.skipTypes({tyGenericInst, tyVar, tyLent, tyAlias, tySink})
|
||||
result = t.assignment
|
||||
if result.isNil:
|
||||
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.} =
|
||||
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 =
|
||||
result = newNodeI(nkHiddenDeref, n.info)
|
||||
|
||||
@@ -259,19 +259,19 @@ proc makePtrType*(c: PContext, baseType: PType): PType =
|
||||
proc makeTypeWithModifier*(c: PContext,
|
||||
modifier: TTypeKind,
|
||||
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
|
||||
else:
|
||||
result = newTypeS(modifier, c)
|
||||
addSonSkipIntLit(result, baseType.assertNotNil)
|
||||
|
||||
proc makeVarType*(c: PContext, baseType: PType): PType =
|
||||
if baseType.kind == tyVar:
|
||||
proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType =
|
||||
if baseType.kind == kind:
|
||||
result = baseType
|
||||
else:
|
||||
result = newTypeS(tyVar, c)
|
||||
result = newTypeS(kind, c)
|
||||
addSonSkipIntLit(result, baseType.assertNotNil)
|
||||
|
||||
proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
||||
|
||||
@@ -32,7 +32,7 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
# XXX tyGenericInst here?
|
||||
if result.typ.kind == tyProc and tfUnresolved in result.typ.flags:
|
||||
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 != {}:
|
||||
result.typ = newTypeS(tyVoid, c)
|
||||
else:
|
||||
@@ -52,7 +52,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
result.typ = errorType(c)
|
||||
else:
|
||||
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 =
|
||||
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):
|
||||
changeType(n.sons[i], elemType(newType), check)
|
||||
of nkPar:
|
||||
let tup = newType.skipTypes({tyGenericInst, tyAlias})
|
||||
let tup = newType.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||
if tup.kind != tyTuple:
|
||||
if tup.kind == tyObject: return
|
||||
globalError(n.info, "no tuple type for constructor")
|
||||
@@ -393,7 +393,7 @@ proc arrayConstrType(c: PContext, n: PNode): PType =
|
||||
if sonsLen(n) == 0:
|
||||
rawAddSon(typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
|
||||
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)
|
||||
typ.sons[0] = makeRangeType(c, 0, sonsLen(n) - 1, n.info)
|
||||
result = typ
|
||||
@@ -417,7 +417,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
let yy = semExprWithType(c, x)
|
||||
var typ = yy.typ
|
||||
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):
|
||||
x = n.sons[i]
|
||||
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
||||
@@ -471,7 +471,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
|
||||
of nkSym:
|
||||
# n.sym.typ can be nil in 'check' mode ...
|
||||
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)
|
||||
result = newHiddenAddrTaken(c, n)
|
||||
of nkDotExpr:
|
||||
@@ -479,12 +479,12 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
|
||||
if n.sons[1].kind != nkSym:
|
||||
internalError(n.info, "analyseIfAddressTaken")
|
||||
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)
|
||||
result = newHiddenAddrTaken(c, n)
|
||||
of nkBracketExpr:
|
||||
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)
|
||||
result = newHiddenAddrTaken(c, n)
|
||||
else:
|
||||
@@ -499,7 +499,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
|
||||
|
||||
# get the real type of the callee
|
||||
# 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:
|
||||
# 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:
|
||||
n.sons[0] = semExpr(c, n.sons[0], {efInCall})
|
||||
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])
|
||||
elif n.sons[0].kind == nkBracketExpr:
|
||||
let s = bracketedMacro(n.sons[0])
|
||||
@@ -865,7 +865,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
|
||||
|
||||
const
|
||||
tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
|
||||
tyDotOpTransparent = {tyVar, tyPtr, tyRef, tyAlias}
|
||||
tyDotOpTransparent = {tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink}
|
||||
|
||||
proc readTypeParameter(c: PContext, typ: PType,
|
||||
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:
|
||||
p = p.next
|
||||
if p != nil and p.selfSym != nil:
|
||||
var ty = skipTypes(p.selfSym.typ, {tyGenericInst, tyVar, tyPtr, tyRef,
|
||||
tyAlias})
|
||||
var ty = skipTypes(p.selfSym.typ, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef,
|
||||
tyAlias, tySink})
|
||||
while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct})
|
||||
var check: PNode = nil
|
||||
if ty.kind == tyObject:
|
||||
@@ -1108,7 +1108,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
return nil
|
||||
if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass:
|
||||
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})
|
||||
var check: PNode = nil
|
||||
if ty.kind == tyObject:
|
||||
@@ -1175,7 +1175,7 @@ proc semDeref(c: PContext, n: PNode): PNode =
|
||||
checkSonsLen(n, 1)
|
||||
n.sons[0] = semExprWithType(c, n.sons[0])
|
||||
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
|
||||
of tyRef, tyPtr: n.typ = t.lastSon
|
||||
else: result = nil
|
||||
@@ -1195,7 +1195,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
n.sons[0] = semExprWithType(c, n.sons[0],
|
||||
{efNoProcvarCheck, efNoEvaluateGeneric})
|
||||
let arr = skipTypes(n.sons[0].typ, {tyGenericInst,
|
||||
tyVar, tyPtr, tyRef, tyAlias})
|
||||
tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
|
||||
case arr.kind
|
||||
of tyArray, tyOpenArray, tyVarargs, tySequence, tyString,
|
||||
tyCString:
|
||||
@@ -1223,7 +1223,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
n.sons[0] = makeDeref(n.sons[0])
|
||||
# [] operator for tuples requires constant expression:
|
||||
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}:
|
||||
var idx = getOrdValue(n.sons[1])
|
||||
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 # b no 'var T' means: a = addr(b)
|
||||
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
|
||||
skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}:
|
||||
# Direct assignment to a discriminant is allowed!
|
||||
@@ -1455,18 +1455,18 @@ proc semProcBody(c: PContext, n: PNode): PNode =
|
||||
closeScope(c)
|
||||
|
||||
proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
|
||||
var t = skipTypes(restype, {tyGenericInst, tyAlias})
|
||||
var t = skipTypes(restype, {tyGenericInst, tyAlias, tySink})
|
||||
case t.kind
|
||||
of tyVar:
|
||||
t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||
of tyVar, tyLent:
|
||||
if t.kind == tyVar: t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||
if n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv}:
|
||||
n.sons[0] = n.sons[0].sons[1]
|
||||
n.sons[0] = takeImplicitAddr(c, n.sons[0])
|
||||
of tyTuple:
|
||||
for i in 0..<t.sonsLen:
|
||||
var e = skipTypes(t.sons[i], {tyGenericInst, tyAlias})
|
||||
if e.kind == tyVar:
|
||||
e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||
var e = skipTypes(t.sons[i], {tyGenericInst, tyAlias, tySink})
|
||||
if e.kind in {tyVar, tyLent}:
|
||||
if e.kind == tyVar: e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||
if n.sons[0].kind == nkPar:
|
||||
n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i])
|
||||
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])
|
||||
if typ == nil:
|
||||
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
|
||||
elif n.sons[i].kind == nkRange:
|
||||
# already semchecked
|
||||
if typ == nil:
|
||||
typ = skipTypes(n.sons[i].sons[0].typ,
|
||||
{tyGenericInst, tyVar, tyOrdinal, tyAlias})
|
||||
{tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
|
||||
else:
|
||||
n.sons[i] = semExprWithType(c, n.sons[i])
|
||||
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):
|
||||
localError(n.info, errOrdinalTypeExpected)
|
||||
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 =
|
||||
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
|
||||
|
||||
var y = getConstExpr(m, n.sons[1])
|
||||
|
||||
@@ -108,7 +108,7 @@ proc uninstantiate(t: PType): PType =
|
||||
else: t
|
||||
|
||||
proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode =
|
||||
const skippedTypes = {tyTypeDesc, tyAlias}
|
||||
const skippedTypes = {tyTypeDesc, tyAlias, tySink}
|
||||
let trait = traitCall[0]
|
||||
internalAssert trait.kind == nkSym
|
||||
var operand = operand.skipTypes(skippedTypes)
|
||||
@@ -145,7 +145,7 @@ proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode =
|
||||
of "stripGenericParams":
|
||||
result = uninstantiate(operand).toNode(traitCall.info)
|
||||
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
|
||||
hasDestructor(t)
|
||||
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)
|
||||
for child in n: result.add child
|
||||
|
||||
t = skipTypes(t, {tyGenericInst, tyAlias})
|
||||
if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias})
|
||||
t = skipTypes(t, {tyGenericInst, tyAlias, tySink})
|
||||
if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink})
|
||||
if t.kind != tyObject:
|
||||
localError(n.info, errGenerated, "object constructor needs an object type")
|
||||
return
|
||||
|
||||
@@ -102,7 +102,7 @@ proc semExprBranch(c: PContext, n: PNode): PNode =
|
||||
if result.typ != nil:
|
||||
# XXX tyGenericInst here?
|
||||
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 =
|
||||
openScope(c)
|
||||
@@ -446,18 +446,18 @@ proc makeDeref(n: PNode): PNode =
|
||||
var t = n.typ
|
||||
if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass:
|
||||
t = t.lastSon
|
||||
t = skipTypes(t, {tyGenericInst, tyAlias})
|
||||
t = skipTypes(t, {tyGenericInst, tyAlias, tySink})
|
||||
result = n
|
||||
if t.kind == tyVar:
|
||||
if t.kind in {tyVar, tyLent}:
|
||||
result = newNodeIT(nkHiddenDeref, n.info, t.sons[0])
|
||||
addSon(result, n)
|
||||
t = skipTypes(t.sons[0], {tyGenericInst, tyAlias})
|
||||
t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink})
|
||||
while t.kind in {tyPtr, tyRef}:
|
||||
var a = result
|
||||
let baseTyp = t.lastSon
|
||||
result = newNodeIT(nkHiddenDeref, n.info, baseTyp)
|
||||
addSon(result, a)
|
||||
t = skipTypes(baseTyp, {tyGenericInst, tyAlias})
|
||||
t = skipTypes(baseTyp, {tyGenericInst, tyAlias, tySink})
|
||||
|
||||
proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
|
||||
if n.len == 2:
|
||||
@@ -533,7 +533,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
if typ == nil: continue
|
||||
typeAllowedCheck(a.info, typ, symkind)
|
||||
liftTypeBoundOps(c, typ, a.info)
|
||||
var tup = skipTypes(typ, {tyGenericInst, tyAlias})
|
||||
var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
||||
if a.kind == nkVarTuple:
|
||||
if tup.kind != tyTuple:
|
||||
localError(a.info, errXExpected, "tuple")
|
||||
@@ -649,7 +649,7 @@ proc semForVars(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
var length = sonsLen(n)
|
||||
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
|
||||
# and thus no tuple unpacking:
|
||||
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 =
|
||||
result = newNodeI(nkCall, 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)
|
||||
else:
|
||||
result.add arg
|
||||
@@ -880,11 +880,11 @@ proc checkCovariantParamsUsages(genericType: PType) =
|
||||
for fieldType in t.sons:
|
||||
subresult traverseSubTypes(fieldType)
|
||||
|
||||
of tyPtr, tyRef, tyVar:
|
||||
of tyPtr, tyRef, tyVar, tyLent:
|
||||
if t.base.kind == tyGenericParam: return true
|
||||
return traverseSubTypes(t.base)
|
||||
|
||||
of tyDistinct, tyAlias:
|
||||
of tyDistinct, tyAlias, tySink:
|
||||
return traverseSubTypes(t.lastSon)
|
||||
|
||||
of tyGenericInst:
|
||||
@@ -994,8 +994,8 @@ proc checkForMetaFields(n: PNode) =
|
||||
of nkSym:
|
||||
let t = n.sym.typ
|
||||
case t.kind
|
||||
of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyPtr, tyRef,
|
||||
tyProc, tyGenericInvocation, tyGenericInst, tyAlias:
|
||||
of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyLent, tyPtr, tyRef,
|
||||
tyProc, tyGenericInvocation, tyGenericInst, tyAlias, tySink:
|
||||
let start = int ord(t.kind in {tyGenericInvocation, tyGenericInst})
|
||||
for i in start ..< t.sons.len:
|
||||
checkMeta(t.sons[i])
|
||||
@@ -1020,7 +1020,7 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
|
||||
# type aliases are hard:
|
||||
var t = semTypeNode(c, x, 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:
|
||||
assignType(s.typ, t)
|
||||
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):
|
||||
let t = tt.sons[col]
|
||||
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,
|
||||
tyAlias})
|
||||
tyAlias, tySink})
|
||||
if x.kind == tyObject and t.len-1 == n.sons[genericParamsPos].len:
|
||||
foundObj = true
|
||||
x.methods.safeAdd((col,s))
|
||||
|
||||
@@ -101,7 +101,7 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType =
|
||||
if sonsLen(n) == 2:
|
||||
var base = semTypeNode(c, n.sons[1], nil)
|
||||
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 not isOrdinalType(base):
|
||||
localError(n.info, errOrdinalTypeExpected)
|
||||
@@ -153,7 +153,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
|
||||
isNilable = true
|
||||
else:
|
||||
let region = semTypeNode(c, ni, nil)
|
||||
if region.skipTypes({tyGenericInst, tyAlias}).kind notin {
|
||||
if region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin {
|
||||
tyError, tyObject}:
|
||||
message n[i].info, errGenerated, "region needs to be an object type"
|
||||
addSonSkipIntLit(result, region)
|
||||
@@ -286,7 +286,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
||||
# 3 = length(array indx base)
|
||||
let indx = semArrayIndex(c, n[1])
|
||||
var indxB = indx
|
||||
if indxB.kind in {tyGenericInst, tyAlias}: indxB = lastSon(indxB)
|
||||
if indxB.kind in {tyGenericInst, tyAlias, tySink}: indxB = lastSon(indxB)
|
||||
if indxB.kind notin {tyGenericParam, tyStatic, tyFromExpr}:
|
||||
if not isOrdinalType(indxB):
|
||||
localError(n.sons[1].info, errOrdinalTypeExpected)
|
||||
@@ -673,7 +673,7 @@ proc skipGenericInvocation(t: PType): PType {.inline.} =
|
||||
result = t
|
||||
if result.kind == tyGenericInvocation:
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
of tySequence, tySet, tyArray, tyOpenArray,
|
||||
tyVar, tyPtr, tyRef, tyProc:
|
||||
tyVar, tyLent, tyPtr, tyRef, tyProc:
|
||||
# XXX: this is a bit strange, but proc(s: seq)
|
||||
# produces tySequence(tyGenericParam, tyNone).
|
||||
# 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 kind in {skTemplate, skMacro}:
|
||||
typ = newTypeS(tyExpr, c)
|
||||
elif skipTypes(typ, {tyGenericInst, tyAlias}).kind == tyVoid:
|
||||
elif skipTypes(typ, {tyGenericInst, tyAlias, tySink}).kind == tyVoid:
|
||||
continue
|
||||
for j in countup(0, length-3):
|
||||
var arg = newSymG(skParam, a.sons[j], c)
|
||||
@@ -1024,7 +1024,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||
if r != nil:
|
||||
# turn explicit 'void' return type into 'nil' because the rest of the
|
||||
# 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:
|
||||
if r.kind == tyAnything:
|
||||
# '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)
|
||||
elif n[0].kind == nkNilLit and n.len == 2:
|
||||
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:
|
||||
result = freshType(result, prev)
|
||||
result.flags.excl(tfNotNil)
|
||||
@@ -1363,7 +1363,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
case n.len
|
||||
of 3:
|
||||
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:
|
||||
result = freshType(result, prev)
|
||||
result.flags.incl(tfNotNil)
|
||||
@@ -1416,7 +1416,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
of mVar:
|
||||
result = newOrPrevType(tyVar, prev, c)
|
||||
var base = semTypeNode(c, n.sons[1], nil)
|
||||
if base.kind == tyVar:
|
||||
if base.kind in {tyVar, tyLent}:
|
||||
localError(n.info, errVarVarTypeNotAllowed)
|
||||
base = base.sons[0]
|
||||
addSonSkipIntLit(result, base)
|
||||
|
||||
@@ -17,7 +17,7 @@ const
|
||||
proc checkPartialConstructedType(info: TLineInfo, t: PType) =
|
||||
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
||||
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)
|
||||
|
||||
proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
||||
@@ -25,7 +25,7 @@ proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
||||
if t.kind in tyTypeClasses: discard
|
||||
elif tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
||||
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)
|
||||
elif computeSize(t) == szIllegalRecursion:
|
||||
localError(info, errIllegalRecursionInTypeX, typeToString(t))
|
||||
@@ -518,7 +518,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
var r = replaceTypeVarsT(cl, result.sons[i])
|
||||
if result.kind == tyObject:
|
||||
# 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}:
|
||||
r = skipTypes(r2, {tyPtr, tyRef})
|
||||
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] =
|
||||
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 in {tyExpr, tyStmt, tyGenericParam, tyAnything}: return 50
|
||||
return 100
|
||||
@@ -309,7 +309,7 @@ proc typeFits(c: PContext, s: PSym, firstArg: PType): bool {.inline.} =
|
||||
let m = s.getModule()
|
||||
if m != nil and sfSystemModule in m.flags:
|
||||
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 in {tyExpr, tyStmt, tyGenericParam, tyAnything}: return
|
||||
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]
|
||||
suggestOperations(c, n, field, typ, outputs)
|
||||
else:
|
||||
let orig = typ # skipTypes(typ, {tyGenericInst, tyAlias})
|
||||
typ = skipTypes(typ, {tyGenericInst, tyVar, tyPtr, tyRef, tyAlias})
|
||||
let orig = typ # skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
||||
typ = skipTypes(typ, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
|
||||
if typ.kind == tyObject:
|
||||
var t = typ
|
||||
while true:
|
||||
|
||||
@@ -93,7 +93,7 @@ proc getCurrOwner(c: PTransf): PSym =
|
||||
|
||||
proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PNode =
|
||||
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)
|
||||
let owner = getCurrOwner(c)
|
||||
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
|
||||
# and thus no tuple unpacking:
|
||||
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:
|
||||
e = skipConv(e)
|
||||
if e.kind == nkPar:
|
||||
@@ -506,7 +506,7 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto =
|
||||
if putArgInto(arg.sons[i], formal) != paDirectMapping: return
|
||||
result = paDirectMapping
|
||||
else:
|
||||
if skipTypes(formal, abstractInst).kind == tyVar: result = paVarAsgn
|
||||
if skipTypes(formal, abstractInst).kind in {tyVar, tyLent}: result = paVarAsgn
|
||||
else: result = paFastAsgn
|
||||
|
||||
proc findWrongOwners(c: PTransf, n: PNode) =
|
||||
|
||||
@@ -102,7 +102,7 @@ proc isDeepConstExpr*(n: PNode): bool =
|
||||
if not isDeepConstExpr(n.sons[i]): return false
|
||||
if n.typ.isNil: result = true
|
||||
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 != tyObject or not isCaseObj(t.n):
|
||||
result = true
|
||||
|
||||
@@ -51,17 +51,17 @@ const
|
||||
# TODO: Remove tyTypeDesc from each abstractX and (where necessary)
|
||||
# replace with typedescX
|
||||
abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal,
|
||||
tyTypeDesc, tyAlias, tyInferred}
|
||||
tyTypeDesc, tyAlias, tyInferred, tySink, tyLent}
|
||||
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc,
|
||||
tyAlias, tyInferred}
|
||||
tyAlias, tyInferred, tySink, tyLent}
|
||||
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal, tyTypeDesc,
|
||||
tyAlias, tyInferred}
|
||||
tyAlias, tyInferred, tySink}
|
||||
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
|
||||
tyTypeDesc, tyAlias, tyInferred}
|
||||
tyTypeDesc, tyAlias, tyInferred, tySink}
|
||||
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias,
|
||||
tyInferred}
|
||||
tyInferred, tySink}
|
||||
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyTypeDesc, tyAlias,
|
||||
tyInferred}
|
||||
tyInferred, tySink, tyLent}
|
||||
# typedescX is used if we're sure tyTypeDesc should be included (or skipped)
|
||||
typedescPtrs* = abstractPtrs + {tyTypeDesc}
|
||||
typedescInst* = abstractInst + {tyTypeDesc}
|
||||
@@ -388,8 +388,8 @@ const
|
||||
"int", "int8", "int16", "int32", "int64",
|
||||
"float", "float32", "float64", "float128",
|
||||
"uint", "uint8", "uint16", "uint32", "uint64",
|
||||
"unused0", "unused1",
|
||||
"unused2", "varargs[$1]", "unused", "Error Type",
|
||||
"opt", "sink",
|
||||
"lent", "varargs[$1]", "unused", "Error Type",
|
||||
"BuiltInTypeClass", "UserTypeClass",
|
||||
"UserTypeClassInst", "CompositeTypeClass", "inferred",
|
||||
"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]))
|
||||
if i < sonsLen(t) - 1: add(result, ", ")
|
||||
add(result, ')')
|
||||
of tyPtr, tyRef, tyVar:
|
||||
of tyPtr, tyRef, tyVar, tyLent:
|
||||
result = typeToStr[t.kind]
|
||||
if t.len >= 2:
|
||||
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:
|
||||
result = a.sym.position == b.sym.position
|
||||
of tyGenericInvocation, tyGenericBody, tySequence,
|
||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar,
|
||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyLent, tySink,
|
||||
tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyOpt:
|
||||
cycleCheck()
|
||||
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
|
||||
sameValue(a.n.sons[0], b.n.sons[0]) and
|
||||
sameValue(a.n.sons[1], b.n.sons[1])
|
||||
of tyGenericInst, tyAlias, tyInferred, tyLent, tySink:
|
||||
of tyGenericInst, tyAlias, tyInferred:
|
||||
cycleCheck()
|
||||
result = sameTypeAux(a.lastSon, b.lastSon, c)
|
||||
of tyNone: result = false
|
||||
@@ -1101,11 +1101,11 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||
if containsOrIncl(marker, typ.id): return
|
||||
var t = skipTypes(typ, abstractInst-{tyTypeDesc})
|
||||
case t.kind
|
||||
of tyVar:
|
||||
of tyVar, tyLent:
|
||||
if kind in {skProc, skFunc, skConst}: return t
|
||||
var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
|
||||
case t2.kind
|
||||
of tyVar:
|
||||
of tyVar, tyLent:
|
||||
if taHeap notin flags: result = t2 # ``var var`` is illegal on the heap
|
||||
of tyOpenArray:
|
||||
if kind != skParam: result = t
|
||||
@@ -1143,7 +1143,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||
of tyRange:
|
||||
if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
|
||||
{tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t
|
||||
of tyOpenArray, tyVarargs:
|
||||
of tyOpenArray, tyVarargs, tySink:
|
||||
if kind != skParam: result = t
|
||||
else: result = typeAllowedAux(marker, t.sons[0], skVar, flags)
|
||||
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
|
||||
# prevent cascading errors:
|
||||
result = nil
|
||||
of tyUnused, tyOptAsRef, tyUnused1, tyUnused2: internalError("typeAllowedAux")
|
||||
of tyUnused, tyOptAsRef: internalError("typeAllowedAux")
|
||||
|
||||
proc typeAllowed*(t: PType, kind: TSymKind): PType =
|
||||
# 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
|
||||
else: result = 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
|
||||
if base == typ or (base.kind == tyTuple and base.size==szIllegalRecursion):
|
||||
result = szIllegalRecursion
|
||||
|
||||
@@ -209,6 +209,8 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
|
||||
else:
|
||||
result = mapTypeToBracket("ref", mRef, 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 tyOpt: result = mapTypeToBracket("opt", mOpt, t, info)
|
||||
of tyProc:
|
||||
@@ -274,7 +276,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
|
||||
result.add atomicType("static", mNone)
|
||||
if t.n != nil:
|
||||
result.add t.n.copyTree
|
||||
of tyUnused, tyOptAsRef, tyUnused1, tyUnused2: internalError("mapTypeToAstX")
|
||||
of tyUnused, tyOptAsRef: internalError("mapTypeToAstX")
|
||||
|
||||
proc opMapTypeToAst*(t: PType; info: TLineInfo): PNode =
|
||||
result = mapTypeToAstX(t, info, false, true)
|
||||
|
||||
@@ -1288,7 +1288,7 @@ proc whichAsgnOpc(n: PNode): TOpcode =
|
||||
opcAsgnStr
|
||||
of tyFloat..tyFloat128:
|
||||
opcAsgnFloat
|
||||
of tyRef, tyNil, tyVar:
|
||||
of tyRef, tyNil, tyVar, tyLent:
|
||||
opcAsgnRef
|
||||
else:
|
||||
opcAsgnComplex
|
||||
@@ -1481,7 +1481,7 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
cannotEval(n)
|
||||
|
||||
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;
|
||||
flags: TGenFlags) =
|
||||
@@ -1553,7 +1553,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||
result = newNodeIT(nkFloatLit, info, t)
|
||||
of tyCString, tyString:
|
||||
result = newNodeIT(nkStrLit, info, t)
|
||||
of tyVar, tyPointer, tyPtr, tySequence, tyExpr,
|
||||
of tyVar, tyLent, tyPointer, tyPtr, tySequence, tyExpr,
|
||||
tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil:
|
||||
result = newNodeIT(nkNilLit, info, t)
|
||||
of tyProc:
|
||||
|
||||
@@ -102,7 +102,7 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet) =
|
||||
else:
|
||||
storeAny(s, t.lastSon, a[i], stored)
|
||||
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:
|
||||
# we need a slow linear search because of enums with holes:
|
||||
for e in items(t.n):
|
||||
@@ -275,7 +275,7 @@ proc loadAny(p: var JsonParser, t: PType,
|
||||
next(p)
|
||||
return
|
||||
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:
|
||||
internalError "cannot marshal at compile-time " & t.typeToString
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ type
|
||||
when defined(nimHasOpt):
|
||||
type opt*{.magic: "Opt".}[T]
|
||||
|
||||
when defined(nimHasSink):
|
||||
when defined(nimNewRuntime):
|
||||
type sink*{.magic: "BuiltinType".}[T]
|
||||
type lent*{.magic: "BuiltinType".}[T]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user