summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semexprs.nim6
-rw-r--r--tests/varres/tvarres0.nim108
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)