summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala18
-rw-r--r--test/files/run/t9567c.scala29
2 files changed, 44 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
index 451b72d498..a2afb76b0e 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
@@ -504,14 +504,26 @@ trait MatchTranslation {
*/
def treeMaker(binder: Symbol, binderKnownNonNull: Boolean, pos: Position): TreeMaker = {
val paramAccessors = binder.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)
// make an exception for classes under the scala package as they should be well-behaved,
// to optimize matching on List
+ val hasRepeated = paramAccessors.lastOption match {
+ case Some(x) => definitions.isRepeated(x)
+ case _ => false
+ }
val mutableBinders = (
if (!binder.info.typeSymbol.hasTransOwner(ScalaPackageClass) &&
- (paramAccessors exists (_.isMutable)))
- subPatBinders.zipWithIndex.collect{ case (binder, idx) if paramAccessors(idx).isMutable => binder }
- else Nil
+ (paramAccessors exists (x => x.isMutable || definitions.isRepeated(x)))) {
+
+ subPatBinders.zipWithIndex.flatMap {
+ case (binder, idx) =>
+ val param = paramAccessorAt(idx)
+ if (param.isMutable || (definitions.isRepeated(param) && !aligner.isStar)) binder :: Nil
+ else Nil
+ }
+ } else Nil
)
// checks binder ne null before chaining to the next extractor
diff --git a/test/files/run/t9567c.scala b/test/files/run/t9567c.scala
new file mode 100644
index 0000000000..560bea8821
--- /dev/null
+++ b/test/files/run/t9567c.scala
@@ -0,0 +1,29 @@
+case class CaseSequenceTopLevel(as: Int*)
+
+object Test {
+ def main(args: Array[String]): Unit = {
+
+ val buffer1 = collection.mutable.Buffer(0, 0)
+ CaseSequenceTopLevel(buffer1: _*) match {
+ case CaseSequenceTopLevel(_, i) =>
+ buffer1(1) = 1
+ assert(i == 0, i) // fails in 2.11.7 -optimize
+ }
+
+ case class CaseSequence(as: Int*)
+ val buffer2 = collection.mutable.Buffer(0, 0)
+ CaseSequence(buffer2: _*) match {
+ case CaseSequence(_, i) =>
+ buffer2(1) = 1
+ assert(i == 0, i)
+ }
+
+ case class CaseSequenceWithVar(var x: Any, as: Int*)
+ val buffer3 = collection.mutable.Buffer(0, 0)
+ CaseSequenceWithVar("", buffer3: _*) match {
+ case CaseSequenceWithVar(_, _, i) => // crashes in 2.11.7
+ buffer2(1) = 1
+ assert(i == 0, i)
+ }
+ }
+}