From 192634445abc69503bdb87718a8df8ea2e69a8f6 Mon Sep 17 00:00:00 2001 From: Jasper Jenkins Date: Tue, 17 Dec 2019 19:27:08 -0800 Subject: [PATCH] better case coverage error message for alias and range enum --- compiler/semobjconstr.nim | 56 +++---------------- compiler/semstmts.nim | 6 +- compiler/semtypes.nim | 65 ++++++++++++++++------ tests/casestmt/tincompletecaseobject2.nim | 23 ++++++++ tests/objvariant/tnon_zero_discrim_err.nim | 14 +++++ tests/objvariant/trt_discrim_err2.nim | 6 +- 6 files changed, 100 insertions(+), 70 deletions(-) create mode 100644 tests/casestmt/tincompletecaseobject2.nim create mode 100644 tests/objvariant/tnon_zero_discrim_err.nim diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index 0062af24bfb4a..0ddec1706b050 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.. 1: + result &= ", " + if t.kind in {tyEnum, tyBool}: + while t.n[enumSymOffset].sym.position < val: inc(enumSymOffset) + result &= t.n[enumSymOffset].sym.name.s + else: + if i == 64: + result &= "omitted $1 values..." % $(vals.len - i) + break + else: + result &= $val + inc(i) + result &= "}" + +proc formatMissingEnums(c: PContext, n: PNode): string = var coveredCases = initIntSet() for i in 1.. 0: - result.add ", " - result.add child.sym.name.s + for val in processBranchVals(n[i]): + coveredCases.incl val + result = (c.getIntSetOfType(n[0].typ) - coveredCases).renderAsType(n[0].typ) proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, father: PNode, rectype: PType) = @@ -656,9 +687,9 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, delSon(b, b.len - 1) semRecordNodeAux(c, lastSon(n[i]), check, pos, b, rectype, hasCaseFields = true) if chckCovered and covered != toCover(c, a[0].typ): - if a[0].typ.kind == tyEnum: - localError(c.config, a.info, "not all cases are covered; missing: {$1}" % - formatMissingEnums(a)) + if a[0].typ.skipTypes(abstractRange).kind == tyEnum: + localError(c.config, a.info, "not all cases are covered; missing: $1" % + formatMissingEnums(c, a)) else: localError(c.config, a.info, "not all cases are covered") father.add a diff --git a/tests/casestmt/tincompletecaseobject2.nim b/tests/casestmt/tincompletecaseobject2.nim new file mode 100644 index 0000000000000..ccf6a3a6c2aac --- /dev/null +++ b/tests/casestmt/tincompletecaseobject2.nim @@ -0,0 +1,23 @@ +discard """ +cmd: "nim check $file" +errormsg: "not all cases are covered; missing: {A, B}" +nimout: ''' +tincompletecaseobject2.nim(16, 1) Error: not all cases are covered; missing: {B, C, D} +tincompletecaseobject2.nim(19, 1) Error: not all cases are covered; missing: {A, C} +tincompletecaseobject2.nim(22, 1) Error: not all cases are covered; missing: {A, B} +''' +""" +type + ABCD = enum A, B, C, D + AliasABCD = ABCD + RangeABC = range[A .. C] + AliasRangeABC = RangeABC + +case AliasABCD A: +of A: discard + +case RangeABC A: +of B: discard + +case AliasRangeABC A: +of C: discard diff --git a/tests/objvariant/tnon_zero_discrim_err.nim b/tests/objvariant/tnon_zero_discrim_err.nim new file mode 100644 index 0000000000000..c595bba1bde31 --- /dev/null +++ b/tests/objvariant/tnon_zero_discrim_err.nim @@ -0,0 +1,14 @@ +discard """ + errormsg: "low(kind) must be 0 for discriminant" + line: 7 +""" +type + HoledObj = object + case kind: int + of 0: a: int + else: discard + +let someInt = low(int) +case someInt +of 938: echo HoledObj(kind: someInt, a: 1) +else: discard diff --git a/tests/objvariant/trt_discrim_err2.nim b/tests/objvariant/trt_discrim_err2.nim index c595bba1bde31..4f2790bc6c799 100644 --- a/tests/objvariant/trt_discrim_err2.nim +++ b/tests/objvariant/trt_discrim_err2.nim @@ -1,10 +1,10 @@ discard """ - errormsg: "low(kind) must be 0 for discriminant" - line: 7 + errormsg: " branch initialization with a runtime discriminator only supports ordinal types with 2^16 elements or less." + line: 13 """ type HoledObj = object - case kind: int + case kind: range[0 .. 20000] of 0: a: int else: discard