inko icon indicating copy to clipboard operation
inko copied to clipboard

Infer all match case types as nil if any one of them is nil, regardless of their order

Open yorickpeterse opened this issue 2 years ago • 0 comments

Description

If the first case in a match returns nil, the compiler treats all case statements as returning nil and the return type of match as a whole is also nil. The idea was that if the first case returns nil then you shouldn't have to explicitly add nil in the others, as you almost certainly just want to ignore the value.

A pattern where this gets annoying is this:

match foo {
  case A -> some_map.set(x, y)
  case B -> {}
}

If some_map is e.g. Map[String, Int], the compiler now complains that case B -> {} isn't compatible with Option[Int] as returned by Map.set. To work around that one must do this:

match foo {
  case A -> {
    some_map.set(x, y)
    nil
  }
  case B -> nil
}

To make this easier, we should change the inference rules such that if any case returns nil, regardless of the order, they all return nil. This way no explicit nil is needed in the above case, and it (in general) better captures what one means when a case returns nil (= you don't care about the return value).

Implementing this would require two passes over the case statements in a match: one pass to type-check their bodies and determine the return type (during which we also set a flag if we encounter nil), and a pass to ensure those return types are compatible with the first case return type (unless we encountered a nil).

Related work

No response

yorickpeterse avatar Nov 25 '23 23:11 yorickpeterse