scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

Spurious 'unreachable code' when pattern matching a compound type including a sealed trait #12771

Open noresttherein opened 1 year ago

noresttherein commented 1 year ago

Reproduction steps

Scala version: 2.13.10

in "file1.scala":

    sealed trait T[+X <: E[X]]
    trait S[+X <: E[X]] extends T[X]
    trait A extends T[A]
    trait B extends A with T[B]

    type E[+X <: A with T[X]] =
        A with T[X]

in "file2.scala":

    def test[E1 <: E[E1], E2 <: E[E2]](a :E[E1], b :E[E2]) =
        (a, b) match {
            case (_, _ :B) => 3
            case (_ :B, _) => 2
            case _ => 4
        }

Problem

unreachable code
            case (_ :B, _) => 2
SethTisue commented 1 year ago

two files isn't needed, one will do. S can be omitted

Scala 3.3.0-RC3 refuses to compile the code with:

[error] Cyclic reference involving type E
[error]   sealed trait T[+X <: E[X]]
[error]                        ^
noresttherein commented 1 year ago

Hmm. I certainly was in a situation where my example compiled, and only moving it outside reproduces the warning I was seeing in my code. Maybe further reduction of the example made it work again. And while I knew that S isn't needed for reproducing, I thought it might be important in that no exhaustivity check may take place in this case.

Scala 3.3.0-RC3 refuses to compile the code with:

Then I am in deep ****. Is there any way to work around it? EDIT: wait, I have just tried in scastie, and it works for me? link

SethTisue commented 1 year ago

maybe because I wrapped the whole thing in an object Test? 🤷

% cat S.scala 
object Test {
  type E[+X <: A with T[X]] = A with T[X]
  sealed trait T[+X <: E[X]]
  trait A extends T[A]
  trait B extends A with T[B]
  def test[E1 <: E[E1], E2 <: E[E2]](a :E[E1], b :E[E2]) =
    (a, b) match {
      case (_, _ :B) =>
      case (_ :B, _) =>
      case _ =>
    }
}
% scala-cli compile -S 3.3.0-RC3 .
Compiling project (Scala 3.3.0-RC3, JVM)
[error] ./S.scala:3:24
[error] Cyclic reference involving type E
[error]   sealed trait T[+X <: E[X]]
[error]                        ^
Error compiling project (Scala 3.3.0-RC3, JVM)
Compilation failed
noresttherein commented 1 year ago

No. It's the definition order between E and T - if T is before E, it compiles, otherwise not. Is it how it should be, or is it also a bug?

som-snytt commented 1 year ago

I was just reading dotty 17221 and this is 12771...

I agree that "complete reproduction" matters -- whether imports, package objects, etc, are involved. How are elements brought into scope? Especially if experiment shows that order of definitions makes a difference.

I see the 2.13 warning, and it compiles for me using 3.3.1-RC1-bin-SNAPSHOT-git-d4a8600 in various orderings or importations.

Except Seth's version errors as shown. Was that the E.T. phone home version?

Yes, that must be a dotty bug. Whatever the limitation, statement order should not matter. Right?

noresttherein commented 1 year ago

As Seth has said, it seems separate files are not needed, I might have chased the wrong squirrel while trying to reproduce. Here's a minimal example for Scala 2 and the tangent issue (can't say if it qualifies as a bug) for Scala 3

som-snytt commented 1 year ago

I meant specifically that scastie is not a good way to represent minimal repro, as the wrapping introduces cruft. (Sometimes scastie wrapping specifically induces some bad behavior. By sometimes, I mean at least once in my experience, much like REPL bugs.)

But thanks for additional minimization.

Edit: maybe top-level type in Scala 3 means the same as in scastie, or maybe not, for example; and then, how to code it in Scala 2 standalone.

Edit: I created the dotty ticket, see link.

noresttherein commented 1 year ago

Ok, sorry, I'll have it in mind in the future.