Skip to content

flaky match may not be exhaustive in case of tuples #12341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
robstoll opened this issue Feb 12, 2021 · 6 comments
Closed

flaky match may not be exhaustive in case of tuples #12341

robstoll opened this issue Feb 12, 2021 · 6 comments

Comments

@robstoll
Copy link

reproduction steps

Unfortunately, hard to reproduce as the error does not always occur and it happens in close-source code, so I cannot share a real example. I tried to reproduce it with the following on scastie but it compiles correctly:

object JoinedStructure3 {
    def unapply[T1, T2, T3](p: ((T1, T2), T3)): Option[(T1, T2, T3)] = p match {
        case ((t1, t2), t3) => Some((t1, t2, t3))
        case _ => None
    }
  
    def filter(f: ((Int, Int), Int) => Int) = ???
  
    def test() = {
      filter { 
        case JoinedStructure3(a, b, c) => a + b + c  // sometimes fails
      }
      filter { 
        case ((a, b), c) => a + b + c  // basically the same but never fails
      }
    }
  }

As context, in the real world example it is a slick Query which is inner joined, and the problem also occurs when using map not only filter.

problem

It happens, but not in all cases, that the compiler emits a warning:

: [other-match-analysis @ com.example.Xy.myQuery] match may not be exhaustive.
[warn] It would fail on the following input: (_, _)
[warn]           .filter {
[warn]                   ^

As shown above in the example, when I am not using the helper construct but ((a, b), c) then I never have the problem.
Also, the helper construct also exists for more than 3 joined tables and there we never run into the problem.

I know, the bug report is a bit fuzzy but I hope it helps nonetheless to track down the problem.

@martijnhoekstra
Copy link

martijnhoekstra commented Feb 12, 2021

Does the same happen if JoinedStructure3.unapply returns Some[(T1, T2, T3)] rather than Option[(T1, T2, T3)]? (or is it some whitebox macro that, depending on the context, may return Some or Option?)

@robstoll
Copy link
Author

That's a good, point there is actually no reason to have the default case in the unapply method, going to try that one out.
Also, I just realised why it is flaky. Someone has suppressed the warnign with @nowarn("cat=other-match-analysis") and since it was not nearby, I have not spotted it. Thus closing this issue and re-open in case it should still occur.
thanks @martijnhoekstra for your help

@som-snytt
Copy link

They need an -Xlint for when nowarn is not nearby. -Xlint:nowarn-action-at-a-distance.

@robstoll
Copy link
Author

I know you are joking a bit but it's not entirely wrong. I see often that e.g. deprecations are suppressed for whole classes/traits where it would be better if they are suppressed for the very usage only

@som-snytt
Copy link

Yes, usually I am joking a bit but not entirely wrong. I think this is why go and scala have resisted the warnings and suppression dance. I have come around to the viewpoint that anything short of incorrectness (an error) should be treated by a 3rd party tool (linter) where local preferences determine policy. For example, suppressing too much might error. OTOH, I don't like how this plays out IRL, where "style policies" fail the build on dubious grounds.

@som-snytt
Copy link

The ticket for meta-lint is #13057

@som-snytt som-snytt closed this as not planned Won't fix, can't repro, duplicate, stale Apr 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants