diff options
-rw-r--r-- | compiler/semstmts.nim | 10 | ||||
-rw-r--r-- | compiler/semtypes.nim | 9 | ||||
-rw-r--r-- | compiler/types.nim | 2 | ||||
-rw-r--r-- | tests/objvariant/tfloatrangeobj.nim | 13 |
4 files changed, 28 insertions, 6 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 6423b8fb3..5d1990e33 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -878,10 +878,14 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode = var covered: BiggestInt = 0 var typ = commonTypeBegin var hasElse = false - let caseTyp = skipTypes(n.sons[0].typ, abstractVarRange-{tyTypeDesc}) + let caseTyp = skipTypes(n.sons[0].typ, abstractVar-{tyTypeDesc}) + const shouldChckCovered = {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool} case caseTyp.kind - of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool: + of shouldChckCovered: chckCovered = true + of tyRange: + if skipTypes(caseTyp.sons[0], abstractInst).kind in shouldChckCovered: + chckCovered = true of tyFloat..tyFloat128, tyString, tyError: discard else: @@ -889,7 +893,7 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode = result = handleCaseStmtMacro(c, n) if result != nil: return result - localError(c.config, n.info, errSelectorMustBeOfCertainTypes) + localError(c.config, n.sons[0].info, errSelectorMustBeOfCertainTypes) return for i in 1 ..< sonsLen(n): var x = n.sons[i] diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 6a2783551..86cb0f35b 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -223,7 +223,8 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = if not hasUnknownTypes: if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})): localError(c.config, n.info, "type mismatch") - elif not rangeT[0].isOrdinalType and rangeT[0].kind notin tyFloat..tyFloat128: + elif not rangeT[0].isOrdinalType and rangeT[0].kind notin tyFloat..tyFloat128 or + rangeT[0].kind == tyBool: localError(c.config, n.info, "ordinal or float type expected") elif enumHasHoles(rangeT[0]): localError(c.config, n.info, "enum '$1' has holes" % typeToString(rangeT[0])) @@ -605,11 +606,15 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, var covered: BiggestInt = 0 var chckCovered = false var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc}) + const shouldChckCovered = {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool} case typ.kind - of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool, tyRange: + of shouldChckCovered: chckCovered = true of tyFloat..tyFloat128, tyString, tyError: discard + of tyRange: + if skipTypes(typ.sons[0], abstractInst).kind in shouldChckCovered: + chckCovered = true of tyForward: errorUndeclaredIdentifier(c, n.sons[0].info, typ.sym.name.s) elif not isOrdinalType(typ): diff --git a/compiler/types.nim b/compiler/types.nim index e07d97948..8a9af3134 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1255,7 +1255,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, result = typeAllowedAux(marker, lastSon(t), kind, flags) of tyRange: if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin - {tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t + {tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t of tyOpenArray, tyVarargs, tySink: if kind != skParam: result = t diff --git a/tests/objvariant/tfloatrangeobj.nim b/tests/objvariant/tfloatrangeobj.nim new file mode 100644 index 000000000..cad2b2aa0 --- /dev/null +++ b/tests/objvariant/tfloatrangeobj.nim @@ -0,0 +1,13 @@ +discard """ + output: '''(kind: 2.0, twoStr: "TWO STR") +(kind: 1.0) +''' +""" +type + FloatRange = range[1.0..3.0] + VariantObj = object + case kind: FloatRange + of 2.0: twoStr: string + +echo VariantObj(kind: 2.0, twoStr: "TWO STR") +echo VariantObj(kind: 1.0) |