summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2024-08-22 13:21:13 +0800
committerGitHub <noreply@github.com>2024-08-22 07:21:13 +0200
commit79f5a74408fab60c21e3905b72fe7dcdcb34eb52 (patch)
tree85ce29e8812c4ce20ac342f7865df2e8aa7c114b
parent04da0a6028a4a0d469a10567a35655646f4957c2 (diff)
downloadNim-79f5a74408fab60c21e3905b72fe7dcdcb34eb52.tar.gz
fixes #23454; IndexDefect thrown when destructuring a lent tuple (#23993)
fixes #23454
-rw-r--r--compiler/transf.nim5
-rw-r--r--tests/lent/tlent_from_var.nim36
2 files changed, 40 insertions, 1 deletions
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 7ab4ccae2..4061a407c 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -496,7 +496,10 @@ proc transformAddrDeref(c: PTransf, n: PNode, kinds: TNodeKinds): PNode =
       elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
         result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, c.idgen)
   else:
-    if n[0].kind in kinds:
+    if n[0].kind in kinds and
+        not (n[0][0].kind == nkSym and n[0][0].sym.kind == skForVar and
+          n[0][0].typ.skipTypes(abstractVar).kind == tyTuple
+        ): # elimination is harmful to `for tuple unpack` because of newTupleAccess
       # addr ( deref ( x )) --> x
       result = n[0][0]
       if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
diff --git a/tests/lent/tlent_from_var.nim b/tests/lent/tlent_from_var.nim
index d61ff6dc0..8cf65e286 100644
--- a/tests/lent/tlent_from_var.nim
+++ b/tests/lent/tlent_from_var.nim
@@ -50,3 +50,39 @@ template get*[T: not void](self: Opt[T]): T = self.value()
 method connect*(
   self: Opt[(int, int)]) =
   discard self.get()[0]
+
+block: # bug #23454
+  type
+    Letter = enum
+      A
+
+    LetterPairs = object
+      values: seq[(Letter, string)]
+
+  iterator items(list: var LetterPairs): lent (Letter, string) =
+    for item in list.values:
+      yield item
+
+  var instance = LetterPairs(values: @[(A, "foo")])
+
+  for (a, _) in instance:
+    case a
+    of A: discard
+
+block: # bug #23454
+  type
+    Letter = enum
+      A
+
+    LetterPairs = object
+      values: seq[(Letter, string)]
+
+  iterator items(list: var LetterPairs): var (Letter, string) =
+    for item in list.values.mItems:
+      yield item
+
+  var instance = LetterPairs(values: @[(A, "foo")])
+
+  for (a, _) in instance:
+    case a
+    of A: discard