parent
c2fced129f
commit
be82d11576
3 changed files with 31 additions and 5 deletions
|
|
@ -218,14 +218,16 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
|
||||||
of nkSym:
|
of nkSym:
|
||||||
let kinds = if isUnsafeAddr: {skVar, skResult, skTemp, skParam, skLet, skForVar}
|
let kinds = if isUnsafeAddr: {skVar, skResult, skTemp, skParam, skLet, skForVar}
|
||||||
else: {skVar, skResult, skTemp}
|
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
|
if owner != nil and owner == n.sym.owner and
|
||||||
sfGlobal notin n.sym.flags:
|
sfGlobal notin n.sym.flags:
|
||||||
result = arLocalLValue
|
result = arLocalLValue
|
||||||
else:
|
else:
|
||||||
result = arLValue
|
result = arLValue
|
||||||
elif n.sym.kind == skParam and n.sym.typ.kind in {tyVar, tySink}:
|
|
||||||
result = arLValue
|
|
||||||
elif n.sym.kind == skType:
|
elif n.sym.kind == skType:
|
||||||
let t = n.sym.typ.skipTypes({tyTypeDesc})
|
let t = n.sym.typ.skipTypes({tyTypeDesc})
|
||||||
if t.kind == tyVar: result = arStrange
|
if t.kind == tyVar: result = arStrange
|
||||||
|
|
|
||||||
|
|
@ -1561,11 +1561,11 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode =
|
||||||
of nkBracketExpr:
|
of nkBracketExpr:
|
||||||
if len(n) == 1: return n.sons[0]
|
if len(n) == 1: return n.sons[0]
|
||||||
else: discard
|
else: discard
|
||||||
let valid = isAssignable(c, n)
|
let valid = isAssignable(c, n, isLent)
|
||||||
if valid != arLValue:
|
if valid != arLValue:
|
||||||
if valid == arLocalLValue:
|
if valid == arLocalLValue:
|
||||||
localError(c.config, n.info, errXStackEscape % renderTree(n, {renderNoComments}))
|
localError(c.config, n.info, errXStackEscape % renderTree(n, {renderNoComments}))
|
||||||
elif not isLent:
|
else:
|
||||||
localError(c.config, n.info, errExprHasNoAddress)
|
localError(c.config, n.info, errExprHasNoAddress)
|
||||||
result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ))
|
result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ))
|
||||||
result.add(n)
|
result.add(n)
|
||||||
|
|
|
||||||
24
tests/lent/tnot_allowed_lent.nim
Normal file
24
tests/lent/tnot_allowed_lent.nim
Normal file
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue