-
Notifications
You must be signed in to change notification settings - Fork 3.1k
SI-9315 Desugar string concat to java.lang.StringBuilder ... #4737
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
|
Thanks a lot, @Blaisorblade, the pasto was the remaining issue! :-) |
|
I'm happy I was of help! |
|
That's all I had to say. Kudos, and good luck with the next reviewer! |
|
|
👍 |
|
review by @lrytz? |
|
sure. sorry i was a bit off the pr queue lately.. |
|
While we're looking at this part of the compiler, I'd like to consider making This would be a deviation from Java, but it would be handy for things like |
|
@retronym Not sure I understand this completely. Can you describe how the calls should look under the new scheme (vs. the old)? |
|
Mhhh, do you mean https://github.com/soc/scala/blob/SI-9315/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala#L223, where it always picks |
|
Mhhh, I guess we should do the same for arguments of type |
|
Yes. The parameter type corresponds to signature of the fake method |
|
This change of course would be a behavioural difference for ill-behaved |
I'd argue that, even for 2.12, the behavior should be equivalent for |
|
I think you could quite easily do it in the backend (not tested!): diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
index 535e1a8..99efb0d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
@@ -219,9 +219,11 @@ abstract class BCodeIdiomatic extends SubComponent {
*/
final def genStringConcat(el: BType, pos: Position): Unit = {
- val jtype =
- if (el.isArray || el.isClass) ObjectReference
- else el
+ val jtype = el match {
+ case c: ClassBType if c.isSubtypeOf(CharSequenceReference) => CharSequenceReference
+ case t if t.isArray || t.isClass => ObjectReference
+ case t => t
+ }
val bt = MethodBType(List(jtype), StringBuilderReference)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
index 00ca096..c0339de 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
@@ -108,6 +108,7 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) {
lazy val StringReference : ClassBType = classBTypeFromSymbol(StringClass)
lazy val StringBuilderReference : ClassBType = classBTypeFromSymbol(StringBuilderClass)
+ lazy val CharSequenceReference : ClassBType = classBTypeFromSymbol(requiredClass[CharSequence])
lazy val ThrowableReference : ClassBType = classBTypeFromSymbol(ThrowableClass)
lazy val jlCloneableReference : ClassBType = classBTypeFromSymbol(JavaCloneableClass) // java/lang/Cloneable
lazy val jlNPEReference : ClassBType = classBTypeFromSymbol(NullPointerExceptionClass) // java/lang/NullPointerException
@@ -254,6 +255,7 @@ final class CoreBTypesProxy[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes:
def StringReference : ClassBType = _coreBTypes.StringReference
def StringBuilderReference : ClassBType = _coreBTypes.StringBuilderReference
+ def CharSequenceReference : ClassBType = _coreBTypes.CharSequenceReference
def ThrowableReference : ClassBType = _coreBTypes.ThrowableReference
def jlCloneableReference : ClassBType = _coreBTypes.jlCloneableReference
def jlNPEReference : ClassBType = _coreBTypes.jlNPEReference |
|
I also added support for the |
|
Using the overload for |
|
It would be great to add a test for the overloading change. The easiest would be a unit test in |
|
@lrytz Agree, that was my reasoning for leaving out |
|
Is there anything needed to make junit pick the new tests up? I wrote a test class, added all the annotations, but the class is never tested. |
|
it should happen by itself - maybe you missed some annotation? feel free to post the diff. btw, i very much recommend to write and run tests in intellij. |
|
@lrytz Ooops, sorry, forgot to push! Here are the tests: https://github.com/soc/scala/commit/2e05ec4bd81b0dbbf8664cb079128e2bc618e94c#diff-7506aaabf8fa132381745c90a77c1606R23 JUnit doesn't seem to pick up the class: |
|
no idea why it's not picked up.. i can run the test in intellij. |
|
@soc the answer is here: https://github.com/scala/scala/blob/2.11.x/build.xml#L1562. You need to name the class |
|
@lrytz Arrrgh, thanks a lot! :-) |
|
Ok, this is weird: I don't think it is intentional that we box the primitives and use |
|
That's why it's so great that finally somebody is writing tests for this thing :-) Boxing is added in erasure. It must be because there's only a single |
|
here's a starting point: lrytz@e90fb97 |
|
@soc this needs a rebase. Once the TODOs in #4737 (comment) are addressed I think we can get this in! |
|
@soc do you have time to push this one forward? it would be a nice addition to 2.12.0-M4 (probably mid-february). |
|
@lrytz Rebased, addressed comments, added test. |
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.
StringBuilderRef seems to be not used
... instead of scala.collection.mutable.StringBuilder to benefit from JVM optimizations. Unfortunately primitives are already boxed in erasure when they end up in this part of the backend.
|
@lrytz Done! |
|
LGTM, thanks for another iteration! |
SI-9315 Desugar string concat to java.lang.StringBuilder ...
... instead of scala.collection.mutable.StringBuilder to benefit from
JVM optimizations.