Skip to content
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

Case Seq() is declared unreachable when matching a Vector #13931

Closed
ansvonwa opened this issue Nov 12, 2021 · 11 comments · Fixed by #14104 or #14112
Closed

Case Seq() is declared unreachable when matching a Vector #13931

ansvonwa opened this issue Nov 12, 2021 · 11 comments · Fixed by #14104 or #14112
Assignees
Labels
area:pattern-matching itype:bug prio:blocker regression This worked in a previous version but doesn't anymore
Milestone

Comments

@ansvonwa
Copy link
Contributor

Compiler version

3.1.1-RC1, 3.1.2-RC1-bin-20211102-82172ed-NIGHTLY but not in 3.1.0

Minimized code

Vector() match {
  case Seq() => println("empty")
  case _ => println("non-empty")
}

Output

[warn] 4 |      case Seq() => println("empty")
[warn]   |           ^^^^^
[warn]   |           Unreachable case
[warn] one warning found
[warn] one warning found
[info] running run 
empty

Expectation

No warning

@KacperFKorban KacperFKorban added area:pattern-matching regression This worked in a previous version but doesn't anymore labels Nov 12, 2021
@dwijnand dwijnand self-assigned this Nov 15, 2021
@dwijnand dwijnand changed the title Wrong "Unreachable case"-warning Case Seq() is declared unreachable when matching a Vector Nov 15, 2021
@SethTisue
Copy link
Member

SethTisue commented Dec 2, 2021

We should try hard to fix this regression — it seems pretty fundamental to me.

Note that it's not something about Vector specifically; IndexedSeq() match ... also fails

even IndexedSeq() match { case IndexedSeq() => ... fails

so does IndexedSeq(1) match { case IndexedSeq(1) => ...

@SethTisue
Copy link
Member

it would be nice to have a reproduction that is self-contained in the sense of not bringing in complicated collections classes like Vector and IndexedSeq, but my efforts so far to construct one have failed

@SethTisue SethTisue self-assigned this Dec 2, 2021
@dwijnand
Copy link
Member

dwijnand commented Dec 2, 2021

Looks like quite a tricky one... Looks like taking out one part fixes these and breaks some others: master...dwijnand:reachabarity. Check the comment in tests/patmat/exhaustive_heuristics.scala: I think what I'm taking out is doing that list unapply to cons build rewrite, but doing that breaks the 3 cases here.

@dwijnand
Copy link
Member

dwijnand commented Dec 2, 2021

See also scala/bug#12252, where I thought I came to learn that in Scala 3 the arity problem is properly dealt with. Looks like it does so by eagerly rewriting all seq's to cons lists, and that breaks these cases.

Also, something seems funky in master, because my patternMatcher logging is being emitted in "elimOpaque" phase.

@smarter
Copy link
Member

smarter commented Dec 2, 2021

is being emitted in "elimOpaque" phase.

I think that's normal even if it's confusing, the phase in the context is used to determine which denotation transformers should be run when accessing a denotation in the current context: it will be the denotation transformers of all phases less than ctx.phase, and tree transformers of a given (mega-)phase are always set to have the denotation transformer of that phase already run (for megaphases this is set in https://github.com/lampepfl/dotty/blob/d2b6bd5df40e93ed457295ba7b3aa0f6d689bd60/compiler/src/dotty/tools/dotc/transform/MegaPhase.scala#L460). To help deal with that you can do -Ylog:phaseName+ which is equivalent to -Ylog:phaseName,phaseAfterThat

@dwijnand
Copy link
Member

dwijnand commented Dec 3, 2021

Ah. I understand what you say, thank you very much for explaining. That's really unfortunate and annoying... That's not how it is in nsc, is it? Can we change this?

@smarter
Copy link
Member

smarter commented Dec 3, 2021

The phaseName+ thing is adequate I'd say, cause you do want to see the logs of the denotation transformer of phaseName itself too. To do something more precise you'd need to only enable the printer depending on the tree transformer maybe?

@odersky
Copy link
Contributor

odersky commented Dec 9, 2021

What is the commit that broke this? I believe this needs to be fixed before we ship 3.1.1.

@odersky
Copy link
Contributor

odersky commented Dec 9, 2021

It seems to be a commit from #13485

We should revert the PR unless we can figure this out right now and fix it. 3.1.1 RC 2 is overdue. We should not let regressions like this stay in the codebase.

@dwijnand
Copy link
Member

It seems to be a commit from #13485

We should revert the PR unless we can figure this out right now and fix it. 3.1.1 RC 2 is overdue. We should not let regressions like this stay in the codebase.

I'll look closer on Monday, but if we have to revert it would only have to be the emitting of the deferred warnings, not the rest of the PR. As in:

-        for (pat <- deferred.reverseIterator)
-          report.warning(MatchCaseUnreachable(), pat.srcPos)

@smarter smarter added this to the 3.1.1 milestone Dec 12, 2021
@dwijnand
Copy link
Member

I'll PR the revert and a backport of the revert, and then fix this afterwards.

@dwijnand dwijnand linked a pull request Dec 14, 2021 that will close this issue
@Kordyjan Kordyjan modified the milestones: 3.2.0-RC1, 3.1.2 Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:pattern-matching itype:bug prio:blocker regression This worked in a previous version but doesn't anymore
Projects
None yet
8 participants