summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan@lightbend.com>2016-07-18 14:35:27 -0700
committerGitHub <noreply@github.com>2016-07-18 14:35:27 -0700
commit52fb8e88aa4ac5f1c165065e08c6bbe4d49eb4a9 (patch)
tree5fe720b23a526779c8dcb11bc105c4d5ffadee0a
parentc901ad6c66ddcaafdd7600027afc330595bcecbb (diff)
parentd386e802d53ab616a8a6005c89a9be30ab5526d8 (diff)
downloadscala-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.scala17
-rw-r--r--test/files/pos/t9855.scala10
-rw-r--r--test/files/pos/t9855b.scala16
-rw-r--r--test/files/run/t6288.check6
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))))