Skip to content

False unreachable case warning for inlined code #19157

Closed
@odersky

Description

@odersky

Compiler version

3.4.0 RC 1

Minimized example

  inline def count(inline x: Boolean) = x match
    case true => 1
    case false => 0

  assert(count(true) == 1)
  assert(count(false) == 0)
  var x = true
  assert(count(x) == 1)

Output

-- [E030] Match case Unreachable Warning: tl-count.scala:7:14 ------------------
7 |  assert(count(true) == 1)
  |         ^^^^^^^^^^^
  |         Unreachable case
  |-----------------------------------------------------------------------------
  |Inline stack trace
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  |This location contains code that was inlined from tl-count.scala:5
5 |    case false => 0
  |         ^^^^^
   -----------------------------------------------------------------------------
-- [E030] Match case Unreachable Warning: tl-count.scala:8:14 ------------------
8 |  assert(count(false) == 0)
  |         ^^^^^^^^^^^^
  |         Unreachable case
  |-----------------------------------------------------------------------------
  |Inline stack trace
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  |This location contains code that was inlined from tl-count.scala:4
4 |    case true => 1
  |         ^^^^
   -----------------------------------------------------------------------------

Expectation

No warnings. Generally, unreachable case warnings should be disabled for code that was inlined.

I encountered this in the wild where it did not find the source line correctly and was completely stumped until I changed the error message to give me a little bit more info. After the change I got this, which was more intelligible. I think that would be a good idea independently, but ideally we also mention previous cases as proposed in #18519.

7 |  assert(count(true) == 1)
  |         ^^^^^^^^^^^
  |         Unreachable case:
  |         Pattern false
  |         cannot possibly match a selector of type (true : Boolean)
  |         at this point in the match sequence.
  |-----------------------------------------------------------------------------
  |Inline stack trace
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  |This location contains code that was inlined from tl-count.scala:5
5 |    case false => 0
  |         ^^^^^
   -----------------------------------------------------------------------------
-- [E030] Match case Unreachable Warning: tl-count.scala:8:14 ------------------
8 |  assert(count(false) == 0)
  |         ^^^^^^^^^^^^
  |         Unreachable case:
  |         Pattern true
  |         cannot possibly match a selector of type (false : Boolean)
  |         at this point in the match sequence.
  |-----------------------------------------------------------------------------
  |Inline stack trace
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  |This location contains code that was inlined from tl-count.scala:4
4 |    case true => 1
  |         ^^^^
   -----------------------------------------------------------------------------

Overall, I believe that eliminating false unreachable warnings and improving error messages for real ones should be a priority for us. It's a major source of unfriendliness and head-scratching. And the other thing really needing improvement is a more robust reporting of inline traces. I noted when they come from different compilation units they are often wrong.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions