diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-01-14 11:18:40 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-01-14 11:18:40 -0800 |
commit | 00914fca8b65d2437ff7464f7401d5606a99e9fd (patch) | |
tree | 0c3bca4ee26f6a46804fc23fcdd1e5a67c833abb /src | |
parent | d81355dc5ea39b9604852620953bc96384f643a7 (diff) | |
parent | 3ef487ecb6733bfe3c13d89780ebcfc81f9a5ea0 (diff) | |
download | scala-00914fca8b65d2437ff7464f7401d5606a99e9fd.tar.gz scala-00914fca8b65d2437ff7464f7401d5606a99e9fd.tar.bz2 scala-00914fca8b65d2437ff7464f7401d5606a99e9fd.zip |
Merge pull request #1882 from JamesIry/SI-5954_2.10.x
SI-5954 Adds implementation restriction preventing companions in package...
Diffstat (limited to 'src')
4 files changed, 30 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index cfc7f14210..517b91dca8 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -174,6 +174,7 @@ trait ScalaSettings extends AbsScalaSettings val etaExpandKeepsStar = BooleanSetting ("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.") val Yinvalidate = StringSetting ("-Yinvalidate", "classpath-entry", "Invalidate classpath entry before run", "") val noSelfCheck = BooleanSetting ("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.") + val companionsInPkgObjs = BooleanSetting("-Ycompanions-in-pkg-objs", "Allow companion objects and case classes in package objects. See issue SI-5954.") val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes") val exposeEmptyPackage = BooleanSetting("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly() diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 386eec207a..e3fd83f388 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1891,7 +1891,33 @@ trait Typers extends Modes with Adaptations with Tags { }) } val impl2 = finishMethodSynthesis(impl1, clazz, context) + + // SI-5954. On second compile of a companion class contained in a package object we end up + // with some confusion of names which leads to having two symbols with the same name in the + // same owner. Until that can be straightened out we can't allow companion objects in package + // objects. But this code also tries to be friendly by distinguishing between case classes and + // user written companion pairs + def restrictPackageObjectMembers(mdef : ModuleDef) = for (m <- mdef.symbol.info.members) { + // ignore synthetic objects, because the "companion" object to a case class is synthetic and + // we only want one error per case class + if (!m.isSynthetic) { + // can't handle case classes in package objects + if (m.isCaseClass) pkgObjectRestriction(m, mdef, "case") + // can't handle companion class/object pairs in package objects + else if ((m.isClass && m.companionModule != NoSymbol && !m.companionModule.isSynthetic) || + (m.isModule && m.companionClass != NoSymbol && !m.companionClass.isSynthetic)) + pkgObjectRestriction(m, mdef, "companion") + } + + def pkgObjectRestriction(m : Symbol, mdef : ModuleDef, restricted : String) = { + val pkgName = mdef.symbol.ownerChain find (_.isPackage) map (_.decodedName) getOrElse mdef.symbol.toString + context.error(if (m.pos.isDefined) m.pos else mdef.pos, s"implementation restriction: package object ${pkgName} cannot contain ${restricted} ${m}. Instead, ${m} should be placed directly in package ${pkgName}.") + } + } + if (!settings.companionsInPkgObjs.value && mdef.symbol.isPackageObject) + restrictPackageObjectMembers(mdef) + treeCopy.ModuleDef(mdef, typedMods, mdef.name, impl2) setType NoType } /** In order to override this in the TreeCheckers Typer so synthetics aren't re-added diff --git a/src/reflect/scala/reflect/internal/settings/MutableSettings.scala b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala index 81368df7a6..ec3501d5bc 100644 --- a/src/reflect/scala/reflect/internal/settings/MutableSettings.scala +++ b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala @@ -47,4 +47,6 @@ abstract class MutableSettings extends AbsSettings { def XoldPatmat: BooleanSetting def XnoPatmatAnalysis: BooleanSetting def XfullLubs: BooleanSetting + def companionsInPkgObjs: BooleanSetting + } diff --git a/src/reflect/scala/reflect/runtime/Settings.scala b/src/reflect/scala/reflect/runtime/Settings.scala index 0e0cf3fc40..2d5b76f094 100644 --- a/src/reflect/scala/reflect/runtime/Settings.scala +++ b/src/reflect/scala/reflect/runtime/Settings.scala @@ -43,6 +43,7 @@ private[reflect] class Settings extends MutableSettings { val printtypes = new BooleanSetting(false) val uniqid = new BooleanSetting(false) val verbose = new BooleanSetting(false) + val companionsInPkgObjs = new BooleanSetting(false) val Yrecursion = new IntSetting(0) val maxClassfileName = new IntSetting(255) |