parent
3105909f88
commit
7ccc7d7e93
4 changed files with 26 additions and 6 deletions
|
|
@ -176,6 +176,7 @@ type
|
||||||
arLocalLValue, # is an l-value, but local var; must not escape
|
arLocalLValue, # is an l-value, but local var; must not escape
|
||||||
# its stack frame!
|
# its stack frame!
|
||||||
arDiscriminant, # is a discriminant
|
arDiscriminant, # is a discriminant
|
||||||
|
arLentValue, # lent value
|
||||||
arStrange # it is a strange beast like 'typedesc[var T]'
|
arStrange # it is a strange beast like 'typedesc[var T]'
|
||||||
|
|
||||||
proc exprRoot*(n: PNode): PSym =
|
proc exprRoot*(n: PNode): PSym =
|
||||||
|
|
@ -260,9 +261,14 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
|
||||||
# types that are equal modulo distinction preserve l-value:
|
# types that are equal modulo distinction preserve l-value:
|
||||||
result = isAssignable(owner, n[1], isUnsafeAddr)
|
result = isAssignable(owner, n[1], isUnsafeAddr)
|
||||||
of nkHiddenDeref:
|
of nkHiddenDeref:
|
||||||
if isUnsafeAddr and n[0].typ.kind == tyLent: result = arLValue
|
let n0 = n[0]
|
||||||
elif n[0].typ.kind == tyLent: result = arDiscriminant
|
if n0.typ.kind == tyLent:
|
||||||
else: result = arLValue
|
if isUnsafeAddr or (n0.kind == nkSym and n0.sym.kind == skResult):
|
||||||
|
result = arLValue
|
||||||
|
else:
|
||||||
|
result = arLentValue
|
||||||
|
else:
|
||||||
|
result = arLValue
|
||||||
of nkDerefExpr, nkHiddenAddr:
|
of nkDerefExpr, nkHiddenAddr:
|
||||||
result = arLValue
|
result = arLValue
|
||||||
of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
|
of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
|
||||||
|
|
|
||||||
|
|
@ -1712,7 +1712,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||||
if le == nil:
|
if le == nil:
|
||||||
localError(c.config, a.info, "expression has no type")
|
localError(c.config, a.info, "expression has no type")
|
||||||
elif (skipTypes(le, {tyGenericInst, tyAlias, tySink}).kind != tyVar and
|
elif (skipTypes(le, {tyGenericInst, tyAlias, tySink}).kind != tyVar and
|
||||||
isAssignable(c, a) == arNone) or
|
isAssignable(c, a) in {arNone, arLentValue}) or
|
||||||
skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}:
|
skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}:
|
||||||
# Direct assignment to a discriminant is allowed!
|
# Direct assignment to a discriminant is allowed!
|
||||||
localError(c.config, a.info, errXCannotBeAssignedTo %
|
localError(c.config, a.info, errXCannotBeAssignedTo %
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ type
|
||||||
|
|
||||||
proc mytest1(s: MyObject, i: int): lent string =
|
proc mytest1(s: MyObject, i: int): lent string =
|
||||||
## works fine
|
## works fine
|
||||||
if i < s.x.len - 1 and s.x[i] != "":
|
if i < s.x.len - 1 and s.x[i] != "":
|
||||||
result = s.x[i]
|
result = s.x[i]
|
||||||
else: raise newException(KeyError, "err1")
|
else: raise newException(KeyError, "err1")
|
||||||
|
|
||||||
proc mytest2(s: MyObject, i: int): lent string =
|
proc mytest2(s: MyObject, i: int): lent string =
|
||||||
## reject due to if expr
|
## reject due to if expr
|
||||||
if i < s.x.len - 1 and s.x[i] != "": s.x[i]
|
if i < s.x.len - 1 and s.x[i] != "": s.x[i]
|
||||||
|
|
|
||||||
14
tests/lent/tnot_allowed_lent2.nim
Normal file
14
tests/lent/tnot_allowed_lent2.nim
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
discard """
|
||||||
|
errmsg: "'x' cannot be assigned to"
|
||||||
|
line: 10
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc bug14498 =
|
||||||
|
var a = @['a', 'b', 'c', 'd', 'e', 'f']
|
||||||
|
|
||||||
|
for x in a:
|
||||||
|
x = 'c'
|
||||||
|
|
||||||
|
echo a
|
||||||
|
|
||||||
|
bug14498()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue