summary refs log tree commit diff stats
path: root/compiler/semobjconstr.nim
diff options
context:
space:
mode:
authorJasper Jenkins <jasper.vs.jenkins@gmail.com>2019-12-18 01:29:01 -0800
committerClyybber <darkmine956@gmail.com>2019-12-18 10:29:01 +0100
commit3c38edf56335926b6a9d7ef317422144b8d3f197 (patch)
tree9827fcf87d9f27345fa45709f4d310e3c3b228cb /compiler/semobjconstr.nim
parent148f6d98204f36a718cb61e9aab01299f06f711b (diff)
downloadNim-3c38edf56335926b6a9d7ef317422144b8d3f197.tar.gz
Better case coverage error message for alias and range enum (#12913)
Diffstat (limited to 'compiler/semobjconstr.nim')
-rw-r--r--compiler/semobjconstr.nim56
1 files changed, 9 insertions, 47 deletions
diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim
index 0062af24b..0ddec1706 100644
--- a/compiler/semobjconstr.nim
+++ b/compiler/semobjconstr.nim
@@ -84,55 +84,17 @@ proc caseBranchMatchesExpr(branch, matched: PNode): bool =
 
   return false
 
-template processBranchVals(b, op) =
-  if b.kind != nkElifBranch:
-    for i in 0..<b.len-1:
-      if b[i].kind == nkIntLit:
-        result.op(b[i].intVal.int)
-      elif b[i].kind == nkRange:
-        for i in b[i][0].intVal..b[i][1].intVal:
-          result.op(i.int)
-
-proc allPossibleValues(c: PContext, t: PType): IntSet =
-  result = initIntSet()
-  if t.enumHasHoles:
-    let t = t.skipTypes(abstractRange)
-    for field in t.n.sons:
-      result.incl(field.sym.position)
-  else:
-    for i in toInt64(firstOrd(c.config, t))..toInt64(lastOrd(c.config, t)):
-      result.incl(i.int)
-
 proc branchVals(c: PContext, caseNode: PNode, caseIdx: int,
                 isStmtBranch: bool): IntSet =
   if caseNode[caseIdx].kind == nkOfBranch:
     result = initIntSet()
-    processBranchVals(caseNode[caseIdx], incl)
+    for val in processBranchVals(caseNode[caseIdx]):
+      result.incl(val)
   else:
-    result = allPossibleValues(c, caseNode[0].typ)
+    result = c.getIntSetOfType(caseNode[0].typ)
     for i in 1..<caseNode.len-1:
-      processBranchVals(caseNode[i], excl)
-
-proc rangeTypVals(rangeTyp: PType): IntSet =
-  assert rangeTyp.kind == tyRange
-  let (a, b) = (rangeTyp.n[0].intVal, rangeTyp.n[1].intVal)
-  result = initIntSet()
-  for it in a..b:
-    result.incl(it.int)
-
-proc formatUnsafeBranchVals(t: PType, diffVals: IntSet): string =
-  if diffVals.len <= 32:
-    var strs: seq[string]
-    let t = t.skipTypes(abstractRange)
-    if t.kind in {tyEnum, tyBool}:
-      var i = 0
-      for val in diffVals:
-        while t.n[i].sym.position < val: inc(i)
-        strs.add(t.n[i].sym.name.s)
-    else:
-      for val in diffVals:
-        strs.add($val)
-    result = "{" & strs.join(", ") & "} "
+      for val in processBranchVals(caseNode[i]):
+        result.excl(val)
 
 proc findUsefulCaseContext(c: PContext, discrimator: PNode): (PNode, int) =
   for i in countdown(c.p.caseContext.high, 0):
@@ -250,9 +212,9 @@ proc semConstructFields(c: PContext, recNode: PNode,
 
       template valuesInConflictError(valsDiff) =
         localError(c.config, discriminatorVal.info, ("possible values " &
-          "$2are in conflict with discriminator values for " &
+          "$2 are in conflict with discriminator values for " &
           "selected object branch $1.") % [$selectedBranch,
-          formatUnsafeBranchVals(recNode[0].typ, valsDiff)])
+          valsDiff.renderAsType(recNode[0].typ)])
 
       let branchNode = recNode[selectedBranch]
       let flags = flags*{efAllowDestructor} + {efPreferStatic,
@@ -275,7 +237,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
         let (ctorCase, ctorIdx) = findUsefulCaseContext(c, discriminatorVal)
         if ctorCase == nil:
           if discriminatorVal.typ.kind == tyRange:
-            let rangeVals = rangeTypVals(discriminatorVal.typ)
+            let rangeVals = c.getIntSetOfType(discriminatorVal.typ)
             let recBranchVals = branchVals(c, recNode, selectedBranch, false)
             let diff = rangeVals - recBranchVals
             if diff.len != 0:
@@ -311,7 +273,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
               break
         if failedBranch != -1:
           if discriminatorVal.typ.kind == tyRange:
-            let rangeVals = rangeTypVals(discriminatorVal.typ)
+            let rangeVals = c.getIntSetOfType(discriminatorVal.typ)
             let recBranchVals = branchVals(c, recNode, selectedBranch, false)
             let diff = rangeVals - recBranchVals
             if diff.len != 0: