mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
Print missing case labels (#10600)
This commit is contained in:
committed by
Andreas Rumpf
parent
048a7a6539
commit
43a0dd42bc
@@ -873,6 +873,9 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
||||
if chckCovered:
|
||||
if covered == toCover(c, n.sons[0].typ):
|
||||
hasElse = true
|
||||
elif n.sons[0].typ.kind == tyEnum:
|
||||
localError(c.config, n.info, "not all cases are covered; missing: {$1}" %
|
||||
formatMissingEnums(n))
|
||||
else:
|
||||
localError(c.config, n.info, "not all cases are covered")
|
||||
closeScope(c)
|
||||
|
||||
@@ -608,6 +608,24 @@ proc toCover(c: PContext, t: PType): BiggestInt =
|
||||
|
||||
proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||
father: PNode, rectype: PType, hasCaseFields = false)
|
||||
|
||||
proc formatMissingEnums(n: PNode): string =
|
||||
var coveredCases = initIntSet()
|
||||
for i in 1 ..< n.len:
|
||||
let ofBranch = n[i]
|
||||
for j in 0 ..< ofBranch.len - 1:
|
||||
let child = ofBranch[j]
|
||||
if child.kind == nkIntLit:
|
||||
coveredCases.incl(child.intVal.int)
|
||||
elif child.kind == nkRange:
|
||||
for k in child[0].intVal.int .. child[1].intVal.int:
|
||||
coveredCases.incl k
|
||||
for child in n[0].typ.n.sons:
|
||||
if child.sym.position notin coveredCases:
|
||||
if result.len > 0:
|
||||
result.add ", "
|
||||
result.add child.sym.name.s
|
||||
|
||||
proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||
father: PNode, rectype: PType) =
|
||||
var a = copyNode(n)
|
||||
@@ -644,7 +662,11 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||
delSon(b, sonsLen(b) - 1)
|
||||
semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype, hasCaseFields = true)
|
||||
if chckCovered and covered != toCover(c, a.sons[0].typ):
|
||||
localError(c.config, a.info, "not all cases are covered")
|
||||
if a.sons[0].typ.kind == tyEnum:
|
||||
localError(c.config, a.info, "not all cases are covered; missing: {$1}" %
|
||||
formatMissingEnums(a))
|
||||
else:
|
||||
localError(c.config, a.info, "not all cases are covered")
|
||||
addSon(father, a)
|
||||
|
||||
proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||
|
||||
@@ -3,7 +3,7 @@ discard """
|
||||
line: 33
|
||||
file: "tcaseexpr1.nim"
|
||||
|
||||
errormsg: "not all cases are covered"
|
||||
errormsg: "not all cases are covered; missing: {C}"
|
||||
line: 27
|
||||
file: "tcaseexpr1.nim"
|
||||
"""
|
||||
|
||||
115
tests/casestmt/tincompletecaseobject.nim
Normal file
115
tests/casestmt/tincompletecaseobject.nim
Normal file
@@ -0,0 +1,115 @@
|
||||
discard """
|
||||
errormsg: '''
|
||||
not all cases are covered; missing: {nnkComesFrom, nnkDotCall, nnkHiddenCallConv, nnkVarTuple, nnkCurlyExpr, nnkRange, nnkCheckedFieldExpr, nnkDerefExpr, nnkElifExpr, nnkElseExpr, nnkLambda, nnkDo, nnkBind, nnkClosedSymChoice, nnkHiddenSubConv, nnkConv, nnkStaticExpr, nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv, nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange, nnkStringToCString, nnkCStringToString, nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit, nnkImportAs, nnkConverterDef, nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch, nnkElifBranch, nnkExceptBranch, nnkElse, nnkAsmStmt, nnkTypeDef, nnkFinally, nnkContinueStmt, nnkImportStmt, nnkImportExceptStmt, nnkExportStmt, nnkExportExceptStmt, nnkFromStmt, nnkIncludeStmt, nnkUsingStmt, nnkBlockExpr, nnkStmtListType, nnkBlockType, nnkWith, nnkWithout, nnkTypeOfExpr, nnkObjectTy, nnkTupleTy, nnkTupleClassTy, nnkTypeClassTy, nnkStaticTy, nnkRecList, nnkRecCase, nnkRecWhen, nnkVarTy, nnkConstTy, nnkMutableTy, nnkDistinctTy, nnkProcTy, nnkIteratorTy, nnkSharedTy, nnkEnumTy, nnkEnumFieldDef, nnkArglist, nnkPattern, nnkReturnToken, nnkClosure, nnkGotoState, nnkState, nnkBreakState, nnkFuncDef, nnkTupleConstr}
|
||||
'''
|
||||
"""
|
||||
|
||||
# this isn't imported from macros.nim to make it robust against possible changes in the ast.
|
||||
|
||||
type
|
||||
NimNodeKind* = enum
|
||||
nnkNone, nnkEmpty, nnkIdent, nnkSym,
|
||||
nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit,
|
||||
nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit,
|
||||
nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit,
|
||||
nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit,
|
||||
nnkTripleStrLit, nnkNilLit, nnkComesFrom, nnkDotCall,
|
||||
nnkCommand, nnkCall, nnkCallStrLit, nnkInfix,
|
||||
nnkPrefix, nnkPostfix, nnkHiddenCallConv,
|
||||
nnkExprEqExpr,
|
||||
nnkExprColonExpr, nnkIdentDefs, nnkVarTuple,
|
||||
nnkPar, nnkObjConstr, nnkCurly, nnkCurlyExpr,
|
||||
nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange,
|
||||
nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr,
|
||||
nnkElifExpr, nnkElseExpr, nnkLambda, nnkDo, nnkAccQuoted,
|
||||
nnkTableConstr, nnkBind,
|
||||
nnkClosedSymChoice,
|
||||
nnkOpenSymChoice,
|
||||
nnkHiddenStdConv,
|
||||
nnkHiddenSubConv, nnkConv, nnkCast, nnkStaticExpr,
|
||||
nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv,
|
||||
nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
|
||||
nnkStringToCString, nnkCStringToString, nnkAsgn,
|
||||
nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit,
|
||||
nnkImportAs, nnkProcDef, nnkMethodDef, nnkConverterDef,
|
||||
nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch,
|
||||
nnkElifBranch, nnkExceptBranch, nnkElse,
|
||||
nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt,
|
||||
nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt,
|
||||
nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection,
|
||||
nnkConstDef, nnkTypeDef,
|
||||
nnkYieldStmt, nnkDefer, nnkTryStmt, nnkFinally, nnkRaiseStmt,
|
||||
nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt,
|
||||
nnkDiscardStmt, nnkStmtList,
|
||||
nnkImportStmt = 1337, # make a hole just for fun
|
||||
nnkImportExceptStmt,
|
||||
nnkExportStmt,
|
||||
nnkExportExceptStmt,
|
||||
nnkFromStmt,
|
||||
nnkIncludeStmt,
|
||||
nnkBindStmt, nnkMixinStmt, nnkUsingStmt,
|
||||
nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr,
|
||||
nnkStmtListType, nnkBlockType,
|
||||
nnkWith, nnkWithout,
|
||||
nnkTypeOfExpr, nnkObjectTy,
|
||||
nnkTupleTy, nnkTupleClassTy, nnkTypeClassTy, nnkStaticTy,
|
||||
nnkRecList, nnkRecCase, nnkRecWhen,
|
||||
nnkRefTy, nnkPtrTy, nnkVarTy,
|
||||
nnkConstTy, nnkMutableTy,
|
||||
nnkDistinctTy,
|
||||
nnkProcTy,
|
||||
nnkIteratorTy, # iterator type
|
||||
nnkSharedTy, # 'shared T'
|
||||
nnkEnumTy,
|
||||
nnkEnumFieldDef,
|
||||
nnkArglist, nnkPattern
|
||||
nnkReturnToken,
|
||||
nnkClosure,
|
||||
nnkGotoState,
|
||||
nnkState,
|
||||
nnkBreakState,
|
||||
nnkFuncDef,
|
||||
nnkTupleConstr
|
||||
|
||||
const
|
||||
nnkLiterals* = {nnkCharLit..nnkNilLit}
|
||||
|
||||
nnkSomething* = {nnkStmtList, nnkStmtListExpr, nnkDiscardStmt, nnkVarSection, nnkLetSection,
|
||||
nnkConstSection, nnkPar, nnkAccQuoted, nnkAsgn, nnkDefer, nnkCurly, nnkBracket,
|
||||
nnkStaticStmt, nnkTableConstr, nnkExprColonExpr, nnkInfix, nnkPrefix,
|
||||
nnkRaiseStmt, nnkYieldStmt, nnkBracketExpr, nnkDotExpr, nnkCast, nnkBlockStmt,
|
||||
nnkExprEqExpr}
|
||||
|
||||
type
|
||||
MyFictionalType = object
|
||||
a: int
|
||||
case n: NimNodeKind
|
||||
of nnkLiterals, nnkCommentStmt, nnkNone, nnkEmpty, nnkIdent, nnkSym,
|
||||
nnkType, nnkBindStmt, nnkMixinStmt, nnkTypeSection, nnkPragmaBlock,
|
||||
nnkPragmaExpr, nnkPragma, nnkBreakStmt, nnkCallStrLit, nnkPostfix,
|
||||
nnkOpenSymChoice:
|
||||
b: int
|
||||
of nnkCall, nnkCommand:
|
||||
c: int
|
||||
of nnkReturnStmt:
|
||||
d: int
|
||||
of nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkProcDef, nnkMethodDef:
|
||||
e: int
|
||||
of nnkSomething, nnkRefTy, nnkPtrTy, nnkHiddenStdConv:
|
||||
f: int
|
||||
of nnkObjConstr:
|
||||
g: int
|
||||
of nnkIfStmt, nnkIfExpr, nnkWhenStmt:
|
||||
# if when and case statements are branching statements. So a
|
||||
# single function call is allowed to be in all of the braches and
|
||||
# the entire expression can still be considered as a forwarding
|
||||
# template.
|
||||
h: int
|
||||
of nnkCaseStmt:
|
||||
i: int
|
||||
of nnkTryStmt:
|
||||
j: int
|
||||
of nnkIdentDefs:
|
||||
k: int
|
||||
of nnkConstDef:
|
||||
l: int
|
||||
Reference in New Issue
Block a user