diff options
author | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2014-09-24 00:20:40 +0200 |
---|---|---|
committer | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2014-09-24 00:20:40 +0200 |
commit | a908ded364a6f8b664c6b02552a909c143d21b19 (patch) | |
tree | 1ca43c96e57a7420b08029d873e477cc80e5fe67 | |
parent | 9ecfac84be3368acfd882d517c8138481b5568ec (diff) | |
parent | 0022dccfde2f2d1e383254d8b5677c2468b57701 (diff) | |
download | scala-a908ded364a6f8b664c6b02552a909c143d21b19.tar.gz scala-a908ded364a6f8b664c6b02552a909c143d21b19.tar.bz2 scala-a908ded364a6f8b664c6b02552a909c143d21b19.zip |
Merge pull request #3998 from retronym/backport/7756
[backport] SI-7756 Uncripple refchecks in case bodies
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 35 | ||||
-rw-r--r-- | test/files/neg/t7756a.check | 7 | ||||
-rw-r--r-- | test/files/neg/t7756a.flags | 1 | ||||
-rw-r--r-- | test/files/neg/t7756a.scala | 11 | ||||
-rw-r--r-- | test/files/neg/t7756b.check | 4 | ||||
-rw-r--r-- | test/files/neg/t7756b.flags | 1 | ||||
-rw-r--r-- | test/files/neg/t7756b.scala | 5 | ||||
-rw-r--r-- | test/files/pos/t7756b.scala | 13 |
8 files changed, 69 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index fea234dd14..1d5a37eb38 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -98,6 +98,11 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans var localTyper: analyzer.Typer = typer; var currentApplication: Tree = EmptyTree var inPattern: Boolean = false + @inline final def savingInPattern[A](body: => A): A = { + val saved = inPattern + try body finally inPattern = saved + } + var checkedCombinations = Set[List[Type]]() // only one overloaded alternative is allowed to define default arguments @@ -1822,19 +1827,33 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans case _ => tree } + // skip refchecks in patterns.... result = result match { case CaseDef(pat, guard, body) => - inPattern = true - val pat1 = transform(pat) - inPattern = false + val pat1 = savingInPattern { + inPattern = true + transform(pat) + } treeCopy.CaseDef(tree, pat1, transform(guard), transform(body)) case LabelDef(_, _, _) if treeInfo.hasSynthCaseSymbol(result) => - val old = inPattern - inPattern = true - val res = deriveLabelDef(result)(transform) // TODO SI-7756 Too broad! The code from the original case body should be fully refchecked! - inPattern = old - res + savingInPattern { + inPattern = true + deriveLabelDef(result)(transform) + } + case Apply(fun, args) if fun.symbol.isLabel && treeInfo.isSynthCaseSymbol(fun.symbol) => + savingInPattern { + // SI-7756 If we were in a translated pattern, we can now switch out of pattern mode, as the label apply signals + // that we are in the user-supplied code in the case body. + // + // Relies on the translation of: + // (null: Any) match { case x: List[_] => x; x.reverse; case _ => }' + // to: + // <synthetic> val x2: List[_] = (x1.asInstanceOf[List[_]]: List[_]); + // matchEnd4({ x2; x2.reverse}) // case body is an argument to a label apply. + if (settings.future.value) inPattern = false // By default, bug compatibility with 2.10.[0-4] + super.transform(result) + } case ValDef(_, _, _, _) if treeInfo.hasSynthCaseSymbol(result) => deriveValDef(result)(transform) // SI-7716 Don't refcheck the tpt of the synthetic val that holds the selector. case _ => diff --git a/test/files/neg/t7756a.check b/test/files/neg/t7756a.check new file mode 100644 index 0000000000..8d42717e47 --- /dev/null +++ b/test/files/neg/t7756a.check @@ -0,0 +1,7 @@ +t7756a.scala:7: error: type arguments [Object] do not conform to trait TA's type parameter bounds [X <: CharSequence] + locally(null: TA[Object]) + ^ +t7756a.scala:7: error: type arguments [Object] do not conform to trait TA's type parameter bounds [X <: CharSequence] + locally(null: TA[Object]) + ^ +two errors found diff --git a/test/files/neg/t7756a.flags b/test/files/neg/t7756a.flags new file mode 100644 index 0000000000..29f4ede37a --- /dev/null +++ b/test/files/neg/t7756a.flags @@ -0,0 +1 @@ +-Xfuture diff --git a/test/files/neg/t7756a.scala b/test/files/neg/t7756a.scala new file mode 100644 index 0000000000..4453e84963 --- /dev/null +++ b/test/files/neg/t7756a.scala @@ -0,0 +1,11 @@ +object Test { + def test: Unit = { + trait TA[X <: CharSequence] + 0 match { + case _ => + // the bounds violation isn't reported. RefChecks seems to be too broadly disabled under virtpatmat: see 65340ed4ad2e + locally(null: TA[Object]) + () + } + } +} diff --git a/test/files/neg/t7756b.check b/test/files/neg/t7756b.check new file mode 100644 index 0000000000..5a88ae3c25 --- /dev/null +++ b/test/files/neg/t7756b.check @@ -0,0 +1,4 @@ +t7756b.scala:3: error: comparing values of types Int and String using `==' will always yield false + case _ => 0 == "" + ^ +one error found diff --git a/test/files/neg/t7756b.flags b/test/files/neg/t7756b.flags new file mode 100644 index 0000000000..3f3381a45b --- /dev/null +++ b/test/files/neg/t7756b.flags @@ -0,0 +1 @@ +-Xfuture -Xfatal-warnings diff --git a/test/files/neg/t7756b.scala b/test/files/neg/t7756b.scala new file mode 100644 index 0000000000..a2de29c8e7 --- /dev/null +++ b/test/files/neg/t7756b.scala @@ -0,0 +1,5 @@ +object Test { + 0 match { + case _ => 0 == "" + } +} diff --git a/test/files/pos/t7756b.scala b/test/files/pos/t7756b.scala new file mode 100644 index 0000000000..009248510d --- /dev/null +++ b/test/files/pos/t7756b.scala @@ -0,0 +1,13 @@ +// This is a pos test to show that the backported bug fix for SI-7756 is +// only enabled under -Xfuture. +object Test { + def test: Unit = { + trait TA[X <: CharSequence] + 0 match { + case _ => + // the bounds violation isn't reported. RefChecks seems to be too broadly disabled under virtpatmat: see 65340ed4ad2e + locally(null: TA[Object]) + () + } + } +} |