summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-03-03 22:30:39 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-03-04 13:26:05 +1000
commitf08282946647ec4049af965024b4638a4a55f5fd (patch)
tree9f34715e57f643184cf987fbb871f92eee66f391
parentfe5bd09861994734bc394813d069ea40c89d39de (diff)
downloadscala-f08282946647ec4049af965024b4638a4a55f5fd.tar.gz
scala-f08282946647ec4049af965024b4638a4a55f5fd.tar.bz2
scala-f08282946647ec4049af965024b4638a4a55f5fd.zip
SI-9425 Fix a residual bug with multi-param-list case classes
During code review for the fix for SI-9546, we found a corner case in the SI-9425 that remained broken. Using `finalResultType` peels off all the constructor param lists, and solves that problem.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala13
-rw-r--r--test/files/run/t9546e.scala15
2 files changed, 25 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 517271e5eb..3b2e07bdbd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1522,7 +1522,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
sym.isCase &&
sym.name == nme.apply &&
isClassTypeAccessible(tree) &&
- !tree.tpe.resultType.typeSymbol.primaryConstructor.isLessAccessibleThan(tree.symbol)
+ !tree.tpe.finalResultType.typeSymbol.primaryConstructor.isLessAccessibleThan(tree.symbol)
}
private def transformCaseApply(tree: Tree) = {
@@ -1571,8 +1571,15 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
// term should have been eliminated by super accessors
assert(!(qual.symbol.isTrait && sym.isTerm && mix == tpnme.EMPTY), (qual.symbol, sym, mix))
- // SI-9546 isHigherKinded excludes generic case classes which are instead considered when transforming
- // the enclosing `TypeApply`.
+ // Rewrite eligible calls to monomorphic case companion apply methods to the equivalent constructor call.
+ //
+ // Note: for generic case classes the rewrite needs to be handled at the enclosing `TypeApply` to transform
+ // `TypeApply(Select(C, apply), targs)` to `Select(New(C[targs]), <init>)`. In case such a `TypeApply`
+ // was deemed ineligible for transformation (e.g. the case constructor was private), the refchecks transform
+ // will recurse to this point with `Select(C, apply)`, which will have a type `[T](...)C[T]`.
+ //
+ // We don't need to perform the check on the Select node, and `!isHigherKinded will guard against this
+ // redundant (and previously buggy, SI-9546) consideration.
if (!tree.tpe.isHigherKinded && isSimpleCaseApply(tree)) {
transformCaseApply(tree)
} else {
diff --git a/test/files/run/t9546e.scala b/test/files/run/t9546e.scala
new file mode 100644
index 0000000000..b19d0871aa
--- /dev/null
+++ b/test/files/run/t9546e.scala
@@ -0,0 +1,15 @@
+case class A private (x: Int)
+case class B private (x: Int)(y: Int)
+
+class C {
+ def f = A(1)
+ def g = B(1)(2) // was: constructor B in class B cannot be accessed in class C
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ new C().f
+ new C().g
+ }
+
+}