summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/lowerings.nim4
-rw-r--r--compiler/semexprs.nim8
-rw-r--r--compiler/semstmts.nim59
-rw-r--r--compiler/transf.nim3
4 files changed, 50 insertions, 24 deletions
diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim
index 9ff3ece33..fff6c75ca 100644
--- a/compiler/lowerings.nim
+++ b/compiler/lowerings.nim
@@ -21,8 +21,8 @@ proc newDeref*(n: PNode): PNode {.inline.} =
 
 proc newTupleAccess*(g: ModuleGraph; tup: PNode, i: int): PNode =
   if tup.kind == nkHiddenAddr:
-    result = newNodeIT(nkHiddenAddr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar}))
-    result.addSon(newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar}).sons[i]))
+    result = newNodeIT(nkHiddenAddr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent}))
+    result.addSon(newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent}).sons[i]))
     addSon(result[0], tup[0])
     var lit = newNodeIT(nkIntLit, tup.info, getSysType(g, tup.info, tyInt))
     lit.intVal = i
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 765110d56..a3d92da8c 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1781,21 +1781,21 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
   var t = skipTypes(restype, {tyGenericInst, tyAlias, tySink})
   case t.kind
   of tyVar, tyLent:
-    if t.kind == tyVar: t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
+    t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
     if n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv}:
       n.sons[0] = n.sons[0].sons[1]
     n.sons[0] = takeImplicitAddr(c, n.sons[0], t.kind == tyLent)
   of tyTuple:
     for i in 0..<t.sonsLen:
-      var e = skipTypes(t.sons[i], {tyGenericInst, tyAlias, tySink})
+      let e = skipTypes(t.sons[i], {tyGenericInst, tyAlias, tySink})
       if e.kind in {tyVar, tyLent}:
-        if e.kind == tyVar: e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
+        e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
         if n.sons[0].kind in {nkPar, nkTupleConstr}:
           n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i], e.kind == tyLent)
         elif n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv} and
              n.sons[0].sons[1].kind in {nkPar, nkTupleConstr}:
           var a = n.sons[0].sons[1]
-          a.sons[i] = takeImplicitAddr(c, a.sons[i], false)
+          a.sons[i] = takeImplicitAddr(c, a.sons[i], e.kind == tyLent)
         else:
           localError(c.config, n.sons[0].info, errXExpected, "tuple constructor")
   else: discard
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 5a0aac40e..dfa592549 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -678,25 +678,30 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode =
   var length = sonsLen(n)
   let iterBase = n.sons[length-2].typ
   var iter = skipTypes(iterBase, {tyGenericInst, tyAlias, tySink})
+  var iterAfterVarLent = iter.skipTypes({tyLent, tyVar})
   # length == 3 means that there is one for loop variable
   # and thus no tuple unpacking:
-  if iter.kind != tyTuple or length == 3:
+  if iterAfterVarLent.kind != tyTuple or length == 3:
     if length == 3:
       if n.sons[0].kind == nkVarTuple:
-        var mutable = false
-        if iter.kind == tyVar:
-          iter = iter.skipTypes({tyVar})
-          mutable = true
-        if sonsLen(n[0])-1 != sonsLen(iter):
+        if sonsLen(n[0])-1 != sonsLen(iterAfterVarLent):
           localError(c.config, n[0].info, errWrongNumberOfVariables)
         for i in 0 ..< sonsLen(n[0])-1:
           var v = symForVar(c, n[0][i])
           if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
-          if mutable:
-            v.typ = newTypeS(tyVar, c)
-            v.typ.sons.add iter[i]
-          else:
-            v.typ = iter.sons[i]
+          case iter.kind
+            of tyVar:
+              v.typ = newTypeS(tyVar, c)
+              v.typ.sons.add iterAfterVarLent[i]
+              if tfVarIsPtr in iter.flags:
+                v.typ.flags.incl tfVarIsPtr
+            of tyLent:
+              v.typ = newTypeS(tyLent, c)
+              v.typ.sons.add iterAfterVarLent[i]
+              if tfVarIsPtr in iter.flags:
+                v.typ.flags.incl tfVarIsPtr
+            else:
+              v.typ = iter.sons[i]
           n.sons[0][i] = newSymNode(v)
           if sfGenSym notin v.flags: addDecl(c, v)
           elif v.owner == nil: v.owner = getCurrOwner(c)
@@ -712,15 +717,22 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode =
         elif v.owner == nil: v.owner = getCurrOwner(c)
     else:
       localError(c.config, n.info, errWrongNumberOfVariables)
-  elif length-2 != sonsLen(iter):
+  elif length-2 != sonsLen(iterAfterVarLent):
     localError(c.config, n.info, errWrongNumberOfVariables)
   else:
     for i in 0 .. length - 3:
       if n.sons[i].kind == nkVarTuple:
         var mutable = false
-        if iter[i].kind == tyVar:
-          iter[i] = iter[i].skipTypes({tyVar})
-          mutable = true
+        var isLent = false
+        iter[i] = case iter[i].kind
+          of tyVar:
+            mutable = true
+            iter[i].skipTypes({tyVar})
+          of tyLent:
+            isLent = true
+            iter[i].skipTypes({tyLent})
+          else: iter[i]
+
         if sonsLen(n[i])-1 != sonsLen(iter[i]):
           localError(c.config, n[i].info, errWrongNumberOfVariables)
         for j in 0 ..< sonsLen(n[i])-1:
@@ -729,6 +741,9 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode =
           if mutable:
             v.typ = newTypeS(tyVar, c)
             v.typ.sons.add iter[i][j]
+          elif isLent:
+            v.typ = newTypeS(tyLent, c)
+            v.typ.sons.add iter[i][j]
           else:
             v.typ = iter[i][j]
           n.sons[i][j] = newSymNode(v)
@@ -737,7 +752,19 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode =
       else:
         var v = symForVar(c, n.sons[i])
         if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
-        v.typ = iter.sons[i]
+        case iter.kind
+        of tyVar:
+          v.typ = newTypeS(tyVar, c)
+          v.typ.sons.add iterAfterVarLent[i]
+          if tfVarIsPtr in iter.flags:
+            v.typ.flags.incl tfVarIsPtr
+        of tyLent:
+          v.typ = newTypeS(tyLent, c)
+          v.typ.sons.add iterAfterVarLent[i]
+          if tfVarIsPtr in iter.flags:
+            v.typ.flags.incl tfVarIsPtr
+        else:
+          v.typ = iter.sons[i]
         n.sons[i] = newSymNode(v)
         if sfGenSym notin v.flags:
           if not isDiscardUnderscore(v): addDecl(c, v)
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 555583685..836a6154c 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -371,8 +371,7 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
   # c.transCon.forStmt.len == 3 means that there is one for loop variable
   # and thus no tuple unpacking:
   if e.typ.isNil: return result # can happen in nimsuggest for unknown reasons
-  if skipTypes(e.typ, {tyGenericInst, tyAlias, tySink}).kind == tyTuple and
-      c.transCon.forStmt.len != 3:
+  if c.transCon.forStmt.len != 3:
     e = skipConv(e)
     if e.kind in {nkPar, nkTupleConstr}:
       for i in 0 ..< sonsLen(e):