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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public enum ErrorMessageID {
StaticFieldsOnlyAllowedInObjectsID,
CyclicInheritanceID,
UnableToExtendSealedClassID,
UnableToEmitSwitchID,
;

public int errorNumber() {
Expand Down
29 changes: 29 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1972,4 +1972,33 @@ object messages {
val msg = hl"Cannot extend ${"sealed"} $pclazz in a different source file"
val explanation = "A sealed class or trait can only be extended in the same file as its declaration"
}

case class UnableToEmitSwitch()(implicit ctx: Context)
extends Message(UnableToEmitSwitchID) {
val kind = "Syntax"
val msg = hl"Could not emit switch for ${"@switch"} annotated match"
val explanation = {
val codeExample =
"""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
|}""".stripMargin

hl"""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"""
}
}
}
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Decorators._
import patmat.Space
import NameKinds.{UniqueNameKind, PatMatStdBinderName, PatMatCaseName}
import config.Printers.patmatch
import reporting.diagnostic.messages._

/** The pattern matching transform.
* After this phase, the only Match nodes remaining in the code are simple switches
Expand Down Expand Up @@ -908,7 +909,7 @@ object PatternMatcher {
tpes.toSet.size: Int // without the type ascription, testPickling fails because of #2840.
}
if (numConsts(resultCases) < numConsts(original.cases))
ctx.warning(i"could not emit switch for @switch annotated match", original.pos)
ctx.warning(UnableToEmitSwitch(), original.pos)
case _ =>
}

Expand Down