* Fix semRecordCase * Fix ftpclient.nim * Check for ordinal type * Check tyRange for exhaustiveness
This commit is contained in:
commit
72500420d3
3 changed files with 20 additions and 18 deletions
|
|
@ -95,13 +95,6 @@ proc semWhile(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
||||||
elif efInTypeof in flags:
|
elif efInTypeof in flags:
|
||||||
result.typ = n[1].typ
|
result.typ = n[1].typ
|
||||||
|
|
||||||
proc toCover(c: PContext, t: PType): BiggestInt =
|
|
||||||
let t2 = skipTypes(t, abstractVarRange-{tyTypeDesc})
|
|
||||||
if t2.kind == tyEnum and enumHasHoles(t2):
|
|
||||||
result = sonsLen(t2.n)
|
|
||||||
else:
|
|
||||||
result = lengthOrd(c.config, skipTypes(t, abstractVar-{tyTypeDesc}))
|
|
||||||
|
|
||||||
proc semProc(c: PContext, n: PNode): PNode
|
proc semProc(c: PContext, n: PNode): PNode
|
||||||
|
|
||||||
proc semExprBranch(c: PContext, n: PNode; flags: TExprFlags = {}): PNode =
|
proc semExprBranch(c: PContext, n: PNode; flags: TExprFlags = {}): PNode =
|
||||||
|
|
|
||||||
|
|
@ -591,6 +591,13 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
|
||||||
for i in lastIndex.succ..(sonsLen(branch) - 2):
|
for i in lastIndex.succ..(sonsLen(branch) - 2):
|
||||||
checkForOverlap(c, t, i, branchIndex)
|
checkForOverlap(c, t, i, branchIndex)
|
||||||
|
|
||||||
|
proc toCover(c: PContext, t: PType): BiggestInt =
|
||||||
|
let t2 = skipTypes(t, abstractVarRange-{tyTypeDesc})
|
||||||
|
if t2.kind == tyEnum and enumHasHoles(t2):
|
||||||
|
result = sonsLen(t2.n)
|
||||||
|
else:
|
||||||
|
result = lengthOrd(c.config, skipTypes(t, abstractVar-{tyTypeDesc}))
|
||||||
|
|
||||||
proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
father: PNode, rectype: PType, hasCaseFields = false)
|
father: PNode, rectype: PType, hasCaseFields = false)
|
||||||
proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
|
|
@ -603,15 +610,16 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
return
|
return
|
||||||
incl(a.sons[0].sym.flags, sfDiscriminant)
|
incl(a.sons[0].sym.flags, sfDiscriminant)
|
||||||
var covered: BiggestInt = 0
|
var covered: BiggestInt = 0
|
||||||
|
var chckCovered = false
|
||||||
var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc})
|
var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc})
|
||||||
if not isOrdinalType(typ):
|
case typ.kind
|
||||||
localError(c.config, n.info, "selector must be of an ordinal type")
|
of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool, tyRange:
|
||||||
elif firstOrd(c.config, typ) != 0:
|
chckCovered = true
|
||||||
localError(c.config, n.info, "low(" & $a.sons[0].sym.name.s &
|
of tyFloat..tyFloat128, tyString, tyError:
|
||||||
") must be 0 for discriminant")
|
discard
|
||||||
elif lengthOrd(c.config, typ) > 0x00007FFF:
|
else:
|
||||||
localError(c.config, n.info, "len($1) must be less than 32768" % a.sons[0].sym.name.s)
|
if not isOrdinalType(typ):
|
||||||
var chckCovered = true
|
localError(c.config, n.info, "selector must be of an ordinal type, float or string")
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
var b = copyTree(n.sons[i])
|
var b = copyTree(n.sons[i])
|
||||||
addSon(a, b)
|
addSon(a, b)
|
||||||
|
|
@ -620,12 +628,14 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
checkMinSonsLen(b, 2, c.config)
|
checkMinSonsLen(b, 2, c.config)
|
||||||
semCaseBranch(c, a, b, i, covered)
|
semCaseBranch(c, a, b, i, covered)
|
||||||
of nkElse:
|
of nkElse:
|
||||||
chckCovered = false
|
|
||||||
checkSonsLen(b, 1, c.config)
|
checkSonsLen(b, 1, c.config)
|
||||||
|
if chckCovered and covered == toCover(c, a.sons[0].typ):
|
||||||
|
localError(c.config, b.info, "invalid else, all cases are already covered")
|
||||||
|
chckCovered = false
|
||||||
else: illFormedAst(n, c.config)
|
else: illFormedAst(n, c.config)
|
||||||
delSon(b, sonsLen(b) - 1)
|
delSon(b, sonsLen(b) - 1)
|
||||||
semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype, hasCaseFields = true)
|
semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype, hasCaseFields = true)
|
||||||
if chckCovered and covered != lengthOrd(c.config, a.sons[0].typ):
|
if chckCovered and covered != toCover(c, a.sons[0].typ):
|
||||||
localError(c.config, a.info, "not all cases are covered")
|
localError(c.config, a.info, "not all cases are covered")
|
||||||
addSon(father, a)
|
addSon(father, a)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,6 @@ type
|
||||||
oneSecond: BiggestInt # Bytes transferred in one second.
|
oneSecond: BiggestInt # Bytes transferred in one second.
|
||||||
lastProgressReport: float # Time
|
lastProgressReport: float # Time
|
||||||
toStore: string # Data left to upload (Only used with async)
|
toStore: string # Data left to upload (Only used with async)
|
||||||
else: nil
|
|
||||||
|
|
||||||
FtpClientObj* = FtpBaseObj[Socket]
|
FtpClientObj* = FtpBaseObj[Socket]
|
||||||
FtpClient* = ref FtpClientObj
|
FtpClient* = ref FtpClientObj
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue