diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-01-21 03:04:22 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-01-21 03:04:22 +0100 |
commit | c99f952dfbce3a0b57958e02c992d98ca7dd0e83 (patch) | |
tree | 9c689911e4cc158026a25578526e751207e00e5a | |
parent | 7adf3bf4769b27bada8e9562d611d6c57263905a (diff) | |
download | Nim-c99f952dfbce3a0b57958e02c992d98ca7dd0e83.tar.gz |
basic 'lent T' test works
-rw-r--r-- | compiler/ccgexprs.nim | 14 | ||||
-rw-r--r-- | compiler/parampatterns.nim | 5 | ||||
-rw-r--r-- | compiler/semexprs.nim | 16 | ||||
-rw-r--r-- | tests/lent/tbasic_lent_check.nim | 17 |
4 files changed, 36 insertions, 16 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index bb9a9f6c6..ba0820e93 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -414,7 +414,7 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) = else: linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) of 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("genDeepCopy: " & $ty.kind) @@ -699,7 +699,7 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) = case typ.kind of tyRef: d.storage = OnHeap - of tyVar: + of tyVar, tyLent: d.storage = OnUnknown if tfVarIsPtr notin typ.flags and p.module.compileToCpp and e.kind == nkHiddenDeref: @@ -1359,9 +1359,9 @@ proc genOf(p: BProc, x: PNode, typ: PType, 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 = rfmt(nil, "(*$1)", r) t = skipTypes(t.lastSon, typedescInst) if not p.module.compileToCpp: @@ -1723,7 +1723,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, tySink}) + let destType = e.typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink}) if sameBackendType(destType, e.sons[1].typ): expr(p, e.sons[1], d) else: @@ -1799,7 +1799,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, tySink, tyVar, tyRange}) + let underlying = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent, tyRange}) if optOverflowCheck notin p.options or underlying.kind in {tyUInt..tyUInt64}: binaryStmt(p, e, d, opr[op]) else: diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index 0b8c8543e..aacd25795 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -222,7 +222,10 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult elif compareTypes(n.typ, n.sons[1].typ, dcEqIgnoreDistinct): # types that are equal modulo distinction preserve l-value: result = isAssignable(owner, n.sons[1], isUnsafeAddr) - of nkHiddenDeref, nkDerefExpr, nkHiddenAddr: + of nkHiddenDeref: + if n[0].typ.kind == tyLent: result = arDiscriminant + else: result = arLValue + of nkDerefExpr, nkHiddenAddr: result = arLValue of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr: result = isAssignable(owner, n.sons[0], isUnsafeAddr) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index e737f7676..d4b1eec88 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -951,7 +951,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = else: result = semMacroExpr(c, n, n, s, flags) of skTemplate: - if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or + if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or sfCustomPragma in sym.flags: markUsed(n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) @@ -1296,7 +1296,7 @@ proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode = #fixAbstractType(c, result) #analyseIfAddressTakenInCall(c, result) -proc takeImplicitAddr(c: PContext, n: PNode): PNode = +proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode = case n.kind of nkHiddenAddr, nkAddr: return n of nkHiddenDeref, nkDerefExpr: return n.sons[0] @@ -1307,7 +1307,7 @@ proc takeImplicitAddr(c: PContext, n: PNode): PNode = if valid != arLValue: if valid == arLocalLValue: localError(n.info, errXStackEscape, renderTree(n, {renderNoComments})) - else: + elif not isLent: localError(n.info, errExprHasNoAddress) result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ)) result.add(n) @@ -1315,9 +1315,9 @@ proc takeImplicitAddr(c: PContext, n: PNode): PNode = proc asgnToResultVar(c: PContext, n, le, ri: PNode) {.inline.} = if le.kind == nkHiddenDeref: var x = le.sons[0] - if x.typ.kind == tyVar and x.kind == nkSym and x.sym.kind == skResult: + if x.typ.kind in {tyVar, tyLent} and x.kind == nkSym and x.sym.kind == skResult: n.sons[0] = x # 'result[]' --> 'result' - n.sons[1] = takeImplicitAddr(c, ri) + n.sons[1] = takeImplicitAddr(c, ri, x.typ.kind == tyLent) x.typ.flags.incl tfVarIsPtr #echo x.info, " setting it for this type ", typeToString(x.typ), " ", n.info @@ -1473,18 +1473,18 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) = 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]) + n.sons[0] = takeImplicitAddr(c, n.sons[0], t.kind == tyLent) of tyTuple: for i in 0..<t.sonsLen: 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]) + n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i], e.kind == tyLent) elif n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv} and n.sons[0].sons[1].kind == nkPar: var a = n.sons[0].sons[1] - a.sons[i] = takeImplicitAddr(c, a.sons[i]) + a.sons[i] = takeImplicitAddr(c, a.sons[i], false) else: localError(n.sons[0].info, errXExpected, "tuple constructor") else: discard diff --git a/tests/lent/tbasic_lent_check.nim b/tests/lent/tbasic_lent_check.nim new file mode 100644 index 000000000..1d954725b --- /dev/null +++ b/tests/lent/tbasic_lent_check.nim @@ -0,0 +1,17 @@ +discard """ + cmd: "nim c --newRuntime $file" + output: "1" +""" + +proc viewInto(a: array[4, string]): lent string = + result = a[0] + +proc passToVar(x: var string) = + discard + +proc main = + let x = ["1", "2", "3", "4"] + echo viewInto(x) + doAssert(not compiles(passToVar(viewInto(x)))) + +main() |