-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #3588: Do not emit switch when matching on Any #3589
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
As done |
val switchCases = collectSwitchCases(plan) | ||
val switchCases = | ||
if (plan.scrutinee.tpe.widen.classSymbol == defn.AnyClass) Nil | ||
else collectSwitchCases(plan) |
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 it should be part of collectSwitchCases
and maybe use the already defined isSwitchableType
function
ba339ff
to
00dc76d
Compare
@@ -795,7 +795,8 @@ object PatternMatcher { | |||
(tpe isRef defn.IntClass) || | |||
(tpe isRef defn.ByteClass) || | |||
(tpe isRef defn.ShortClass) || | |||
(tpe isRef defn.CharClass) | |||
(tpe isRef defn.CharClass) || | |||
(tpe isRef defn.StringClass) |
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.
Scalac does not emit switch for String
. Is it a limitation we can lift? Java supports switch for String
since JDK 7
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.
https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11 and how achieve the same with dotty's enum?
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.
We have code testing that strings are switchable. I saw that failure in the first commit.
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.
Is support for switching on strings actually implemented somewhere in the compiler? The Java support is implemented by desugaring them into two switch statements on integers, there is no bytecode-level support for switching on strings.
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.
We currenly do exactly the same as in scalac. We desugar it into if/then/else
1c9c526
to
9f1f890
Compare
library/test/dotty/ShowTests.scala
Outdated
@@ -64,7 +64,7 @@ class ShowTests { | |||
case class Car(model: String, manufacturer: String, year: Int) | |||
|
|||
assertEquals("Car(Mustang,Ford,1967)", Car("Mustang", "Ford", 1967).show) | |||
assertEquals("Map()", Map().show) | |||
assertEquals("Map()", Map[String, String]().show) |
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.
What's the warning emitted?
The test actually expect something of type Map[Nothing, Nothing]
.
9f1f890
to
0ba8e23
Compare
(tpe isRef defn.ByteClass) || | ||
(tpe isRef defn.ShortClass) || | ||
(tpe isRef defn.CharClass) | ||
|
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 tried with isSwitchableType
and it seems to work if you widen before calling it:
isSwitchableType(scrutinee.tpe.widen)
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.
done
case A(3) => | ||
case _ => | ||
} | ||
} |
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 would add two more tests:
- a pos test compiled with
-Xfatal-warnings
:
class Test {
def test(x: 1) = (x: @annotation.switch) match {
case 1 => 1
case 2 => 2
case 3 => 3
}
}
- a neg test compiled with
-Xfatal-warnings
:
object Test {
case class IntAnyVal(x: Int) extends AnyVal
def test(x: IntAnyVal) = (x: @annotation.switch) match { //error: warning: could not emit switch
case IntAnyVal(1) => 1
case IntAnyVal(2) => 2
case IntAnyVal(3) => 3
case _ => 4
}
}
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.
Done
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.
LGTM. I think you can squash the commits since the history is not meaningful.
a0a0a67
to
90df459
Compare
No description provided.