diff options
author | Adriaan Moors <adriaan@lightbend.com> | 2016-07-18 14:35:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-18 14:35:27 -0700 |
commit | 52fb8e88aa4ac5f1c165065e08c6bbe4d49eb4a9 (patch) | |
tree | 5fe720b23a526779c8dcb11bc105c4d5ffadee0a | |
parent | c901ad6c66ddcaafdd7600027afc330595bcecbb (diff) | |
parent | d386e802d53ab616a8a6005c89a9be30ab5526d8 (diff) | |
download | scala-52fb8e88aa4ac5f1c165065e08c6bbe4d49eb4a9.tar.gz scala-52fb8e88aa4ac5f1c165065e08c6bbe4d49eb4a9.tar.bz2 scala-52fb8e88aa4ac5f1c165065e08c6bbe4d49eb4a9.zip |
Merge pull request #5273 from retronym/ticket/9855
SI-9855 Fix regression in extractor pattern translation
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala | 17 | ||||
-rw-r--r-- | test/files/pos/t9855.scala | 10 | ||||
-rw-r--r-- | test/files/pos/t9855b.scala | 16 | ||||
-rw-r--r-- | test/files/run/t6288.check | 6 |
4 files changed, 32 insertions, 17 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala index e12b8548a8..5750f8f7e7 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala @@ -125,7 +125,7 @@ trait MatchTranslation { // TODO: paramType may contain unbound type params (run/t2800, run/t3530) val makers = ( // Statically conforms to paramType - if (this ensureConformsTo paramType) treeMaker(binder, false, pos) :: Nil + if (tpe <:< paramType) treeMaker(binder, false, pos) :: Nil else typeTest :: extraction :: Nil ) step(makers: _*)(extractor.subBoundTrees: _*) @@ -162,16 +162,6 @@ trait MatchTranslation { setVarInfo(binder, paramType) true } - // If <:< but not =:=, no type test needed, but the tree maker relies on the binder having - // exactly paramType (and not just some type compatible with it.) SI-6624 shows this is necessary - // because apparently patBinder may have an unfortunate type (.decls don't have the case field - // accessors) TODO: get to the bottom of this -- I assume it happens when type checking - // infers a weird type for an unapply call. By going back to the parameterType for the - // extractor call we get a saner type, so let's just do that for now. - def ensureConformsTo(paramType: Type): Boolean = ( - (tpe =:= paramType) - || (tpe <:< paramType) && setInfo(paramType) - ) private def concreteType = tpe.bounds.hi private def unbound = unbind(tree) @@ -396,7 +386,6 @@ trait MatchTranslation { /** Create the TreeMaker that embodies this extractor call * - * `binder` has been casted to `paramType` if necessary * `binderKnownNonNull` indicates whether the cast implies `binder` cannot be null * when `binderKnownNonNull` is `true`, `ProductExtractorTreeMaker` does not do a (redundant) null check on binder */ @@ -502,7 +491,7 @@ trait MatchTranslation { * when `binderKnownNonNull` is `true`, `ProductExtractorTreeMaker` does not do a (redundant) null check on binder */ def treeMaker(binder: Symbol, binderKnownNonNull: Boolean, pos: Position): TreeMaker = { - val paramAccessors = binder.constrParamAccessors + val paramAccessors = aligner.wholeType.typeSymbol.constrParamAccessors val numParams = paramAccessors.length def paramAccessorAt(subPatIndex: Int) = paramAccessors(math.min(subPatIndex, numParams - 1)) // binders corresponding to mutable fields should be stored (SI-5158, SI-6070) @@ -531,7 +520,7 @@ trait MatchTranslation { // reference the (i-1)th case accessor if it exists, otherwise the (i-1)th tuple component override protected def tupleSel(binder: Symbol)(i: Int): Tree = { - val accessors = binder.caseFieldAccessors + val accessors = aligner.wholeType.typeSymbol.caseFieldAccessors if (accessors isDefinedAt (i-1)) gen.mkAttributedStableRef(binder) DOT accessors(i-1) else codegen.tupleSel(binder)(i) // this won't type check for case classes, as they do not inherit ProductN } diff --git a/test/files/pos/t9855.scala b/test/files/pos/t9855.scala new file mode 100644 index 0000000000..b6ac3e2432 --- /dev/null +++ b/test/files/pos/t9855.scala @@ -0,0 +1,10 @@ +class C { + def xx(verb: String, a: Array[Int]) { + val reYYYY = """(\d\d\d\d)""".r + verb match { + case "time" if a.isEmpty => + case "time" => + case reYYYY(y) => + } + } +} diff --git a/test/files/pos/t9855b.scala b/test/files/pos/t9855b.scala new file mode 100644 index 0000000000..30c58be3dc --- /dev/null +++ b/test/files/pos/t9855b.scala @@ -0,0 +1,16 @@ +object Test { + var FALSE = false + def main(args: Array[String]): Unit = { + val SomeB = new B + new B() match { + case SomeB if FALSE => + case SomeB => + case Ext(_) => + } + } +} +object Ext { + def unapply(s: A) = Some(()) +} +class A +class B extends A diff --git a/test/files/run/t6288.check b/test/files/run/t6288.check index 67877fd56d..7933f516a8 100644 --- a/test/files/run/t6288.check +++ b/test/files/run/t6288.check @@ -7,7 +7,7 @@ }; [21]def unapply([29]z: [32]<type: [32]scala.Any>): [21]Option[Int] = [56][52][52]scala.Some.apply[[52]Int]([58]-1); [64]{ - [64]case <synthetic> val x1: [64]Any = [64]""; + [64]case <synthetic> val x1: [64]String = [64]""; [64]case5()[84]{ [84]<synthetic> val o7: [84]Option[Int] = [84][84]Case3.unapply([84]x1); [84]if ([84]o7.isEmpty.unary_!) @@ -30,7 +30,7 @@ }; [127]def unapplySeq([138]z: [141]<type: [141]scala.Any>): [127]Option[List[Int]] = [167]scala.None; [175]{ - [175]case <synthetic> val x1: [175]Any = [175]""; + [175]case <synthetic> val x1: [175]String = [175]""; [175]case5()[195]{ [195]<synthetic> val o7: [195]Option[List[Int]] = [195][195]Case4.unapplySeq([195]x1); [195]if ([195][195]o7.isEmpty.unary_!.&&([195][195][195][195]o7.get.!=([195]null).&&([195][195][195][195]o7.get.lengthCompare([195]1).==([195]0)))) @@ -53,7 +53,7 @@ }; [238]def unapply([246]z: [249]<type: [249]scala.Any>): [238]Boolean = [265]true; [273]{ - [273]case <synthetic> val x1: [273]Any = [273]""; + [273]case <synthetic> val x1: [273]String = [273]""; [273]case5()[293]{ [293]<synthetic> val o7: [293]Option[List[Int]] = [293][293]Case4.unapplySeq([293]x1); [293]if ([293][293]o7.isEmpty.unary_!.&&([293][293][293][293]o7.get.!=([293]null).&&([293][293][293][293]o7.get.lengthCompare([293]0).==([293]0)))) |