summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--test/files/run/valueclasses-constr.scala84
5 files changed, 77 insertions, 20 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 2ba45c5972..f4039cf6d3 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -1872,7 +1872,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def unpackLocation: AnyRef = null
/** Remove private modifier from symbol `sym`s definition. If `sym` is a
- * term symbol rename it by expanding its name to avoid name clashes
+ * is not a constructor nor a static module rename it by expanding its name to avoid name clashes
+ * @param base the fully qualified name of this class will be appended if name expansion is needed
*/
final def makeNotPrivate(base: Symbol) {
if (this.isPrivate) {
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 4c3972519a..5104518dd9 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -28,6 +28,9 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
/** the following two members override abstract members in Transform */
val phaseName: String = "extmethods"
+ /** The following flags may be set by this phase: */
+ override def phaseNewFlags: Long = notPRIVATE
+
def newTransformer(unit: CompilationUnit): Transformer =
new Extender(unit)
@@ -101,6 +104,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
case Template(_, _, _) =>
if (currentOwner.isDerivedValueClass) {
extensionDefs(currentOwner.companionModule) = new mutable.ListBuffer[Tree]
+ currentOwner.primaryConstructor.makeNotPrivate(NoSymbol)
super.transform(tree)
} else if (currentOwner.isStaticOwner) {
super.transform(tree)
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index ed263cbbef..105c2c0b98 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -263,8 +263,8 @@ abstract class TreeCheckers extends Analyzer {
tree match {
case x: PackageDef =>
- if (sym.ownerChain contains currentOwner) ()
- else fail(sym + " owner chain does not contain currentOwner " + currentOwner)
+ if ((sym.ownerChain contains currentOwner) || currentOwner == definitions.EmptyPackageClass) ()
+ else fail(sym + " owner chain does not contain currentOwner " + currentOwner + sym.ownerChain)
case _ =>
def cond(s: Symbol) = !s.isTerm || s.isMethod || s == sym.owner
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index ad48712a32..893941984f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1284,8 +1284,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
unit.error(clazz.pos, "value class may not be a "+
(if (clazz.owner.isTerm) "local class" else "member of another class"))
val constr = clazz.primaryConstructor
- if ((constr hasFlag (PRIVATE | PROTECTED)) || constr.privateWithin != NoSymbol)
- unit.error(constr.pos, "value class must have public primary constructor")
clazz.info.decls.toList.filter(acc => acc.isMethod && (acc hasFlag PARAMACCESSOR)) match {
case List(acc) =>
def isUnderlyingAcc(sym: Symbol) =
diff --git a/test/files/run/valueclasses-constr.scala b/test/files/run/valueclasses-constr.scala
index 7a10299386..652d8d8d22 100644
--- a/test/files/run/valueclasses-constr.scala
+++ b/test/files/run/valueclasses-constr.scala
@@ -1,25 +1,79 @@
-object TOD {
- final val SecondsPerDay = 86400
+package test1 {
+ object TOD {
+ final val SecondsPerDay = 86400
- def apply(seconds: Int) = {
- val n = seconds % SecondsPerDay
- new TOD(if (n >= 0) n else n + SecondsPerDay)
- }
+ def apply(seconds: Int) = {
+ val n = seconds % SecondsPerDay
+ new TOD(if (n >= 0) n else n + SecondsPerDay)
+ }
+ }
+
+ final class TOD (val secondsOfDay: Int) extends AnyVal {
+ def hours = secondsOfDay / 3600
+ def minutes = (secondsOfDay / 60) % 60
+ def seconds = secondsOfDay % 60
+
+ override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds)
+ }
}
+package test2 {
+ object TOD {
+ final val SecondsPerDay = 86400
+
+ def apply(seconds: Int) = {
+ val n = seconds % SecondsPerDay
+ new TOD(if (n >= 0) n else n + SecondsPerDay)
+ }
+ }
+
+ final class TOD private[test2] (val secondsOfDay: Int) extends AnyVal {
+ def hours = secondsOfDay / 3600
+ def minutes = (secondsOfDay / 60) % 60
+ def seconds = secondsOfDay % 60
+
+ override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds)
+ }
+
+ object Client {
+ def newTOD(x: Int) = new TOD(x)
+ }
+}
+
+package test3 {
+ object TOD {
+ final val SecondsPerDay = 86400
+
+ def apply(seconds: Int) = {
+ val n = seconds % SecondsPerDay
+ new TOD(if (n >= 0) n else n + SecondsPerDay)
+ }
+ }
-final class TOD (val secondsOfDay: Int) extends AnyVal {
- def hours = secondsOfDay / 3600
- def minutes = (secondsOfDay / 60) % 60
- def seconds = secondsOfDay % 60
+ final class TOD private (val secondsOfDay: Int) extends AnyVal {
+ def hours = secondsOfDay / 3600
+ def minutes = (secondsOfDay / 60) % 60
+ def seconds = secondsOfDay % 60
- override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds)
+ override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds)
+ }
}
object Test extends App {
- val y: TOD = new TOD(1000)
- val x: TOD = TOD(1000)
- println(x.hours)
- println(x)
+ val y1: test1.TOD = new test1.TOD(1000)
+ val y2: test2.TOD = test2.Client.newTOD(1000)
+ val x1: test1.TOD = test1.TOD(1000)
+ val x2: test2.TOD = test2.TOD(1000)
+ val x3: test3.TOD = test3.TOD(1000)
+ println(y1.minutes)
+ println(y1)
+ println(y2.minutes)
+ println(y2)
+ println(x1.minutes)
+ println(x1)
+ println(x2.minutes)
+ println(x2)
+ println(x3.minutes)
+ println(x3)
}