Skip to content

no warn when pattern match not exhaustive #23006

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

Open
road21 opened this issue Apr 16, 2025 · 5 comments
Open

no warn when pattern match not exhaustive #23006

road21 opened this issue Apr 16, 2025 · 5 comments
Labels
area:pattern-matching area:reporting Error reporting including formatting, implicit suggestions, etc itype:bug

Comments

@road21
Copy link
Contributor

road21 commented Apr 16, 2025

I was playing around #22993 and found the following regression.

Compiler version

3..4.3, 3.6.4, 3.7.1-RC1-bin-20250415-06886b0-NIGHTLY
(works in 3.3.5, 3.5.2)

Minimized code

sealed trait Foo[+T]
class Bar[+T](val t: T) extends Foo[T]

object Lol extends Bar[Int](1), Foo[Boolean]

def downcast[T](foo: Foo[T]): Bar[T] =
  foo match
    case b: Bar[T] => b

downcast[Boolean & Int](Lol).t == true

https://scastie.scala-lang.org/road21/4aa1fpYiSqqRLwRXh1BmSA/2

Output

Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Boolean

Expectation

I expect warning:

[warn] match may not be exhaustive.
@road21 road21 added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 16, 2025
@TomasMikula
Copy link
Contributor

FWIW, I'd expect inheriting from both Foo[Int] and Foo[Boolean] to be prohibited (unless provably Int <: Boolean). Does anyone have an, even hypothetical, use case for such weird inheritance hierarchies?

@bishabosha
Copy link
Member

bishabosha commented Apr 16, 2025

I don't see anything really wrong here with the pattern match, the final .t is typed as Int & Boolean and nowhere is it prevented to define a value of that type:

scala> def foo: Int & Boolean = ???
def foo: Int & Boolean
                                                                                                                                                                                                                                                                                 
scala> foo == true
scala.NotImplementedError: an implementation is missing
  at scala.Predef$.$qmark$qmark$qmark(Predef.scala:344)
  at rs$line$1$.foo(

what is a problem is that Scala 2.13.16 would issue an illegal inheritance error:

scala> sealed trait Foo[+T]
     | class Bar[+T](val t: T) extends Foo[T]
     | 
     | class Lol extends Bar[Int](1) with Foo[Boolean]
       class Lol extends Bar[Int](1) with Foo[Boolean]
             ^
On line 4: error: illegal inheritance;
        class Lol inherits different type instances of trait Foo:
       Foo[Boolean] and Foo[Int]

I dont that that is necessarily bad in scala 3, but there should probably be a type error in trying to assign val t: Int = 1 to Int & Boolean

@road21
Copy link
Contributor Author

road21 commented Apr 16, 2025

I don't see anything really wrong here with the pattern match

I expect that this pattern match is not exhaustive because:
We match value of type Foo[Boolean & Int] against type Bar[Boolean & Int].
Type Bar[Boolean & Int] is obviously empty (it can not have legal inhabitant).
Type Foo[Boolean & Int] is not empty, it has value Lol.

but there should probably be a type error in trying to assign val t: Int = 1 to Int & Boolean

Sorry, I don't see where we are assigning val t: Int = 1 to Int & Boolean

@TomasMikula
Copy link
Contributor

By allowing such (previously illegal) inheritance we

  • lose some deductive power (fact),
  • don't gain anything of value (hypothesis, prove me wrong).

I really hope that this is just a blip that's going to be corrected.

NB: I don't think there's anything wrong with a type Foo[Boolean] & Foo[Int]. I just think it's wrong to extend both Foo[Boolean] and Foo[Int]. If it's not wrong, it should be allowed directly, right? Would you argue to make the following legal?

sealed trait Foo[+T]
object Lol extends Foo[Int], Foo[Boolean] // Error: trait Foo is extended twice

@sjrd
Copy link
Member

sjrd commented Apr 17, 2025

Yes, I believe extending both in a concrete class should be rejected. @odersky Random guess: is that something in the realm of bad-bounds checking?

@Gedochao Gedochao added area:pattern-matching itype:soundness Soundness bug (it lets us compile code that crashes at runtime with a ClassCastException) area:reporting Error reporting including formatting, implicit suggestions, etc and removed stat:needs triage Every issue needs to have an "area" and "itype" label itype:soundness Soundness bug (it lets us compile code that crashes at runtime with a ClassCastException) labels Apr 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:pattern-matching area:reporting Error reporting including formatting, implicit suggestions, etc itype:bug
Projects
None yet
Development

No branches or pull requests

5 participants