diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 22 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 5 | ||||
-rw-r--r-- | src/library/scala/runtime/AnyValCompanion.scala | 86 | ||||
-rw-r--r-- | test/files/neg/bug1392.check | 4 | ||||
-rw-r--r-- | test/files/neg/bug1392.scala | 1 | ||||
-rw-r--r-- | test/files/neg/bug3123.check | 4 | ||||
-rw-r--r-- | test/files/neg/bug3123.scala | 5 |
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 } - } -} |