From be82d115764819bf9da799630948676ef6cde42a Mon Sep 17 00:00:00 2001 From: cooldome Date: Sat, 21 Sep 2019 05:45:27 +0100 Subject: [PATCH] fixes #12224 (#12225) * fixes #12224 * improve test --- compiler/parampatterns.nim | 8 +++++--- compiler/semexprs.nim | 4 ++-- tests/lent/tnot_allowed_lent.nim | 24 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 tests/lent/tnot_allowed_lent.nim diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index b8f1fd8327..78ba68ae65 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -218,14 +218,16 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult of nkSym: let kinds = if isUnsafeAddr: {skVar, skResult, skTemp, skParam, skLet, skForVar} else: {skVar, skResult, skTemp} - if n.sym.kind in kinds: + if n.sym.kind == skParam and n.sym.typ.kind in {tyVar, tySink}: + result = arLValue + elif isUnsafeAddr and n.sym.kind == skParam: + result = arLValue + elif n.sym.kind in kinds: if owner != nil and owner == n.sym.owner and sfGlobal notin n.sym.flags: result = arLocalLValue else: result = arLValue - elif n.sym.kind == skParam and n.sym.typ.kind in {tyVar, tySink}: - result = arLValue elif n.sym.kind == skType: let t = n.sym.typ.skipTypes({tyTypeDesc}) if t.kind == tyVar: result = arStrange diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 3d529509cc..2f0eccd8c8 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1561,11 +1561,11 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode = of nkBracketExpr: if len(n) == 1: return n.sons[0] else: discard - let valid = isAssignable(c, n) + let valid = isAssignable(c, n, isLent) if valid != arLValue: if valid == arLocalLValue: localError(c.config, n.info, errXStackEscape % renderTree(n, {renderNoComments})) - elif not isLent: + else: localError(c.config, n.info, errExprHasNoAddress) result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ)) result.add(n) diff --git a/tests/lent/tnot_allowed_lent.nim b/tests/lent/tnot_allowed_lent.nim new file mode 100644 index 0000000000..b144ce36b8 --- /dev/null +++ b/tests/lent/tnot_allowed_lent.nim @@ -0,0 +1,24 @@ +discard """ + errmsg: "expression has no address" +""" +type + MyObject = object + x: seq[string] + +proc mytest1(s: MyObject, i: int): lent string = + ## works fine + if i < s.x.len - 1 and s.x[i] != "": + result = s.x[i] + else: raise newException(KeyError, "err1") + +proc mytest2(s: MyObject, i: int): lent string = + ## reject due to if expr + if i < s.x.len - 1 and s.x[i] != "": s.x[i] + else: raise newException(KeyError, "err1") + +for i in 1..5: + var x = MyObject(x: @["1", "2", "3"]) + echo mytest1(x, 1) + echo mytest2(x, 1) + +