diff options
-rw-r--r-- | compiler/semexprs.nim | 6 | ||||
-rw-r--r-- | tests/varres/tvarres0.nim | 108 |
2 files changed, 113 insertions, 1 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 826cf51ba..5c00ce1f8 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -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: diff --git a/tests/varres/tvarres0.nim b/tests/varres/tvarres0.nim index fd10a73bd..0f89c7e71 100644 --- a/tests/varres/tvarres0.nim +++ b/tests/varres/tvarres0.nim @@ -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) |