summary refs log tree commit diff stats
path: root/compiler/semfields.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/semfields.nim')
-rw-r--r--compiler/semfields.nim46
1 files changed, 25 insertions, 21 deletions
diff --git a/compiler/semfields.nim b/compiler/semfields.nim
index a911ae823..874055cdc 100644
--- a/compiler/semfields.nim
+++ b/compiler/semfields.nim
@@ -23,7 +23,7 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
     result = newNode(nkEmpty)
     return
   case n.kind
-  of nkEmpty..pred(nkIdent), succ(nkSym)..nkNilLit: result = n
+  of nkEmpty..pred(nkIdent), succ(nkSym)..nkNilLit: result = copyNode(n)
   of nkIdent, nkSym:
     result = n
     let ident = considerQuotedIdent(c.c, n)
@@ -52,8 +52,7 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
     if n.kind == nkContinueStmt:
       localError(c.c.config, n.info,
                  "'continue' not supported in a 'fields' loop")
-    result = copyNode(n)
-    newSons(result, n.len)
+    result = shallowCopy(n)
     for i in 0..<n.len:
       result[i] = instFieldLoopBody(c, n[i], forLoop)
 
@@ -65,10 +64,12 @@ type
 proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
   case typ.kind
   of nkSym:
-    var fc: TFieldInstCtx  # either 'tup[i]' or 'field' is valid
-    fc.c = c.c
-    fc.field = typ.sym
-    fc.replaceByFieldName = c.m == mFieldPairs
+    # either 'tup[i]' or 'field' is valid
+    var fc = TFieldInstCtx(
+      c: c.c,
+      field: typ.sym,
+      replaceByFieldName: c.m == mFieldPairs
+    )
     openScope(c.c)
     inc c.c.inUnrolledContext
     let body = instFieldLoopBody(fc, lastSon(forLoop), forLoop)
@@ -107,10 +108,10 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
   # so that 'break' etc. work as expected, we produce
   # a 'while true: stmt; break' loop ...
   result = newNodeI(nkWhileStmt, n.info, 2)
-  var trueSymbol = strTableGet(c.graph.systemModule.tab, getIdent(c.cache, "true"))
+  var trueSymbol = systemModuleSym(c.graph, getIdent(c.cache, "true"))
   if trueSymbol == nil:
     localError(c.config, n.info, "system needs: 'true'")
-    trueSymbol = newSym(skUnknown, getIdent(c.cache, "true"), getCurrOwner(c), n.info)
+    trueSymbol = newSym(skUnknown, getIdent(c.cache, "true"), c.idgen, getCurrOwner(c), n.info)
     trueSymbol.typ = getSysType(c.graph, n.info, tyBool)
 
   result[0] = newSymNode(trueSymbol, n.info)
@@ -128,34 +129,37 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
     localError(c.config, n.info, errGenerated, "no object or tuple type")
     return result
   for i in 1..<call.len:
-    var tupleTypeB = skipTypes(call[i].typ, skippedTypesForFields)
+    let calli = call[i]
+    var tupleTypeB = skipTypes(calli.typ, skippedTypesForFields)
     if not sameType(tupleTypeA, tupleTypeB):
-      typeMismatch(c.config, call[i].info, tupleTypeA, tupleTypeB)
+      typeMismatch(c.config, calli.info, tupleTypeA, tupleTypeB, calli)
 
   inc(c.p.nestedLoopCounter)
+  let oldBreakInLoop = c.p.breakInLoop
+  c.p.breakInLoop = true
   if tupleTypeA.kind == tyTuple:
     var loopBody = n[^1]
     for i in 0..<tupleTypeA.len:
       openScope(c)
-      var fc: TFieldInstCtx
-      fc.tupleType = tupleTypeA
-      fc.tupleIndex = i
-      fc.c = c
-      fc.replaceByFieldName = m == mFieldPairs
+      var fc = TFieldInstCtx(
+          tupleType: tupleTypeA,
+          tupleIndex: i,
+          c: c,
+          replaceByFieldName: m == mFieldPairs
+      )
       var body = instFieldLoopBody(fc, loopBody, n)
       inc c.inUnrolledContext
       stmts.add(semStmt(c, body, {}))
       dec c.inUnrolledContext
       closeScope(c)
   else:
-    var fc: TFieldsCtx
-    fc.m = m
-    fc.c = c
+    var fc = TFieldsCtx(m: m, c: c)
     var t = tupleTypeA
     while t.kind == tyObject:
       semForObjectFields(fc, t.n, n, stmts)
-      if t[0] == nil: break
-      t = skipTypes(t[0], skipPtrs)
+      if t.baseClass == nil: break
+      t = skipTypes(t.baseClass, skipPtrs)
+  c.p.breakInLoop = oldBreakInLoop
   dec(c.p.nestedLoopCounter)
   # for TR macros this 'while true: ...; break' loop is pretty bad, so
   # we avoid it now if we can: