Skip to content

#1589: Add error message for not emitting switch. #3556

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

vitorsvieira
Copy link
Contributor

@vitorsvieira vitorsvieira commented Nov 26, 2017

Regarding #1589, this PR addresses "could not emit switch" (PatternMatcher.911).

Noticed that ctx.warning was not propagating the error messages during tests.

@smarter Suggested to refactor checkMessagesAfter in a way that errors and warning messages are reported.

Would it be something like below?

  def checkMessagesAfter(checkAfterPhase: String)(source: String): Report = {
    ctx = newContext
    val runCtx = checkCompile(checkAfterPhase, source) { (_, _) => () }

    if (!runCtx.reporter.hasErrors && !runCtx.reporter.hasWarnings) new EmptyReport  
    else {
      val rep = runCtx.reporter.asInstanceOf[StoreReporter]
      val msgs = rep.removeBufferedMessages(runCtx).map(_.contained()).reverse
      new Report(msgs, runCtx)
    }
  }

I'd be more than happy to contribute!

Copy link
Member

@dottybot dottybot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, and thank you for opening this PR! 🎉

All contributors have signed the CLA, thank you! ❤️

Have an awesome day! ☀️

@vitorsvieira vitorsvieira changed the title #1589: Add error message for not emitting @switch. #1589: Add error message for not emitting switch. Nov 26, 2017
|val number = (middle: @switch) match {
| case 'a' => 1
| case 'm' => 13
| case last => 26 //a non-literal may prevent switch generation: this would not compile.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case _ is unreachable. You might want to either replace

case last => ...

with

case `last` => ...

or rename last to Last

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

case class UnableToEmitSwitch()(implicit ctx: Context)
extends Message(UnableToEmitSwitchID) {
val kind = "Syntax"
val msg = hl"""Could not emit switch for ${"@switch"} annotated match"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for triple quotes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

| case 'm' => 13
| case Last => 26 //a non-literal may prevent switch generation: this would not compile.
| case _ => 0
|}""".stripMargin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A more complete example:

val ConstantB = 'B'
final val ConstantC = 'C'
def tokenMe(ch: Char) = (ch: @switch) match {
  case '\t' | '\n' => 1
  case 'A'         => 2
  case ConstantB   => 3  // a non-literal may prevent switch generation: this would not compile
  case ConstantC   => 4  // a constant value is allowed
  case _           => 5
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Updated.

|-The matched value is a known integer or types implicitly convertible to integer.
|-The matched expression only matches literal values, without type checks, if statements, or extractors.
|-The expression have its value available at compile time.
|-There are more than two case statements."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If annotated with ${"@switch"}, the compiler will verify that the match has been compiled to a
tableswitch or lookupswitch and issue an error if it instead compiles into a series of conditional
expressions. Example usage:

$codeExample

The compiler will not apply the optimisation if:
- the matched value is not of type ${"Int"}, ${"Byte"}, ${"Short"} or ${"Char"}
- the matched value is not a constant literal
- there are less than three cases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Nov 27, 2017

Please change the commit message to Ref #1589: Add error message for not emitting switch

Copy link
Contributor

@allanrenucci allanrenucci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks @vitorsvieira!

@allanrenucci allanrenucci merged commit 780183d into scala:master Nov 27, 2017
@vitorsvieira
Copy link
Contributor Author

Cool! 👍

@vitorsvieira vitorsvieira deleted the wip/1589-patternmatcher-unable-to-emit-switch branch November 27, 2017 10:56
nerush pushed a commit to nerush/dotty that referenced this pull request Nov 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants