diff options
34 files changed, 183 insertions, 178 deletions
diff --git a/compiler/aliases.nim b/compiler/aliases.nim index cd7e7f19a..490ac987a 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -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): diff --git a/compiler/ast.nim b/compiler/ast.nim index f5114feb0..54c33a038 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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. diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index d4fad041d..db2a9ddc9 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -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) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 5a25a9853..0a312b4c7 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -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: diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index 275c2ddb6..ad5d1c95f 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -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]) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index c9cd3b125..24d3a0dfb 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -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) diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index b1a268c9e..fe28d2209 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -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 diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 6f7d9f489..0513e88f4 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -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: diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index 0fdeceba0..55da69985 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -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) = diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim index 51b65258b..5bf8f358a 100644 --- a/compiler/evalffi.nim +++ b/compiler/evalffi.nim @@ -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) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index dac2de746..ac1a4b5d5 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -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) diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim index d9df04e4b..3768acf27 100644 --- a/compiler/jstypes.nim +++ b/compiler/jstypes.nim @@ -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))] diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index cf43ba15d..fca5ef52e 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -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 = diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 9612ff0ab..8510bf7ee 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -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") diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 6735cc1ce..4afaf859d 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -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 diff --git a/compiler/sem.nim b/compiler/sem.nim index 1098e9961..0e97a66b2 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -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 diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index 67af6ade7..bbd2baf6e 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -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) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index a51b9afe3..c580f8fd5 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -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) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 8affee649..3996188dc 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -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 = diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 51e75e91f..577580f2e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -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) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index d2d36140d..f690615ac 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -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]) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 0d0f2ee82..189babdec 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -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) diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index a0bf084fa..46e6ef25d 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -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 diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index d8754a931..096cf99de 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -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)) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index b0171fcbe..5172bc653 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index a42092ae0..d9b368b0e 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -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 diff --git a/compiler/suggest.nim b/compiler/suggest.nim index f9210cc93..28ce3c591 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -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: diff --git a/compiler/transf.nim b/compiler/transf.nim index f8f7f8746..14ff58c90 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -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) = diff --git a/compiler/trees.nim b/compiler/trees.nim index 7efefdc2e..577ea75ee 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -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 diff --git a/compiler/types.nim b/compiler/types.nim index 0d3a25980..b4f78b561 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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 diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index fb277272b..bb6c47324 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -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) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 17878b656..a22acdff0 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -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: diff --git a/compiler/vmmarshal.nim b/compiler/vmmarshal.nim index 0939a5953..5f725994e 100644 --- a/compiler/vmmarshal.nim +++ b/compiler/vmmarshal.nim @@ -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 diff --git a/lib/system.nim b/lib/system.nim index de91c4dda..8f83fb8c3 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -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] |