summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorLemonBoy <LemonBoy@users.noreply.github.com>2018-07-01 15:27:14 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-07-01 15:27:14 +0200
commitdbbe311e18e1c7a2ecf6d9788010400161507532 (patch)
treec110d1719679bb22732b54d76e856f07f09d83a0
parentb61e69202bfc5f0d122973b8e9cdaf88350f5f73 (diff)
downloadNim-dbbe311e18e1c7a2ecf6d9788010400161507532.tar.gz
Minor changes to discardable handling (#8155)
-rw-r--r--compiler/semexprs.nim13
-rw-r--r--compiler/semstmts.nim15
-rw-r--r--tests/exprs/tstmtexprs.nim10
3 files changed, 17 insertions, 21 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 031174e5d..f5f5915d4 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -908,19 +908,6 @@ proc buildEchoStmt(c: PContext, n: PNode): PNode =
 
 proc semExprNoType(c: PContext, n: PNode): PNode =
   result = semExpr(c, n, {efWantStmt})
-  # make an 'if' expression an 'if' statement again for backwards
-  # compatibility (.discardable was a bad idea!); bug #6980
-  var isStmt = false
-  if result.kind == nkIfExpr:
-    isStmt = true
-    for condActionPair in result:
-      let action = condActionPair.lastSon
-      if not implicitlyDiscardable(action) and not
-          endsInNoReturn(action):
-        isStmt = false
-    if isStmt:
-      result.kind = nkIfStmt
-      result.typ = nil
   discardCheck(c, result)
 
 proc isTypeExpr(n: PNode): bool =
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 945bcd9e1..bf004a531 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -111,13 +111,15 @@ proc semExprBranchScope(c: PContext, n: PNode): PNode =
 const
   skipForDiscardable = {nkIfStmt, nkIfExpr, nkCaseStmt, nkOfBranch,
     nkElse, nkStmtListExpr, nkTryStmt, nkFinally, nkExceptBranch,
-    nkElifBranch, nkElifExpr, nkElseExpr, nkBlockStmt, nkBlockExpr}
+    nkElifBranch, nkElifExpr, nkElseExpr, nkBlockStmt, nkBlockExpr,
+    nkHiddenStdConv}
 
 proc implicitlyDiscardable(n: PNode): bool =
   var n = n
   while n.kind in skipForDiscardable: n = n.lastSon
-  result = isCallExpr(n) and n.sons[0].kind == nkSym and
-           sfDiscardable in n.sons[0].sym.flags
+  result = n.kind == nkRaiseStmt or
+           (isCallExpr(n) and n.sons[0].kind == nkSym and
+           sfDiscardable in n.sons[0].sym.flags)
 
 proc fixNilType(c: PContext; n: PNode) =
   if isAtom(n):
@@ -132,11 +134,8 @@ proc discardCheck(c: PContext, result: PNode) =
   if c.matchedConcept != nil: return
   if result.typ != nil and result.typ.kind notin {tyStmt, tyVoid}:
     if implicitlyDiscardable(result):
-      var n = result
-      result.typ = nil
-      while n.kind in skipForDiscardable:
-        n = n.lastSon
-        n.typ = nil
+      var n = newNodeI(nkDiscardStmt, result.info, 1)
+      n[0] = result
     elif result.typ.kind != tyError and c.config.cmd != cmdInteractive:
       var n = result
       while n.kind in skipForDiscardable: n = n.lastSon
diff --git a/tests/exprs/tstmtexprs.nim b/tests/exprs/tstmtexprs.nim
index 577f314ec..e91c20458 100644
--- a/tests/exprs/tstmtexprs.nim
+++ b/tests/exprs/tstmtexprs.nim
@@ -151,3 +151,13 @@ if true:
   fooBool()
 else:
   raise newException(ValueError, "argh")
+
+# bug #5374
+
+proc test1(): int64 {.discardable.} = discard
+proc test2(): int {.discardable.} = discard
+
+if true:
+  test1()
+else:
+  test2()