From 61f29368fecf620585c8bb26bb83c746cbbe6571 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 5 Dec 2012 10:18:53 +0100 Subject: SI-4859 Don't rewrite CC().CC2() to new CC2 Where CC and CC2 are case classes. Attempting to do so leads to a "no legal prefix" error. Now, we restrict this optimization (living in RefChecks ?!) to case class applies with a "safe to inline" qualifier. --- .../scala/tools/nsc/typechecker/RefChecks.scala | 9 ++++++--- test/files/pos/t4859.scala | 17 +++++++++++++++++ test/pending/pos/t4859.scala | 15 --------------- 3 files changed, 23 insertions(+), 18 deletions(-) create mode 100644 test/files/pos/t4859.scala delete mode 100644 test/pending/pos/t4859.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index e88447c46d..f0ced1a8d4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1389,9 +1389,12 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans case TypeApply(fun, targs) => isClassTypeAccessible(fun) case Select(module, apply) => - // Fixes SI-5626. Classes in refinement types cannot be constructed with `new`. In this case, - // the companion class is actually not a ClassSymbol, but a reference to an abstract type. - module.symbol.companionClass.isClass + ( // SI-4859 `CaseClass1().InnerCaseClass2()` must not be rewritten to `new InnerCaseClass2()` + treeInfo.isExprSafeToInline(module) && + // SI-5626 Classes in refinement types cannot be constructed with `new`. In this case, + // the companion class is actually not a ClassSymbol, but a reference to an abstract type. + module.symbol.companionClass.isClass + ) } val doTransform = diff --git a/test/files/pos/t4859.scala b/test/files/pos/t4859.scala new file mode 100644 index 0000000000..284a39b7ab --- /dev/null +++ b/test/files/pos/t4859.scala @@ -0,0 +1,17 @@ +object O { + // error: C is not a legal prefix for a constructor + C().CC() + // but this works. + D().DD() +} + +case class C() { + case class CC() +} + +case class D() { + class DD() + object DD { + def apply() = new DD() + } +} diff --git a/test/pending/pos/t4859.scala b/test/pending/pos/t4859.scala deleted file mode 100644 index ec5abd966d..0000000000 --- a/test/pending/pos/t4859.scala +++ /dev/null @@ -1,15 +0,0 @@ -object O { - C().CC() - D().DD() -} - -case class C() { - case class CC() -} - -case class D() { - class DD() - object DD { - def apply() = new DD() - } -} -- cgit v1.2.3