summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-07-25 10:21:26 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-07-25 10:28:32 +1000
commita2cba53e18864a5b9092f1e329c6e0afb09566c5 (patch)
treeabb8bdde67d24f3106fbde27e43d2420e8eee671 /src/compiler
parent6b99dfe746cbb76828db495b58e55db2a0265ee2 (diff)
downloadscala-a2cba53e18864a5b9092f1e329c6e0afb09566c5.tar.gz
scala-a2cba53e18864a5b9092f1e329c6e0afb09566c5.tar.bz2
scala-a2cba53e18864a5b9092f1e329c6e0afb09566c5.zip
SD-167 Fine tuning constructor pattern translation
- Avoid calling NoSymbol.owner when checking whether we're dealing with a case class constructor pattern or a general extractor. Tested manually with the test case in the ticket, no more output is produced under `-Xdev`. - Be more conservative about the conversion to a case class pattern: rather than looking just at the type of the pattern tree, also look at the tree itself to ensure its safe to elide. This change is analagous to SI-4859, which restricted rewrites of case apply calls to case constructors. I've manually tested that case class patterns are still efficiently translated: ``` object Test { def main(args: Array[String]) { Some(1) match { case Some(x) => } } } ``` ``` % qscalac -Xprint:patmat sandbox/test.scala [[syntax trees at end of patmat]] // test.scala package <empty> { object Test extends scala.AnyRef { def <init>(): Test.type = { Test.super.<init>(); () }; def main(args: Array[String]): Unit = { case <synthetic> val x1: Some[Int] = scala.Some.apply[Int](1); case4(){ if (x1.ne(null)) matchEnd3(()) else case5() }; case5(){ matchEnd3(throw new MatchError(x1)) }; matchEnd3(x: Unit){ x } } } } ```
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala3
2 files changed, 3 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index ad9377f8b4..caad4a907b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1764,7 +1764,7 @@ trait Namers extends MethodSynthesis {
* bugs waiting to be reported? If not, why not? When exactly do we need to
* call this method?
*/
- def companionSymbolOf(original: Symbol, ctx: Context): Symbol = {
+ def companionSymbolOf(original: Symbol, ctx: Context): Symbol = if (original == NoSymbol) NoSymbol else {
val owner = original.owner
// SI-7264 Force the info of owners from previous compilation runs.
// Doing this generally would trigger cycles; that's what we also
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
index f90e61ff92..1df3449ce6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
@@ -79,6 +79,7 @@ trait PatternTypers {
// do not update the symbol if the tree's symbol's type does not define an unapply member
// (e.g. since it's some method that returns an object with an unapply member)
val fun = inPlaceAdHocOverloadingResolution(fun0)(hasUnapplyMember)
+ val canElide = treeInfo.isQualifierSafeToElide(fun)
val caseClass = companionSymbolOf(fun.tpe.typeSymbol.sourceModule, context)
val member = unapplyMember(fun.tpe)
def resultType = (fun.tpe memberType member).finalResultType
@@ -94,7 +95,7 @@ trait PatternTypers {
// Dueling test cases: pos/overloaded-unapply.scala, run/case-class-23.scala, pos/t5022.scala
// A case class with 23+ params has no unapply method.
// A case class constructor may be overloaded with unapply methods in the companion.
- if (caseClass.isCase && !member.isOverloaded)
+ if (canElide && caseClass.isCase && !member.isOverloaded)
logResult(s"convertToCaseConstructor($fun, $caseClass, pt=$pt)")(convertToCaseConstructor(fun, caseClass, pt))
else if (!reallyExists(member))
CaseClassConstructorError(fun, s"${fun.symbol} is not a case class, nor does it have an unapply/unapplySeq member")