Nim: Confusing error message for case expression with missing or void-typed `else` clause

Created on 12 Aug 2019  路  2Comments  路  Source: nim-lang/Nim


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.

Example

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

Current Output

/repro/case_expression.nim(8, 12) Error: expression 'foo()' is of type 'int' and has to be discarded

Expected Output


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'

Possible Solution

Additional Information

$ 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
Error messages

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 Nothing type in scala works as well.

All 2 comments

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 Nothing type 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
Was this page helpful?
0 / 5 - 0 ratings

Related issues

juancarlospaco picture juancarlospaco  路  3Comments

hlaaftana picture hlaaftana  路  3Comments

timotheecour picture timotheecour  路  3Comments

kobi2187 picture kobi2187  路  4Comments

Vindaar picture Vindaar  路  3Comments