range/case fixes (#11264)
This commit is contained in:
parent
e26545797e
commit
90ed904c4d
4 changed files with 28 additions and 6 deletions
|
|
@ -878,10 +878,14 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
||||||
var covered: BiggestInt = 0
|
var covered: BiggestInt = 0
|
||||||
var typ = commonTypeBegin
|
var typ = commonTypeBegin
|
||||||
var hasElse = false
|
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
|
case caseTyp.kind
|
||||||
of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool:
|
of shouldChckCovered:
|
||||||
chckCovered = true
|
chckCovered = true
|
||||||
|
of tyRange:
|
||||||
|
if skipTypes(caseTyp.sons[0], abstractInst).kind in shouldChckCovered:
|
||||||
|
chckCovered = true
|
||||||
of tyFloat..tyFloat128, tyString, tyError:
|
of tyFloat..tyFloat128, tyString, tyError:
|
||||||
discard
|
discard
|
||||||
else:
|
else:
|
||||||
|
|
@ -889,7 +893,7 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
||||||
result = handleCaseStmtMacro(c, n)
|
result = handleCaseStmtMacro(c, n)
|
||||||
if result != nil: return result
|
if result != nil: return result
|
||||||
|
|
||||||
localError(c.config, n.info, errSelectorMustBeOfCertainTypes)
|
localError(c.config, n.sons[0].info, errSelectorMustBeOfCertainTypes)
|
||||||
return
|
return
|
||||||
for i in 1 ..< sonsLen(n):
|
for i in 1 ..< sonsLen(n):
|
||||||
var x = n.sons[i]
|
var x = n.sons[i]
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,8 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if not hasUnknownTypes:
|
if not hasUnknownTypes:
|
||||||
if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})):
|
if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})):
|
||||||
localError(c.config, n.info, "type mismatch")
|
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")
|
localError(c.config, n.info, "ordinal or float type expected")
|
||||||
elif enumHasHoles(rangeT[0]):
|
elif enumHasHoles(rangeT[0]):
|
||||||
localError(c.config, n.info, "enum '$1' has holes" % typeToString(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 covered: BiggestInt = 0
|
||||||
var chckCovered = false
|
var chckCovered = false
|
||||||
var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc})
|
var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc})
|
||||||
|
const shouldChckCovered = {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool}
|
||||||
case typ.kind
|
case typ.kind
|
||||||
of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool, tyRange:
|
of shouldChckCovered:
|
||||||
chckCovered = true
|
chckCovered = true
|
||||||
of tyFloat..tyFloat128, tyString, tyError:
|
of tyFloat..tyFloat128, tyString, tyError:
|
||||||
discard
|
discard
|
||||||
|
of tyRange:
|
||||||
|
if skipTypes(typ.sons[0], abstractInst).kind in shouldChckCovered:
|
||||||
|
chckCovered = true
|
||||||
of tyForward:
|
of tyForward:
|
||||||
errorUndeclaredIdentifier(c, n.sons[0].info, typ.sym.name.s)
|
errorUndeclaredIdentifier(c, n.sons[0].info, typ.sym.name.s)
|
||||||
elif not isOrdinalType(typ):
|
elif not isOrdinalType(typ):
|
||||||
|
|
|
||||||
|
|
@ -1255,7 +1255,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
result = typeAllowedAux(marker, lastSon(t), kind, flags)
|
result = typeAllowedAux(marker, lastSon(t), kind, flags)
|
||||||
of tyRange:
|
of tyRange:
|
||||||
if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
|
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:
|
of tyOpenArray, tyVarargs, tySink:
|
||||||
if kind != skParam:
|
if kind != skParam:
|
||||||
result = t
|
result = t
|
||||||
|
|
|
||||||
13
tests/objvariant/tfloatrangeobj.nim
Normal file
13
tests/objvariant/tfloatrangeobj.nim
Normal file
|
|
@ -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)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue