Skip to content
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

Matching strings should emit switches (as in Scala 2) #11923

Closed
harpocrates opened this issue Mar 28, 2021 · 4 comments · Fixed by #11937
Closed

Matching strings should emit switches (as in Scala 2) #11923

harpocrates opened this issue Mar 28, 2021 · 4 comments · Fixed by #11937
Assignees
Milestone

Comments

@harpocrates
Copy link
Contributor

This was initially reported in scala/bug#11740, then fixed in scala/scala#8451, but never ported to Dotty (perhaps because the changes collide a little without the new pattern matching).

I would expect the following to compile into a lookupswitch based on the hashCode of the cases, as it does in Scala 2 (and as Java, Kotlin, etc. also do).

def testMatch(s: String): Int = (s: @switch) match {
  case "S0" => 123
  case "S1" => 121
  case "S2" => 193
  case "S3" => 223
  case "S4" => 423
  case "S5" => 153
  case "S6" => 143
  case "S7" => 133
}

To further confuse the story, this comment from the JS codgen appears to suggest that at some point the Scala.js backend would've received and emitted a switch over strings (although I can't reproduce that behavior, even on Scala 2 and with @switch supposedly claiming a switch will be emitted).

@harpocrates
Copy link
Contributor Author

I'm going to take a stab at this, but I'm opening an issue anyways in case I run out of steam (since this really should be addressed).

@nicolasstucki
Copy link
Contributor

@sjrd should we keep those matched as Match trees in the PatternMatcher and then compile them to bytecode in the backend directly. Or, should we transform the match into a match on the hashCode in PatternMatcher and keep the switches on Int for the backend. What is simpler for Scala.js? I would assume the second option.

@sjrd
Copy link
Member

sjrd commented Mar 29, 2021

We should do as Scala 2 does, i.e., keep those as Match trees in the PatternMatcher, and then compile them to bytecode in the backend directly. Scala.js has its own way of compiling those, which does not use the hashCode.

@bishabosha
Copy link
Member

I started with ef06795 but never got to refining it

@bishabosha bishabosha removed their assignment Mar 30, 2021
harpocrates added a commit to harpocrates/dotty that referenced this issue Aug 18, 2021
The pattern matcher will now emit `Match` with `String` scrutinee as
well as the existing `Int` scrutinee. The JVM backend handles this case
by emitting bytecode that switches on the String's `hashCode` (this
matches what Java does). The SJS already handles `String` matches.

The approach is similar to scala/scala#8451 (see scala/bug#11740 too),
except that instead of doing a transformation on the AST, we just emit the
right bytecode straight away. This is desirable since it means that
Scala.js (and any other backend) can choose their own optimised strategy
for compiling a match on strings.

Fixes scala#11923
olsdavis pushed a commit to olsdavis/dotty that referenced this issue Apr 4, 2022
The pattern matcher will now emit `Match` with `String` scrutinee as
well as the existing `Int` scrutinee. The JVM backend handles this case
by emitting bytecode that switches on the String's `hashCode` (this
matches what Java does). The SJS already handles `String` matches.

The approach is similar to scala/scala#8451 (see scala/bug#11740 too),
except that instead of doing a transformation on the AST, we just emit the
right bytecode straight away. This is desirable since it means that
Scala.js (and any other backend) can choose their own optimised strategy
for compiling a match on strings.

Fixes scala#11923
@Kordyjan Kordyjan added this to the 3.1.0 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants