* discarding empty seqs now raises errors * the same goes for sets
This commit is contained in:
parent
c91ef1a09f
commit
fc7385bfda
3 changed files with 25 additions and 9 deletions
|
|
@ -40,6 +40,13 @@ const
|
||||||
|
|
||||||
proc implicitlyDiscardable(n: PNode): bool
|
proc implicitlyDiscardable(n: PNode): bool
|
||||||
|
|
||||||
|
proc hasEmpty(typ: PType): bool =
|
||||||
|
if typ.kind in {tySequence, tyArray, tySet}:
|
||||||
|
result = typ.lastSon.kind == tyEmpty
|
||||||
|
elif typ.kind == tyTuple:
|
||||||
|
for s in typ.sons:
|
||||||
|
result = result or hasEmpty(s)
|
||||||
|
|
||||||
proc semDiscard(c: PContext, n: PNode): PNode =
|
proc semDiscard(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
checkSonsLen(n, 1, c.config)
|
checkSonsLen(n, 1, c.config)
|
||||||
|
|
@ -47,7 +54,9 @@ proc semDiscard(c: PContext, n: PNode): PNode =
|
||||||
n[0] = semExprWithType(c, n[0])
|
n[0] = semExprWithType(c, n[0])
|
||||||
let sonType = n[0].typ
|
let sonType = n[0].typ
|
||||||
let sonKind = n[0].kind
|
let sonKind = n[0].kind
|
||||||
if isEmptyType(sonType) or sonType.kind in {tyNone, tyTypeDesc} or sonKind == nkTypeOfExpr:
|
if isEmptyType(sonType) or hasEmpty(sonType) or
|
||||||
|
sonType.kind in {tyNone, tyTypeDesc} or
|
||||||
|
sonKind == nkTypeOfExpr:
|
||||||
localError(c.config, n.info, errInvalidDiscard)
|
localError(c.config, n.info, errInvalidDiscard)
|
||||||
if sonType.kind == tyProc and sonKind notin nkCallKinds:
|
if sonType.kind == tyProc and sonKind notin nkCallKinds:
|
||||||
# tyProc is disallowed to prevent ``discard foo`` to be valid, when ``discard foo()`` is meant.
|
# tyProc is disallowed to prevent ``discard foo`` to be valid, when ``discard foo()`` is meant.
|
||||||
|
|
@ -410,13 +419,6 @@ proc semUsing(c: PContext; n: PNode): PNode =
|
||||||
if a[^1].kind != nkEmpty:
|
if a[^1].kind != nkEmpty:
|
||||||
localError(c.config, a.info, "'using' sections cannot contain assignments")
|
localError(c.config, a.info, "'using' sections cannot contain assignments")
|
||||||
|
|
||||||
proc hasEmpty(typ: PType): bool =
|
|
||||||
if typ.kind in {tySequence, tyArray, tySet}:
|
|
||||||
result = typ.lastSon.kind == tyEmpty
|
|
||||||
elif typ.kind == tyTuple:
|
|
||||||
for s in typ.sons:
|
|
||||||
result = result or hasEmpty(s)
|
|
||||||
|
|
||||||
proc hasUnresolvedParams(n: PNode; flags: TExprFlags): bool =
|
proc hasUnresolvedParams(n: PNode; flags: TExprFlags): bool =
|
||||||
result = tfUnresolved in n.typ.flags
|
result = tfUnresolved in n.typ.flags
|
||||||
when false:
|
when false:
|
||||||
|
|
|
||||||
14
tests/discard/tillegaldiscardtypes.nim
Normal file
14
tests/discard/tillegaldiscardtypes.nim
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nim check $file"
|
||||||
|
errormsg: "statement returns no value that can be discarded"
|
||||||
|
nimout: '''
|
||||||
|
tillegaldiscardtypes.nim(11, 3) Error: statement returns no value that can be discarded
|
||||||
|
tillegaldiscardtypes.nim(12, 3) Error: statement returns no value that can be discarded
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc b(v: int) = # bug #21360
|
||||||
|
discard @[]
|
||||||
|
discard []
|
||||||
|
|
||||||
|
b(0)
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "internal error: invalid kind for lastOrd(tyEmpty)"
|
errormsg: "statement returns no value that can be discarded"
|
||||||
"""
|
"""
|
||||||
var q = false
|
var q = false
|
||||||
discard (if q: {} else: {})
|
discard (if q: {} else: {})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue