-
Notifications
You must be signed in to change notification settings - Fork 1.1k
No warning/error when matching unrelated object types #9740
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
Comments
This seems to be the correct behavior. See the following example: class Error {
abstract class RecoveryCompleted
case object RecoveryCompleted extends RecoveryCompleted {
override def equals(that: Any): Boolean = that == TypedRecoveryCompleted
}
abstract class TypedRecoveryCompleted
case object TypedRecoveryCompleted extends TypedRecoveryCompleted
TypedRecoveryCompleted match {
case RecoveryCompleted => println("Recovery completed")
case TypedRecoveryCompleted => println("Typed recovery completed")
}
}
object Test {
def main(args: Array[String]): Unit = new Error
} The first branch matches. |
Related: #3200 scala/bug#1503 |
This fails in 2.13, I just assumed this would also fail in Dotty.
The context for this is that I never got a |
@olofwalker Thanks for clarifying the context. It's a difference between Scala 2 and Scala 3. Maybe Scala 3 should be more conservative here to prevent such mistakes. |
@liufengyun I think I would have been helped by a warning, its a bit like Scala 2, you unknowingly import an implicit, and all of a sudden things work differently. |
We can't just copy what 2.13 is doing here as demonstrated by Fengyun's example in #9740 (comment), scalac wrongly emits an error even though this code is correct. We would have to check if |
It is incomplete, but it seems sound/safe to reject the code. The additional expressiveness seems to be not useful in practice, and usually implies something goes wrong. |
It's safe but it might be annoying to someone :). But I think if we only emit the warning if |
Oops actually we want to check the symbol of the case, not the symbol of the scrutinee. |
After reflection, I think the correct thing to do is either (1) disallow all such cases; or (2) allow all such cases. Anything in the middle (like checking whether the member Disallowing all such usage would align with Scala 2 and prevent accidental errors in practice. It's safe and sound -- incompleteness is fine, as static checks are all incomplete for good reasons. Are there valid use cases that justify allowing such usage? |
I agree. Can always make it more complicated if that proves too annoying - which hasn't appeared to be the case for Scala 2 users so far. The argument around Fengyun's example to me seems to revolve around the fact that any scrutinee type (e.g. |
We enforce that when pattern match on an object, the object should be a subtype of the scrutinee type. Reasons for doing so: - such code patterns usually implies hidden errors in the code - it's always safe/sound to reject the code We could check whether `equals` is overridden in the object, but - it complicates the protocol - overriding `equals` of object is also a bad practice - there is no sign that the slightly improved completeness is useful
We enforce that when pattern match on an object, the object should be a subtype of the scrutinee type. Reasons for doing so: - such code patterns usually implies hidden errors in the code - it's always safe/sound to reject the code We could check whether `equals` is overridden in the object, but - it complicates the protocol - overriding `equals` of object is also a bad practice - there is no sign that the slightly improved completeness is useful
Fix #9740: harden type checking for pattern match on objects
Uh oh!
There was an error while loading. Please reload this page.
Minimized code
Dotty 0.27-RC1
Output
Nothing
Expectation
Something like:
The text was updated successfully, but these errors were encountered: