Skip to content

Commit

Permalink
fix #13848: make var result work with nim cpp (#13959)
Browse files Browse the repository at this point in the history
* fix #13848

* add exhaustive tests for var result
  • Loading branch information
timotheecour authored Apr 13, 2020
1 parent 2ef3908 commit 814f150
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 1 deletion.
6 changes: 5 additions & 1 deletion compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1577,9 +1577,13 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode =
root.name.s, renderTree(n, {renderNoComments}), explanationsBaseUrl])
case n.kind
of nkHiddenAddr, nkAddr: return n
of nkHiddenDeref, nkDerefExpr: return n[0]
of nkDerefExpr: return n[0]
of nkBracketExpr:
if n.len == 1: return n[0]
of nkHiddenDeref:
# issue #13848
# `proc fun(a: var int): var int = a`
discard
else: discard
let valid = isAssignable(c, n, isLent)
if valid != arLValue:
Expand Down
108 changes: 108 additions & 0 deletions tests/varres/tvarres0.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,111 @@ getF().a = 1234
echo getF().a
getF() = Foo(a: 12345)
echo getF().a


block: # #13848
template fun() =
block:
var m = 1

proc identity(o: var int): var int =
result = o
result += 5

identity(m) += 3
doAssert m == 5+4

block:
var m = 10
proc identity2(o: var int): var int =
result = m
result += 100

var ignored = 27
identity2(ignored) += 7
doAssert m == 10 + 100 + 7

block:
iterator test3(o: var int): var int = yield o
var m = 1
for m2 in test3(m): m2+=3
doAssert m == 4

static: fun()
fun()

template fun2() =
block:
var m = 1
var m2 = 1
iterator test3(o: var int): (var int, var int) =
yield (o, m2)

for ti in test3(m):
ti[0]+=3
ti[1]+=4

doAssert (m, m2) == (4, 5)
fun2()
# static: fun2() # BUG: Error: attempt to access a nil address kind: rkInt

template fun3() =
block:
proc test4[T1](o: var T1): var int = o[1]
block:
var m = @[1,2]
test4(m) += 10
doAssert m[1] == 2+10
block:
var m = [1,2]
test4(m) += 10
doAssert m[1] == 2+10
block:
var m = (1, 2)
test4(m) += 10
doAssert m[1] == 2+10

proc test5[T1](o: var T1): var int = o.x
block:
type Foo = object
x: int
var m = Foo(x: 2)
test5(m) += 10
doAssert m.x == 2+10
block:
type Foo = ref object
x: int
var m = Foo(x: 2)
test5(m) += 10
doAssert m.x == 2+10

proc test6[T1](o: T1): var int = o.x
block:
type Foo = ref object
x: int
var m = Foo(x: 2)
test6(m) += 10
doAssert m.x == 2+10

fun3()
static: fun3()

when false:
# BUG:
# c: SIGSEGV
# cpp: error: call to implicitly-deleted default constructor of 'tyTuple__ILZebuYefUeQLAzY85QkHA'
proc test7[T](o: var T): (var int,) =
(o[1], )
var m = @[1,2]
test7(m)[0] += 10

block:
# example from #13848
type
MyType[T] = object
a,b: T
MyTypeAlias = MyType[float32]

var m: MyTypeAlias
proc identity(o: var MyTypeAlias): var MyTypeAlias = o
discard identity(m)

0 comments on commit 814f150

Please sign in to comment.