diff options
-rw-r--r-- | compiler/injectdestructors.nim | 4 | ||||
-rw-r--r-- | compiler/semstmts.nim | 1 | ||||
-rw-r--r-- | tests/discard/tdiscardable.nim | 24 |
3 files changed, 27 insertions, 2 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 98751c7c5..d641b11e6 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -653,7 +653,7 @@ template handleNestedTempl(n, processCall: untyped, willProduceStmt = false, for j in 0 ..< it.len-1: branch[j] = copyTree(it[j]) var ofScope = nestedScope(s, it.lastSon) - branch[^1] = if it[^1].typ.isEmptyType or willProduceStmt: + branch[^1] = if n.typ.isEmptyType or it[^1].typ.isEmptyType or willProduceStmt: processScope(c, ofScope, maybeVoid(it[^1], ofScope)) else: processScopeExpr(c, ofScope, it[^1], processCall, tmpFlags) @@ -701,7 +701,7 @@ template handleNestedTempl(n, processCall: untyped, willProduceStmt = false, #Condition needs to be destroyed outside of the condition/branch scope branch[0] = p(it[0], c, s, normal) - branch[^1] = if it[^1].typ.isEmptyType or willProduceStmt: + branch[^1] = if n.typ.isEmptyType or it[^1].typ.isEmptyType or willProduceStmt: processScope(c, branchScope, maybeVoid(it[^1], branchScope)) else: processScopeExpr(c, branchScope, it[^1], processCall, tmpFlags) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index e4f22f435..32219a977 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -283,6 +283,7 @@ proc discardCheck(c: PContext, result: PNode, flags: TExprFlags) = if implicitlyDiscardable(result): var n = newNodeI(nkDiscardStmt, result.info, 1) n[0] = result + # notes that it doesn't transform nodes into discard statements elif result.typ.kind != tyError and c.config.cmd != cmdInteractive: if result.typ.kind == tyNone: localError(c.config, result.info, "expression has no type: " & diff --git a/tests/discard/tdiscardable.nim b/tests/discard/tdiscardable.nim index 5988f5949..31020251f 100644 --- a/tests/discard/tdiscardable.nim +++ b/tests/discard/tdiscardable.nim @@ -140,3 +140,27 @@ block: # issue #14665 continue inc i test() + +block: # bug #23775 + proc retInt(): int {.discardable.} = + 42 + + proc retString(): string {.discardable.} = + "text" + + type + Enum = enum + A, B, C, D + + proc doStuff(msg: Enum) = + case msg: + of A: + retString() + of B: + retInt() + of C: + discard retString() + else: + let _ = retString() + + doStuff(C) |