summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2020-08-01 07:39:00 +0200
committerGitHub <noreply@github.com>2020-08-01 07:39:00 +0200
commit4ab6887a67dcc87f961937447df0907b9dc7f26d (patch)
tree463aeb6ce9bea373a0376de32299867d8cbd2cad
parent6b88cd0d42cac8059cb4ead691d20c21ed445a12 (diff)
downloadNim-4ab6887a67dcc87f961937447df0907b9dc7f26d.tar.gz
fixes #15111 (#15136)
-rw-r--r--compiler/dfa.nim4
-rw-r--r--compiler/parser.nim4
-rw-r--r--compiler/semobjconstr.nim38
-rw-r--r--compiler/semtypes.nim8
-rw-r--r--compiler/varpartitions.nim2
5 files changed, 32 insertions, 24 deletions
diff --git a/compiler/dfa.nim b/compiler/dfa.nim
index f3b358d72..85a9ccf42 100644
--- a/compiler/dfa.nim
+++ b/compiler/dfa.nim
@@ -280,7 +280,7 @@ proc patch(c: var Con, p: TPosition) =
   # patch with current index
   c.code[p.int].dest = checkedDistance(c.code.len - p.int)
 
-func gen(c: var Con; n: PNode)
+proc gen(c: var Con; n: PNode)
 
 proc popBlock(c: var Con; oldLen: int) =
   var exits: seq[TPosition]
@@ -712,7 +712,7 @@ proc genVarSection(c: var Con; n: PNode) =
       if a.lastSon.kind != nkEmpty:
         genDef(c, a[0])
 
-func gen(c: var Con; n: PNode) =
+proc gen(c: var Con; n: PNode) =
   case n.kind
   of nkSym: genUse(c, n)
   of nkCallKinds:
diff --git a/compiler/parser.nim b/compiler/parser.nim
index ccb7ca3b1..8cfeff6b0 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -1953,7 +1953,7 @@ proc parseObjectPart(p: var TParser): PNode =
         else:
           parMessage(p, errIdentifierExpected, p.tok)
           break
-  else:
+  elif sameOrNoInd(p):
     case p.tok.tokType
     of tkWhen:
       result = parseObjectWhen(p)
@@ -1968,6 +1968,8 @@ proc parseObjectPart(p: var TParser): PNode =
       getTok(p)
     else:
       result = p.emptyNode
+  else:
+    result = p.emptyNode
 
 proc parseObject(p: var TParser): PNode =
   #| object = 'object' pragma? ('of' typeDesc)? COMMENT? objectPart
diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim
index f8639b000..cd5a52fe9 100644
--- a/compiler/semobjconstr.nim
+++ b/compiler/semobjconstr.nim
@@ -154,20 +154,20 @@ proc collectMissingFields(c: PContext, fieldsRecList: PNode,
       if assignment == nil:
         constrCtx.missingFields.add r.sym
 
-proc semConstructFields(c: PContext, recNode: PNode,
+proc semConstructFields(c: PContext, n: PNode,
                         constrCtx: var ObjConstrContext,
                         flags: TExprFlags): InitStatus =
   result = initUnknown
 
-  case recNode.kind
+  case n.kind
   of nkRecList:
-    for field in recNode:
+    for field in n:
       let status = semConstructFields(c, field, constrCtx, flags)
       mergeInitStatus(result, status)
 
   of nkRecCase:
     template fieldsPresentInBranch(branchIdx: int): string =
-      let branch = recNode[branchIdx]
+      let branch = n[branchIdx]
       let fields = branch[^1]
       fieldsPresentInInitExpr(c, fields, constrCtx.initExpr)
 
@@ -176,12 +176,12 @@ proc semConstructFields(c: PContext, recNode: PNode,
         let fields = branchNode[^1]
         collectMissingFields(c, fields, constrCtx)
 
-    let discriminator = recNode[0]
+    let discriminator = n[0]
     internalAssert c.config, discriminator.kind == nkSym
     var selectedBranch = -1
 
-    for i in 1..<recNode.len:
-      let innerRecords = recNode[i][^1]
+    for i in 1..<n.len:
+      let innerRecords = n[i][^1]
       let status = semConstructFields(c, innerRecords, constrCtx, flags)
       if status notin {initNone, initUnknown}:
         mergeInitStatus(result, status)
@@ -217,9 +217,9 @@ proc semConstructFields(c: PContext, recNode: PNode,
         localError(c.config, discriminatorVal.info, ("possible values " &
           "$2 are in conflict with discriminator values for " &
           "selected object branch $1.") % [$selectedBranch,
-          valsDiff.renderAsType(recNode[0].typ)])
+          valsDiff.renderAsType(n[0].typ)])
 
-      let branchNode = recNode[selectedBranch]
+      let branchNode = n[selectedBranch]
       let flags = flags*{efAllowDestructor} + {efPreferStatic,
                                                efPreferNilResult}
       var discriminatorVal = semConstrField(c, flags,
@@ -230,7 +230,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
         if discriminatorVal.kind notin nkLiterals and (
             not isOrdinalType(discriminatorVal.typ, true) or
             lengthOrd(c.config, discriminatorVal.typ) > MaxSetElements or
-            lengthOrd(c.config, recNode[0].typ) > MaxSetElements):
+            lengthOrd(c.config, n[0].typ) > MaxSetElements):
           localError(c.config, discriminatorVal.info,
             "branch initialization with a runtime discriminator only " &
             "supports ordinal types with 2^16 elements or less.")
@@ -242,7 +242,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
         if ctorCase == nil:
           if discriminatorVal.typ.kind == tyRange:
             let rangeVals = c.getIntSetOfType(discriminatorVal.typ)
-            let recBranchVals = branchVals(c, recNode, selectedBranch, false)
+            let recBranchVals = branchVals(c, n, selectedBranch, false)
             let diff = rangeVals - recBranchVals
             if diff.len != 0:
               valuesInConflictError(diff)
@@ -260,7 +260,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
         else:
           var
             ctorBranchVals = branchVals(c, ctorCase, ctorIdx, true)
-            recBranchVals = branchVals(c, recNode, selectedBranch, false)
+            recBranchVals = branchVals(c, n, selectedBranch, false)
             branchValsDiff = ctorBranchVals - recBranchVals
           if branchValsDiff.len != 0:
             valuesInConflictError(branchValsDiff)
@@ -271,14 +271,14 @@ proc semConstructFields(c: PContext, recNode: PNode,
             failedBranch = selectedBranch
         else:
           # With an else clause, check that all other branches don't match:
-          for i in 1..<recNode.len - 1:
-            if recNode[i].caseBranchMatchesExpr(discriminatorVal):
+          for i in 1..<n.len - 1:
+            if n[i].caseBranchMatchesExpr(discriminatorVal):
               failedBranch = i
               break
         if failedBranch != -1:
           if discriminatorVal.typ.kind == tyRange:
             let rangeVals = c.getIntSetOfType(discriminatorVal.typ)
-            let recBranchVals = branchVals(c, recNode, selectedBranch, false)
+            let recBranchVals = branchVals(c, n, selectedBranch, false)
             let diff = rangeVals - recBranchVals
             if diff.len != 0:
               valuesInConflictError(diff)
@@ -301,22 +301,22 @@ proc semConstructFields(c: PContext, recNode: PNode,
         # initialized to zero and this will select a particular branch as
         # a result:
         let defaultValue = newIntLit(c.graph, constrCtx.initExpr.info, 0)
-        let matchedBranch = recNode.pickCaseBranch defaultValue
+        let matchedBranch = n.pickCaseBranch defaultValue
         collectMissingFields matchedBranch
       else:
         result = initPartial
         if discriminatorVal.kind == nkIntLit:
           # When the discriminator is a compile-time value, we also know
           # which branch will be selected:
-          let matchedBranch = recNode.pickCaseBranch discriminatorVal
+          let matchedBranch = n.pickCaseBranch discriminatorVal
           if matchedBranch != nil: collectMissingFields matchedBranch
         else:
           # All bets are off. If any of the branches has a mandatory
           # fields we must produce an error:
-          for i in 1..<recNode.len: collectMissingFields recNode[i]
+          for i in 1..<n.len: collectMissingFields n[i]
 
   of nkSym:
-    let field = recNode.sym
+    let field = n.sym
     let e = semConstrField(c, flags, field, constrCtx.initExpr)
     result = if e != nil: initFull else: initNone
 
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 588a0f4f6..c2aeadc21 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -663,7 +663,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
     internalError(c.config, "semRecordCase: discriminant is no symbol")
     return
   incl(a[0].sym.flags, sfDiscriminant)
-  var covered: Int128 = toInt128(0)
+  var covered = toInt128(0)
   var chckCovered = false
   var typ = skipTypes(a[0].typ, abstractVar-{tyTypeDesc})
   const shouldChckCovered = {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool}
@@ -744,6 +744,8 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
       father.add n
     elif branch != nil:
       semRecordNodeAux(c, branch, check, pos, father, rectype, hasCaseFields)
+    elif father.kind in {nkElse, nkOfBranch}:
+      father.add newNodeI(nkRecList, n.info)
   of nkRecCase:
     semRecordCase(c, n, check, pos, father, rectype)
   of nkNilLit:
@@ -800,7 +802,9 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
     if containsOrIncl(check, n.sym.name.id):
       localError(c.config, n.info, "attempt to redefine: '" & n.sym.name.s & "'")
     father.add n
-  of nkEmpty: discard
+  of nkEmpty:
+    if father.kind in {nkElse, nkOfBranch}:
+      father.add n
   else: illFormedAst(n, c.config)
 
 proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int,
diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim
index 08b591cc5..7a6cc4f63 100644
--- a/compiler/varpartitions.nim
+++ b/compiler/varpartitions.nim
@@ -9,6 +9,8 @@
 
 ## Partition variables into different graphs. Used for
 ## Nim's write tracking and also for the cursor inference.
+## The algorithm is a reinvention / variation of Steensgaard's
+## algorithm.
 ## The used algorithm is "union find" with path compression.
 
 import ast, types, lineinfos, options, msgs, renderer