summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala7
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala22
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala5
-rw-r--r--src/library/scala/runtime/AnyValCompanion.scala86
-rw-r--r--test/files/neg/bug1392.check4
-rw-r--r--test/files/neg/bug1392.scala1
-rw-r--r--test/files/neg/bug3123.check4
-rw-r--r--test/files/neg/bug3123.scala5
9 files changed, 115 insertions, 21 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index b1d1849c71..a3b81862e6 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -807,14 +807,17 @@ abstract class GenICode extends SubComponent {
ctx
case Select(qualifier, selector) =>
- val sym = tree.symbol
+ var sym = tree.symbol
generatedType = toTypeKind(sym.info)
if (sym.isModule) {
if (settings.debug.value)
log("LOAD_MODULE from Select(qualifier, selector): " + sym);
assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- ctx.bb.emit(LOAD_MODULE(sym), tree.pos);
+ if (definitions.primitiveCompanions(sym))
+ ctx.bb.emit(LOAD_MODULE(definitions.getModule("scala.runtime." + sym.name)))
+ else
+ ctx.bb.emit(LOAD_MODULE(sym), tree.pos);
ctx
} else if (sym.isStaticMember) {
ctx.bb.emit(LOAD_FIELD(sym, true), tree.pos)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 40eb08adfd..c587b8342c 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -1737,6 +1737,8 @@ abstract class GenJVM extends SubComponent {
return javaName(definitions.RuntimeNothingClass)
else if (sym == definitions.NullClass)
return javaName(definitions.RuntimeNullClass)
+ else if (definitions.primitiveCompanions(sym.companionModule))
+ return javaName(definitions.getModule("scala.runtime." + sym.name))
if (sym.isClass && !sym.rawowner.isPackageClass && !sym.isModuleClass) {
innerClasses = innerClasses + sym;
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 73d5193ed0..a2382063c3 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -82,8 +82,12 @@ trait Definitions extends reflect.generic.StandardDefinitions {
lazy val RuntimeNothingClass = getClass("scala.runtime.Nothing$")
lazy val RuntimeNullClass = getClass("scala.runtime.Null$")
+ lazy val AnyValCompanionClass = getClass("scala.runtime.AnyValCompanion").setFlag(SEALED | ABSTRACT | TRAIT)
+
// the scala value classes
- lazy val UnitClass = newClass(ScalaPackageClass, nme.Unit, anyvalparam).setFlag(ABSTRACT | FINAL)
+ lazy val UnitClass =
+ newClass(ScalaPackageClass, nme.Unit, anyvalparam).setFlag(ABSTRACT | FINAL)
+
lazy val ByteClass = newValueClass(nme.Byte, 'B', 2)
lazy val ShortClass = newValueClass(nme.Short, 'S', 4)
lazy val CharClass = newValueClass(nme.Char, 'C', 3)
@@ -578,6 +582,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
val boxedModule = new HashMap[Symbol, Symbol]
val unboxMethod = new HashMap[Symbol, Symbol] // Type -> Method
val boxMethod = new HashMap[Symbol, Symbol] // Type -> Method
+ val primitiveCompanions = new HashSet[Symbol]
def isUnbox(m: Symbol) = unboxMethod.valuesIterator contains m
def isBox(m: Symbol) = boxMethod.valuesIterator contains m
@@ -596,6 +601,17 @@ trait Definitions extends reflect.generic.StandardDefinitions {
case None => false
}
+ /** Create a companion object for scala.Unit.
+ */
+ private def initUnitCompanionObject() {
+ val module = ScalaPackageClass.newModule(NoPosition, "Unit")
+ ScalaPackageClass.info.decls.enter(module)
+ val mclass = module.moduleClass
+ mclass.setInfo(ClassInfoType(List(AnyRefClass.tpe, AnyValCompanionClass.tpe), new Scope, mclass))
+ module.setInfo(mclass.tpe)
+ primitiveCompanions += module
+ }
+
private[symtab] def newValueClass(name: Name, tag: Char, weight: Int): Symbol = {
val boxedName = sn.Boxed(name)
@@ -609,8 +625,9 @@ trait Definitions extends reflect.generic.StandardDefinitions {
val module = ScalaPackageClass.newModule(NoPosition, name)
ScalaPackageClass.info.decls.enter(module)
val mclass = module.moduleClass
- mclass.setInfo(ClassInfoType(List(), new Scope, mclass))
+ mclass.setInfo(ClassInfoType(List(AnyRefClass.tpe, AnyValCompanionClass.tpe), new Scope, mclass))
module.setInfo(mclass.tpe)
+ primitiveCompanions += module
val box = newMethod(mclass, nme.box, List(clazz.typeConstructor), boxedClass(clazz).tpe)
boxMethod(clazz) = box
@@ -769,6 +786,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
abbrvTag(UnitClass) = 'V'
initValueClasses()
+ initUnitCompanionObject()
// members of class scala.Any
Any_== = newMethod(AnyClass, nme.EQ, anyparam, booltype) setFlag FINAL
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index f50ace8426..2ccab7641a 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -389,10 +389,9 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** Is this symbol a type but not a class? */
def isNonClassType = false
- /** Term symbols with the exception of static parts of Java classes and packages
- * and the faux companion objects of primitives. (See tickets #1392 and #3123.)
+ /** Term symbols with the exception of static parts of Java classes and packages.
*/
- final def isValue = isTerm && !(isModule && (hasFlag(PACKAGE | JAVA) || isValueClass(companionClass)))
+ final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA))
final def isVariable = isTerm && hasFlag(MUTABLE) && !isMethod
diff --git a/src/library/scala/runtime/AnyValCompanion.scala b/src/library/scala/runtime/AnyValCompanion.scala
new file mode 100644
index 0000000000..0a6f93805a
--- /dev/null
+++ b/src/library/scala/runtime/AnyValCompanion.scala
@@ -0,0 +1,86 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2010, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.runtime
+
+/** A common supertype for companion classes of primitive types.
+ *
+ * A common trait for /companion/ objects of primitive types comes handy
+ * when parameterizing code on types. For instance, the specialized
+ * annotation is passed a sequence of types on which to specialize:
+ * {{{
+ * class Tuple1[@specialized(Unit, Int, Double) T]
+ * }}}
+ *
+ */
+sealed trait AnyValCompanion
+
+/** A object representing 'object scala.Unit'. It should never be used
+ * directly.
+ */
+object Unit extends AnyValCompanion {
+ override def toString = "object scala.Unit"
+}
+
+/** A object representing 'object scala.Boolean'. It should never be used
+ * directly.
+ */
+object Boolean extends AnyValCompanion {
+ override def toString = "object scala.Boolean"
+}
+
+/** A object representing 'object scala.Byte'. It should never be used
+ * directly.
+ */
+object Byte extends AnyValCompanion {
+ override def toString = "object scala.Byte"
+}
+
+/** A object representing 'object scala.Short'. It should never be used
+ * directly.
+ */
+object Short extends AnyValCompanion {
+ override def toString = "object scala.Short"
+}
+
+/** A object representing 'object scala.Char'. It should never be used
+ * directly.
+ */
+object Char extends AnyValCompanion {
+ override def toString = "object scala.Char"
+}
+
+/** A object representing 'object scala.Int'. It should never be used
+ * directly.
+ */
+object Int extends AnyValCompanion {
+ override def toString = "object scala.Int"
+}
+
+/** A object representing 'object scala.Long'. It should never be used
+ * directly.
+ */
+object Long extends AnyValCompanion {
+ override def toString = "object scala.Long"
+}
+
+/** A object representing 'object scala.Float'. It should never be used
+ * directly.
+ */
+object Float extends AnyValCompanion {
+ override def toString = "object scala.Float"
+}
+
+/** A object representing 'object scala.Double'. It should never be used
+ * directly.
+ */
+object Double extends AnyValCompanion {
+ override def toString = "object scala.Double"
+}
diff --git a/test/files/neg/bug1392.check b/test/files/neg/bug1392.check
deleted file mode 100644
index e4c9630435..0000000000
--- a/test/files/neg/bug1392.check
+++ /dev/null
@@ -1,4 +0,0 @@
-bug1392.scala:1: error: object Int is not a value
-object X extends Application { Int }
- ^
-one error found
diff --git a/test/files/neg/bug1392.scala b/test/files/neg/bug1392.scala
deleted file mode 100644
index 54a4b9e908..0000000000
--- a/test/files/neg/bug1392.scala
+++ /dev/null
@@ -1 +0,0 @@
-object X extends Application { Int }
diff --git a/test/files/neg/bug3123.check b/test/files/neg/bug3123.check
deleted file mode 100644
index 8f5319c9a3..0000000000
--- a/test/files/neg/bug3123.check
+++ /dev/null
@@ -1,4 +0,0 @@
-bug3123.scala:3: error: object Int is not a value
- t match { case Int => true }
- ^
-one error found
diff --git a/test/files/neg/bug3123.scala b/test/files/neg/bug3123.scala
deleted file mode 100644
index 667a1da918..0000000000
--- a/test/files/neg/bug3123.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-object NotAValue {
- def test[T](t : T) {
- t match { case Int => true }
- }
-}