diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-05-17 17:39:55 +0200 |
---|---|---|
committer | Felix Mulder <felix.mulder@gmail.com> | 2016-05-17 17:39:55 +0200 |
commit | d5147288df4cc05ac4d761bd0e451f724c474ae1 (patch) | |
tree | b2135b22adb44929fe8f4499665c0099432b9c0b /src/dotty/tools | |
parent | 3aa22cc24f601cb70dcff7247af95ad9fa403de5 (diff) | |
download | dotty-d5147288df4cc05ac4d761bd0e451f724c474ae1.tar.gz dotty-d5147288df4cc05ac4d761bd0e451f724c474ae1.tar.bz2 dotty-d5147288df4cc05ac4d761bd0e451f724c474ae1.zip |
Fix #1258: correct behavior for annotated values
Annotated values are encapsulated in a `ConcreteAnnotation`, as such,
the statement `tpe isRef defn.IntClass` would yield false despite the
annotated reference being an Int.
The tpe is now unwrapped if it has an annotation. If the transformation
fails despite having the annotation the compiler will warn.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/PatternMatcher.scala | 18 |
2 files changed, 15 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 7f59cbed0..e96636282 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -479,6 +479,8 @@ class Definitions { def TASTYLongSignatureAnnot(implicit ctx: Context) = TASTYLongSignatureAnnotType.symbol.asClass lazy val TailrecAnnotType = ctx.requiredClassRef("scala.annotation.tailrec") def TailrecAnnot(implicit ctx: Context) = TailrecAnnotType.symbol.asClass + lazy val SwitchAnnotType = ctx.requiredClassRef("scala.annotation.switch") + def SwitchAnnot(implicit ctx: Context) = SwitchAnnotType.symbol.asClass lazy val ThrowsAnnotType = ctx.requiredClassRef("scala.throws") def ThrowsAnnot(implicit ctx: Context) = ThrowsAnnotType.symbol.asClass lazy val TransientAnnotType = ctx.requiredClassRef("scala.transient") diff --git a/src/dotty/tools/dotc/transform/PatternMatcher.scala b/src/dotty/tools/dotc/transform/PatternMatcher.scala index 740fd5460..f8f32131b 100644 --- a/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -307,10 +307,15 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans // TODO Deal with guards? def isSwitchableType(tpe: Type): Boolean = { - (tpe isRef defn.IntClass) || - (tpe isRef defn.ByteClass) || - (tpe isRef defn.ShortClass) || - (tpe isRef defn.CharClass) + val actualTpe = tpe match { + case t @ AnnotatedType(inner, _) => inner + case x => x + } + + (actualTpe isRef defn.IntClass) || + (actualTpe isRef defn.ByteClass) || + (actualTpe isRef defn.ShortClass) || + (actualTpe isRef defn.CharClass) } object IntEqualityTestTreeMaker { @@ -423,7 +428,8 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans Match(intScrut, newCases :+ defaultCase) } - if (isSwitchableType(scrut.tpe.widenDealias) && cases.forall(isSwitchCase)) { + val dealiased = scrut.tpe.widenDealias + if (isSwitchableType(dealiased) && cases.forall(isSwitchCase)) { val valuesToCases = cases.map(extractSwitchCase) val values = valuesToCases.map(_._1) if (values.tails.exists { tail => tail.nonEmpty && tail.tail.exists(doOverlap(_, tail.head)) }) { @@ -433,6 +439,8 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans Some(makeSwitch(valuesToCases)) } } else { + if (dealiased hasAnnotation defn.SwitchAnnot) + ctx.warning("failed to emit switch for `@switch` annotated match") None } } |