diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala | 13 | ||||
-rw-r--r-- | test/files/specialized/t6035.check | 1 | ||||
-rw-r--r-- | test/files/specialized/t6035/first_1.scala | 5 | ||||
-rw-r--r-- | test/files/specialized/t6035/second_2.scala | 13 |
5 files changed, 32 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 663b3dd2e9..de0650b2ea 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -564,12 +564,6 @@ abstract class UnCurry extends InfoTransform } val sym = tree.symbol - // Take a pass looking for @specialize annotations and set all - // their SPECIALIZE flags for cheaper recognition. - if ((sym ne null) && (sym.isClass || sym.isMethod)) { - for (tp <- sym.typeParams ; if tp hasAnnotation SpecializedClass) - tp setFlag SPECIALIZED - } val result = ( // TODO - settings.noassertions.value temporarily retained to avoid // breakage until a reasonable interface is settled upon. diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index f67cec730b..b544407286 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -19,6 +19,10 @@ import symtab.Flags._ * of class-members which are private up to an enclosing non-package * class, in order to avoid overriding conflicts. * + * This phase also sets SPECIALIZED flag on type parameters with + * `@specialized` annotation. We put this logic here because the + * flag must be set before pickling. + * * @author Martin Odersky * @version 1.0 */ @@ -208,6 +212,15 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT case TypeApply(sel @ Select(This(_), name), args) => mayNeedProtectedAccessor(sel, args, false) + // set a flag for all type parameters with `@specialized` annotation so it can be pickled + case typeDef: TypeDef if typeDef.symbol.deSkolemize.hasAnnotation(definitions.SpecializedClass) => + debuglog("setting SPECIALIZED flag on typeDef.symbol.deSkolemize where typeDef = " + typeDef) + // we need to deSkolemize symbol so we get the same symbol as others would get when + // inspecting type parameter from "outside"; see the discussion of skolems here: + // https://groups.google.com/d/topic/scala-internals/0j8laVNTQsI/discussion + typeDef.symbol.deSkolemize.setFlag(SPECIALIZED) + typeDef + case sel @ Select(qual @ This(_), name) => // warn if they are selecting a private[this] member which // also exists in a superclass, because they may be surprised diff --git a/test/files/specialized/t6035.check b/test/files/specialized/t6035.check new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/files/specialized/t6035.check @@ -0,0 +1 @@ +0 diff --git a/test/files/specialized/t6035/first_1.scala b/test/files/specialized/t6035/first_1.scala new file mode 100644 index 0000000000..1289e9f48e --- /dev/null +++ b/test/files/specialized/t6035/first_1.scala @@ -0,0 +1,5 @@ +trait Foo[@specialized(Int) A] { + def foo(x: A): A +} + +abstract class Inter extends Foo[Int] diff --git a/test/files/specialized/t6035/second_2.scala b/test/files/specialized/t6035/second_2.scala new file mode 100644 index 0000000000..fb317e2a6a --- /dev/null +++ b/test/files/specialized/t6035/second_2.scala @@ -0,0 +1,13 @@ +class Baz extends Inter { + def foo(x: Int) = x + 1 +} + +object Test { + def main(args: Array[String]) { + // it's important that the type is Inter so we do not call Baz.foo(I)I directly! + val baz: Inter = new Baz + // here we should go through specialized version of foo and thus have zero boxing + baz.foo(1) + println(runtime.BoxesRunTime.integerBoxCount) + } +} |