The error message for case expression with missing or void-typed else clause is confusing and doesn't tell the programmer what's actually wrong or how to fix it.
import random
proc foo(): int = 7
proc bar(): int = 8
proc baz(): int = 9
let result = case rand(1..3)
of 1: foo()
of 2: bar()
of 3: baz()
else: assert false, "can't happen"
echo result
/repro/case_expression.nim(8, 12) Error: expression 'foo()' is of type 'int' and has to be discarded
Not sure, but maybe something like:
/repro/case_expression.nim(8, 12) Error: `else` clause has no type or is ambiguous
If you add the compiler's recommended discard to the function calls, you get something that is more actionable but kind of gross looking:
/repro/case_expression.nim(7, 14) Error: expression 'case rand(1 .. 3)
of 1:
discard foo()
of 2:
discard bar()
of 3:
discard baz()
else:
const
expr279228 = "false"
const
loc279231 = (filename: "/repro/case_expression.nim",
line: 11, column: 15)
ploc279232 = "/repro/case_expression.nim(11, 16)"
{.line: (filename: "/repro/case_expression.nim", line: 11,
column: 15).}:
if true:
failedAssertImpl("/repro/case_expression.nim(11, 16) `false` can\'t happen")' has no type (or is ambiguous)
Also, if there is a concrete but mismatching type then the error is much better:
repro_case_expression.nim(11, 12) Error: type mismatch: got <Gadget> but expected 'int'
$ nim -v
Nim Compiler Version 0.20.2 [Linux: amd64]
Compiled at 2019-07-17
Copyright (c) 2006-2019 by Andreas Rumpf
git hash: 88a0edba4b1a3d535b54336fd589746add54e937
active boot switches: -d:release
I would argue that if you have a noreturn void proc in the else branch, the compiler should still evaluate the whole case statement as expression. This is how the Nothing type in scala works as well.
I would argue that if you have a noreturn void proc in the else branch, the compiler should still evaluate the whole case statement as expression. This is how the
Nothingtype in scala works as well.
It does, it's just that Nim doesn't know in advance that assert false doesn't return
https://play.nim-lang.org/#ix=1THq
let x = case true:
of true: 123
else: raiseAssert ""
assert x == 123
Most helpful comment
I would argue that if you have a noreturn void proc in the else branch, the compiler should still evaluate the whole case statement as expression. This is how the
Nothingtype in scala works as well.