-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #3144: emit warnings for unchecked type patterns #3156
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
Conversation
else { | ||
val ignoreWarning = args.forall(p => p.typeSymbol.is(BindDefinedType) || p.isInstanceOf[TypeBounds]) | ||
if (!ignoreWarning) | ||
ctx.warning(UncheckedTypePattern("type arguments are not unchecked since they are eliminated by erasure"), pos) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you meant to write "are not checked"
I think there are two separate issues described in #3144:
class Test {
def f(x: Any): Int = x match {
case xs: List[Int] @unchecked => xs.head
}
}
sealed trait Foo
class Bar
class Test {
def shouldError(foo: Foo) = foo match {
case _: Bar => 1
}
} |
@allanrenucci The second is not an issue, as there could be a class like the follows: class Ruu extends Bar with Foo |
@liufengyun But Foo is |
Ah I see, currently the algorithm just assumes the first case is always reachable to save some computation. We could also check if the first branch is reachable or not, but I'm not sure if it's worth it. BTW, we've checks for hopeless matches, which are located in |
If -- Error: tests/allan/Test.scala:6:9 -------------------------------------------
6 | case _: Foo => 1
| ^
| this case is unreachable since class Bar and class Foo are unrelated
one error found |
@allanrenucci That check is from |
You might want to add a test case for case xs: List[Int @unchecked] => |
tests/patmat/3144b.scala
Outdated
class Test { | ||
def f(x: Any): Int = x match { | ||
case xs: List[Int] @unchecked => xs.head | ||
case xs: List[Int @unchecked] => xs.head |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should extract this case into another function. This case is unreachable here
56c861b
to
07ea5f9
Compare
@@ -880,6 +880,16 @@ object messages { | |||
|""" | |||
} | |||
|
|||
case class UncheckedTypePattern(msg: String)(implicit ctx: Context) | |||
extends Message(UncheckedTypePatternID) { | |||
val kind = "Unchecked Type Pattern" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very specific kind, kinds are supposed to apply to more than one message, I guess here it could be "Pattern Match Exhaustivity" (kinds should also be an enum, but that's a separate issue).
|
||
val explanation = | ||
hl"""|Type arguments and type refinements are erased during compile time, thus it's | ||
|impossible to check them at run-time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The explanation could mention possible fixes: either replace the type arguments by _
or use @unchecked
.
case _ => | ||
debug.println(s"unknown pattern: $pat") | ||
Empty | ||
} | ||
|
||
/* Erase a type binding according to erasure semantics in pattern matching */ | ||
def erase(tp: Type): Type = tp match { | ||
def erase(tp: Type)(implicit warn: String => Unit): Type = tp match { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of passing an implicit around, you could have an outer function which defines warn
and an inner recursive function which uses it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smarter thanks a lot, I've addressed other comments. For this one, doing the refactoring would require to pass an additional Position
to erase
, which will make the API a little ugly.
07ea5f9
to
daa5b84
Compare
Fix #3144: emit warnings for unchecked type patterns