Skip to content

Incorrect Pattern Match Exhaustivity Warning  #9354

@johnynek

Description

@johnynek

Minimized code

See cats at this position:
https://github.com/typelevel/cats/blob/5ac10adbc1714e025ae2b6e9429028d5aea4d309/core/src/main/scala/cats/data/AndThen.scala#L95

  private def runLoop(start: T): R = {
    var self: AndThen[Any, Any] = this.asInstanceOf[AndThen[Any, Any]]
    var current: Any = start.asInstanceOf[Any]
    var continue = true

    while (continue) {
      self match {
        case Single(f, _) =>
          current = f(current)
          continue = false

        case Concat(Single(f, _), right) =>
          current = f(current)
          self = right.asInstanceOf[AndThen[Any, Any]]

        case Concat(left @ Concat(_, _), right) =>
          self = left.rotateAccum(right)
      }
    }
    current.asInstanceOf[R]
  }

This gives a warning that AndThen.Single(_, _) and AndThen.Concat(AndThen.Single(_, _), _) would fail, but those are the first and second elements of the match respectively:

[warn] -- [E029] Pattern Match Exhaustivity Warning: /home/oscarboykin/oss/cats/core/src/main/scala/cats/data/AndThen.scala:95:6 
[warn] 95 |      self match {
[warn]    |      ^^^^
[warn]    |match may not be exhaustive.
[warn]    |
[warn]    |It would fail on pattern case: AndThen.Single(_, _), AndThen.Concat(AndThen.Single(_, _), _)

I guess this may have to do with the specific type parameters changing in this loop. Note we cast to AndThen[Any, Any] but the internal types will have different types.

If that is the problem, maybe we could have a clearer error message because it is confusing to see a claim that a pattern wouldn't match that is explicitly in the match.

cc @travisbrown who has spent time on dotty and cats.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions