From bb23d766bceccecc99280b543001bc70e16afbc9 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 14 Feb 2012 22:04:30 -0800 Subject: Specialization action. The crickets at http://www.scala-lang.org/node/11901 were in unanimous agreement that I should proceed as suggested. - No arguments to @specialize gets you 10/10, not 9/10 - Fixed bugs in AnyRef specialization revealed by trying to use it - Specialized Function1 on AnyRef. - Changed AnyRef specialization to use OBJECT_TAG, not TVAR_TAG. - Deprecated SpecializableCompanion in favor of Specializable, which has the virtue of being public so it can be referenced from outside the library. - Cooked up mechanism to group specializable types so we don't have to repeat ourselves quite so much, and create a few groups for illustrative purposes. I'm not too serious about those names but I used up all my name-thinking-up brain for the day. - Updated genprod and friends since I had to regenerate Function1. - Put tests for a bunch of remaining specialization bugs in pending. Closes SI-4740, SI-4770, SI-5267. --- test/files/run/t4770.scala | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test/files/run/t4770.scala (limited to 'test/files/run/t4770.scala') diff --git a/test/files/run/t4770.scala b/test/files/run/t4770.scala new file mode 100644 index 0000000000..25bf3050c3 --- /dev/null +++ b/test/files/run/t4770.scala @@ -0,0 +1,15 @@ +package crasher { + class Z[@specialized A, @specialized(AnyRef) B](var a: A, var b: B) { + override def toString = "" + ((a, b)) + } + object O { + def apply[@specialized A, @specialized(AnyRef) B](a0: A, b0: B) = new Z(a0, b0) + } +} + +object Test { + def main(args: Array[String]): Unit = { + println(crasher.O("a", 2)) + println(crasher.O(2, "a")) + } +} -- cgit v1.2.3 From 1e648c386216d4c60121321a7ec40e2536bada9c Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 17 Feb 2012 09:52:40 -0800 Subject: Fixed AnyRef specialization. At least for the value of fix which means "better than it was in 2.9." I accidentally spent a long while trying to fix something I didn't realize I hadn't broken. But then I lucked into partially fixing it, so that's good news. See run/t5488-fn.scala if you want to see what still doesn't work. (It's covered at SI-4770, which is now reopened.) Closes SI-5488. --- .../scala/reflect/internal/Definitions.scala | 7 ++- .../tools/nsc/transform/SpecializeTypes.scala | 58 ++++++++++++++-------- src/library/scala/package.scala | 5 +- test/files/buildmanager/t2652/t2652.check | 2 +- test/files/run/t4770.check | 2 - test/files/run/t4770.scala | 15 ------ test/files/run/t4794.check | 2 +- test/files/run/t5488-fn.check | 17 +++++++ test/files/run/t5488-fn.scala | 49 ++++++++++++++++++ test/files/run/t5488.check | 14 ++++++ test/files/run/t5488.scala | 26 ++++++++++ test/pending/run/t4770.check | 2 + test/pending/run/t4770.scala | 15 ++++++ 13 files changed, 165 insertions(+), 49 deletions(-) delete mode 100644 test/files/run/t4770.check delete mode 100644 test/files/run/t4770.scala create mode 100644 test/files/run/t5488-fn.check create mode 100644 test/files/run/t5488-fn.scala create mode 100644 test/files/run/t5488.check create mode 100644 test/files/run/t5488.scala create mode 100644 test/pending/run/t4770.check create mode 100644 test/pending/run/t4770.scala (limited to 'test/files/run/t4770.scala') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index b4b0a7335d..d043230e48 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -70,8 +70,7 @@ trait Definitions extends reflect.api.StandardDefinitions { tpnme.Float -> FLOAT_TAG, tpnme.Double -> DOUBLE_TAG, tpnme.Boolean -> BOOL_TAG, - tpnme.Unit -> VOID_TAG, - tpnme.Object -> OBJECT_TAG + tpnme.Unit -> VOID_TAG ) private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f) @@ -80,7 +79,7 @@ trait Definitions extends reflect.api.StandardDefinitions { private def boxedName(name: Name) = sn.Boxed(name.toTypeName) - lazy val abbrvTag = symbolsMap(ObjectClass :: ScalaValueClasses, nameToTag) + lazy val abbrvTag = symbolsMap(ScalaValueClasses, nameToTag) withDefaultValue OBJECT_TAG lazy val numericWeight = symbolsMapFilt(ScalaValueClasses, nameToWeight.keySet, nameToWeight) lazy val boxedModule = classesMap(x => getModule(boxedName(x))) lazy val boxedClass = classesMap(x => getClass(boxedName(x))) @@ -213,7 +212,7 @@ trait Definitions extends reflect.api.StandardDefinitions { // Note: this is not the type alias AnyRef, it's a companion-like // object used by the @specialize annotation. - def AnyRefModule = getMember(ScalaPackageClass, nme.AnyRef) + lazy val AnyRefModule = getMember(ScalaPackageClass, nme.AnyRef) @deprecated("Use AnyRefModule", "2.10.0") def Predef_AnyRef = AnyRefModule diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 8c34a9139d..8b1d5b3295 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -121,9 +121,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // then pos/spec-List.scala fails - why? Does this kind of check fail // for similar reasons? Does `sym.isAbstractType` make a difference? private def isSpecializedAnyRefSubtype(tp: Type, sym: Symbol) = ( - (specializedOn(sym) contains AnyRefModule) + // !!! Come back to this, not sure it's recognizing AnyRefModule + (specializedOn(sym) exists (s => !isValueClass(s))) && !isValueClass(tp.typeSymbol) && isBoundedGeneric(tp) + // && (tp <:< AnyRefClass.tpe) ) private def isBoundedGeneric(tp: Type) = tp match { case TypeRef(_, sym, _) if sym.isAbstractType => (tp <:< AnyRefClass.tpe) @@ -279,10 +281,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val pre1 = this(pre) // when searching for a specialized class, take care to map all // type parameters that are subtypes of AnyRef to AnyRef - val args1 = map2(args, sym.typeParams) { - case (tp, orig) if isSpecializedAnyRefSubtype(tp, orig) => AnyRefClass.tpe - case (tp, _) => tp - } + val args1 = map2(args, sym.info.typeParams)((tp, orig) => + if (isSpecializedAnyRefSubtype(tp, orig)) AnyRefClass.tpe + else tp + ) specializedClass.get((sym, TypeEnv.fromSpecialization(sym, args1))) match { case Some(sym1) => typeRef(pre1, sym1, survivingArgs(sym, args)) case None => typeRef(pre1, sym, args) @@ -305,7 +307,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { else specializedTypeVars(sym).intersect(env.keySet) ) val (methparams, others) = tvars.toList sortBy ("" + _.name) partition (_.owner.isMethod) - debuglog("specName(" + sym + ") env: " + env + " tvars: " + tvars) + log("specName(" + sym + ") env: " + env + " tvars: " + tvars) specializedName(sym.name, methparams map env, others map env) } @@ -322,10 +324,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { nme.getterToLocal(specializedName(nme.localToGetter(name), types1, types2)) else { val (base, cs, ms) = nme.splitSpecializedName(name) - val abbrevs = definitions.abbrvTag withDefaultValue definitions.abbrvTag(ObjectClass) newTermName(base.toString + "$" - + "m" + ms + types1.map(t => abbrevs(t.typeSymbol)).mkString("", "", "") - + "c" + cs + types2.map(t => abbrevs(t.typeSymbol)).mkString("", "", "$sp")) + + "m" + ms + types1.map(t => definitions.abbrvTag(t.typeSymbol)).mkString("", "", "") + + "c" + cs + types2.map(t => definitions.abbrvTag(t.typeSymbol)).mkString("", "", "$sp")) } } @@ -370,8 +371,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case set :: Nil => set map (x => List(x)) case set :: sets => for (x <- set ; xs <- loop(sets)) yield x :: xs } - // zip the keys with each permutation to create a TypeEnv - loop(keys map concreteTypes) map (xss => Map(keys zip xss: _*)) + // zip the keys with each permutation to create a TypeEnv. + // If we don't exclude the "all AnyRef" specialization, we will + // incur duplicate members and crash during mixin. + loop(keys map concreteTypes) filterNot (_ forall (_ <:< AnyRefClass.tpe)) map (xss => Map(keys zip xss: _*)) } /** Does the given 'sym' need to be specialized in the environment 'env'? @@ -962,6 +965,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } case object UnifyError extends scala.util.control.ControlThrowable + private[this] def unifyError(tp1: Any, tp2: Any): Nothing = { + log("unifyError" + ((tp1, tp2))) + throw UnifyError + } /** Return the most general type environment that specializes tp1 to tp2. * It only allows binding of type parameters annotated with @specialized. @@ -972,29 +979,34 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { private def unify(tp1: Type, tp2: Type, env: TypeEnv, strict: Boolean): TypeEnv = (tp1, tp2) match { case (TypeRef(_, sym1, _), _) if isSpecialized(sym1) => debuglog("Unify - basic case: " + tp1 + ", " + tp2) - if (isValueClass(tp2.typeSymbol) || isSpecializedAnyRefSubtype(tp2, sym1)) + if (isValueClass(tp2.typeSymbol)) env + ((sym1, tp2)) + else if (isSpecializedAnyRefSubtype(tp2, sym1)) + env + ((sym1, tp2)) // env + ((sym1, AnyRefClass.tpe)) + else if (strict) + unifyError(tp1, tp2) else - if (strict) throw UnifyError else env + env case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) => debuglog("Unify TypeRefs: " + tp1 + " and " + tp2 + " with args " + (args1, args2) + " - ") - if (strict && args1.length != args2.length) throw UnifyError + if (strict && args1.length != args2.length) unifyError(tp1, tp2) val e = unify(args1, args2, env, strict) debuglog("unified to: " + e) e case (TypeRef(_, sym1, _), _) if sym1.isTypeParameterOrSkolem => env case (MethodType(params1, res1), MethodType(params2, res2)) => - if (strict && params1.length != params2.length) throw UnifyError + if (strict && params1.length != params2.length) unifyError(tp1, tp2) debuglog("Unify MethodTypes: " + tp1 + " and " + tp2) unify(res1 :: (params1 map (_.tpe)), res2 :: (params2 map (_.tpe)), env, strict) case (PolyType(tparams1, res1), PolyType(tparams2, res2)) => - if (strict && tparams1.length != tparams2.length) throw UnifyError debuglog("Unify PolyTypes: " + tp1 + " and " + tp2) - unify(res1, res2, env, strict) - case (PolyType(_, res), other) => - unify(res, other, env, strict) - case (ThisType(_), ThisType(_)) => env + if (strict && tparams1.length != tparams2.length) + unifyError(tp1, tp2) + else + unify(res1, res2, env, strict) + case (PolyType(_, res), other) => unify(res, other, env, strict) + case (ThisType(_), ThisType(_)) => env case (_, SingleType(_, _)) => unify(tp1, tp2.underlying, env, strict) case (SingleType(_, _), _) => unify(tp1.underlying, tp2, env, strict) case (ThisType(_), _) => unify(tp1.widen, tp2, env, strict) @@ -1016,7 +1028,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { if (env.keySet intersect nenv.keySet isEmpty) env ++ nenv else { debuglog("could not unify: u(" + args._1 + ", " + args._2 + ") yields " + nenv + ", env: " + env) - throw UnifyError + unifyError(tp1, tp2) } } } @@ -1242,7 +1254,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } - def doesConform(origSymbol: Symbol, treeType: Type, memberType: Type, env: TypeEnv) = + def doesConform(origSymbol: Symbol, treeType: Type, memberType: Type, env: TypeEnv) = { (treeType =:= memberType) || { // anyref specialization memberType match { case PolyType(_, resTpe) => @@ -1259,6 +1271,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case _ => false } } + } override def transform(tree: Tree): Tree = { val symbol = tree.symbol @@ -1289,6 +1302,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { curTree = tree tree match { case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => + // log("Attempting to specialize new %s(%s)".format(tpt, args.mkString(", "))) if (findSpec(tpt.tpe).typeSymbol ne tpt.tpe.typeSymbol) { // the ctor can be specialized log("** instantiated specialized type: " + findSpec(tpt.tpe)) diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index 9425eba232..06d7f46d52 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -29,10 +29,7 @@ package object scala { type AbstractMethodError = java.lang.AbstractMethodError // A dummy used by the specialization annotation. - // Normally it's bad juju to place objects inside package objects, - // but there's no choice here as we'd have to be AnyRef's companion - // and defined in the same file - except there is no such file. - object AnyRef extends Specializable { + val AnyRef = new Specializable { override def toString = "object AnyRef" } diff --git a/test/files/buildmanager/t2652/t2652.check b/test/files/buildmanager/t2652/t2652.check index b84c80205e..071281c6ff 100644 --- a/test/files/buildmanager/t2652/t2652.check +++ b/test/files/buildmanager/t2652/t2652.check @@ -3,7 +3,7 @@ compiling Set(A.scala, B.scala) Changes: Map() builder > A.scala compiling Set(A.scala) -Changes: Map(class A -> List(Added(Definition(A.x$mBc$sp)), Added(Definition(A.x$mCc$sp)), Added(Definition(A.x$mDc$sp)), Added(Definition(A.x$mFc$sp)), Added(Definition(A.x$mIc$sp)), Added(Definition(A.x$mJc$sp)), Added(Definition(A.x$mLc$sp)), Added(Definition(A.x$mSc$sp)), Added(Definition(A.x$mVc$sp)), Added(Definition(A.x$mZc$sp)), Changed(Definition(A.x))[method x changed from [T](t: T)T to [T](t: T)T flags: ])) +Changes: Map(class A -> List(Added(Definition(A.x$mBc$sp)), Added(Definition(A.x$mCc$sp)), Added(Definition(A.x$mDc$sp)), Added(Definition(A.x$mFc$sp)), Added(Definition(A.x$mIc$sp)), Added(Definition(A.x$mJc$sp)), Added(Definition(A.x$mSc$sp)), Added(Definition(A.x$mVc$sp)), Added(Definition(A.x$mZc$sp)), Changed(Definition(A.x))[method x changed from [T](t: T)T to [T](t: T)T flags: ])) invalidate B.scala because it references changed definition [Changed(Definition(A.x))[method x changed from [T](t: T)T to [T](t: T)T flags: ]] compiling Set(B.scala) Changes: Map(object B -> List()) diff --git a/test/files/run/t4770.check b/test/files/run/t4770.check deleted file mode 100644 index 38e5a831fa..0000000000 --- a/test/files/run/t4770.check +++ /dev/null @@ -1,2 +0,0 @@ -(a,2) -(2,a) diff --git a/test/files/run/t4770.scala b/test/files/run/t4770.scala deleted file mode 100644 index 25bf3050c3..0000000000 --- a/test/files/run/t4770.scala +++ /dev/null @@ -1,15 +0,0 @@ -package crasher { - class Z[@specialized A, @specialized(AnyRef) B](var a: A, var b: B) { - override def toString = "" + ((a, b)) - } - object O { - def apply[@specialized A, @specialized(AnyRef) B](a0: A, b0: B) = new Z(a0, b0) - } -} - -object Test { - def main(args: Array[String]): Unit = { - println(crasher.O("a", 2)) - println(crasher.O(2, "a")) - } -} diff --git a/test/files/run/t4794.check b/test/files/run/t4794.check index b4de394767..f599e28b8a 100644 --- a/test/files/run/t4794.check +++ b/test/files/run/t4794.check @@ -1 +1 @@ -11 +10 diff --git a/test/files/run/t5488-fn.check b/test/files/run/t5488-fn.check new file mode 100644 index 0000000000..196f58d063 --- /dev/null +++ b/test/files/run/t5488-fn.check @@ -0,0 +1,17 @@ +B$mcII$sp +B +B$mcIV$sp +B$mcLI$sp +B +B$mcLV$sp +B$mcVI$sp +B +B$mcVV$sp +C$mcIII$sp +C +C$mcILI$sp +C +C$mcLII$sp +C +C$mcLLI$sp +C diff --git a/test/files/run/t5488-fn.scala b/test/files/run/t5488-fn.scala new file mode 100644 index 0000000000..9e4f60002b --- /dev/null +++ b/test/files/run/t5488-fn.scala @@ -0,0 +1,49 @@ +class B[@specialized(Int, AnyRef, Unit) A, @specialized(Int, Unit) B](f: A => B) +class C[@specialized(Int, AnyRef) A, @specialized(Int, AnyRef) B, @specialized(Int) C](f: (A, B) => C) +// Not yet: +// class B[@specialized(Int, AnyRef, Unit) A, @specialized(Int, AnyRef, Unit) B](f: A => B) +// class C[@specialized(Int, AnyRef) A, @specialized(Int, AnyRef) B, @specialized(Int, AnyRef) C](f: (A, B) => C) + +object Test { + def main(args:Array[String]) { + def show(x: Any) = println(x.getClass.getName) + + show(new B((x: Int) => 1)) + show(new B((x: Int) => "abc")) + show(new B((x: Int) => ())) + show(new B((x: AnyRef) => 1)) + show(new B((x: AnyRef) => "abc")) + show(new B((x: AnyRef) => ())) + show(new B((x: Unit) => 1)) + show(new B((x: Unit) => "abc")) + show(new B((x: Unit) => ())) + + show(new C((x: Int, y: Int) => 1)) + show(new C((x: Int, y: Int) => "abc")) + show(new C((x: Int, y: AnyRef) => 1)) + show(new C((x: Int, y: AnyRef) => "abc")) + show(new C((x: AnyRef, y: Int) => 1)) + show(new C((x: AnyRef, y: Int) => "abc")) + show(new C((x: AnyRef, y: AnyRef) => 1)) + show(new C((x: AnyRef, y: AnyRef) => "abc")) + } +} +/** If the return types are specialized on AnyRef as well: + +files/run/t5488-fn.scala:18: error: type mismatch; + found : Unit => String + required: Unit => B$sp + show(new B((x: Unit) => "abc")) + ^ +files/run/t5488-fn.scala:24: error: type mismatch; + found : (Int, Object) => String + required: (Int, B$sp) => C$sp + show(new C((x: Int, y: AnyRef) => "abc")) + ^ +files/run/t5488-fn.scala:26: error: type mismatch; + found : (Object, Int) => String + required: (A$sp, Int) => C$sp + show(new C((x: AnyRef, y: Int) => "abc")) + ^ +three errors found +**/ diff --git a/test/files/run/t5488.check b/test/files/run/t5488.check new file mode 100644 index 0000000000..ccd98c4dbc --- /dev/null +++ b/test/files/run/t5488.check @@ -0,0 +1,14 @@ +A0$mcI$sp +A0 +B0$mcII$sp +B0$mcIL$sp +B0$mcLI$sp +B0 +C0$mcIII$sp +C0$mcIIL$sp +C0$mcILI$sp +C0$mcILL$sp +C0$mcLII$sp +C0$mcLIL$sp +C0$mcLLI$sp +C0 diff --git a/test/files/run/t5488.scala b/test/files/run/t5488.scala new file mode 100644 index 0000000000..7bab0cdc3c --- /dev/null +++ b/test/files/run/t5488.scala @@ -0,0 +1,26 @@ +class A0[@specialized(Int, AnyRef) A]() +class B0[@specialized(Int, AnyRef) A, @specialized(Int, AnyRef) B]() +class C0[@specialized(Int, AnyRef) A, @specialized(Int, AnyRef) B, @specialized(Int, AnyRef) C]() + +object Test { + def main(args:Array[String]) { + def show(x: Any) = println(x.getClass.getName) + + show(new A0[Int]()) + show(new A0[AnyRef]()) + + show(new B0[Int, Int]()) + show(new B0[Int, AnyRef]()) + show(new B0[AnyRef, Int]()) + show(new B0[AnyRef, AnyRef]()) + + show(new C0[Int, Int, Int]()) + show(new C0[Int, Int, AnyRef]()) + show(new C0[Int, AnyRef, Int]()) + show(new C0[Int, AnyRef, AnyRef]()) + show(new C0[AnyRef, Int, Int]()) + show(new C0[AnyRef, Int, AnyRef]()) + show(new C0[AnyRef, AnyRef, Int]()) + show(new C0[AnyRef, AnyRef, AnyRef]()) + } +} diff --git a/test/pending/run/t4770.check b/test/pending/run/t4770.check new file mode 100644 index 0000000000..38e5a831fa --- /dev/null +++ b/test/pending/run/t4770.check @@ -0,0 +1,2 @@ +(a,2) +(2,a) diff --git a/test/pending/run/t4770.scala b/test/pending/run/t4770.scala new file mode 100644 index 0000000000..25bf3050c3 --- /dev/null +++ b/test/pending/run/t4770.scala @@ -0,0 +1,15 @@ +package crasher { + class Z[@specialized A, @specialized(AnyRef) B](var a: A, var b: B) { + override def toString = "" + ((a, b)) + } + object O { + def apply[@specialized A, @specialized(AnyRef) B](a0: A, b0: B) = new Z(a0, b0) + } +} + +object Test { + def main(args: Array[String]): Unit = { + println(crasher.O("a", 2)) + println(crasher.O(2, "a")) + } +} -- cgit v1.2.3 From 87e369ef46bd2ca569ffd1cd6f3a554f1d645dc9 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 19 Feb 2012 00:03:55 -0800 Subject: More specialization tests. Some in pending, some in files. Closes SI-4770. --- test/files/run/t3575.check | 16 +++++++++++++ test/files/run/t3575.scala | 55 +++++++++++++++++++++++++++++++++++++++----- test/files/run/t4770.check | 2 ++ test/files/run/t4770.scala | 15 ++++++++++++ test/pending/pos/t4123.scala | 14 +++++++++++ test/pending/pos/t4436.scala | 3 +++ test/pending/pos/t4717.scala | 7 ++++++ test/pending/pos/t4787.scala | 4 ++++ test/pending/run/t4770.check | 2 -- test/pending/run/t4770.scala | 15 ------------ 10 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 test/files/run/t4770.check create mode 100644 test/files/run/t4770.scala create mode 100644 test/pending/pos/t4123.scala create mode 100644 test/pending/pos/t4436.scala create mode 100644 test/pending/pos/t4717.scala create mode 100644 test/pending/pos/t4787.scala delete mode 100644 test/pending/run/t4770.check delete mode 100644 test/pending/run/t4770.scala (limited to 'test/files/run/t4770.scala') diff --git a/test/files/run/t3575.check b/test/files/run/t3575.check index c240b3d90c..9080fd8674 100644 --- a/test/files/run/t3575.check +++ b/test/files/run/t3575.check @@ -2,3 +2,19 @@ Two Two Two Two$mcII$sp +TwoLong +TwoLong$mcIL$sp +TwoLong$mcLI$sp +TwoLong$mcII$sp +TwoCool +TwoCool$mcIL$sp +TwoCool$mcLI$sp +TwoCool$mcII$sp +TwoShort +TwoShort +TwoShort +TwoShort$mcII$sp +TwoMinimal +TwoMinimal$mcIL$sp +TwoMinimal$mcLI$sp +TwoMinimal$mcII$sp diff --git a/test/files/run/t3575.scala b/test/files/run/t3575.scala index 56950e62bb..9ccd90a8c4 100644 --- a/test/files/run/t3575.scala +++ b/test/files/run/t3575.scala @@ -1,12 +1,55 @@ -case class Two[@specialized A, @specialized B](v: A, w: B); - // This is here to tell me if the behavior changes, not because // the output is endorsed. +case class Two[ + @specialized A, + @specialized B +](v: A, w: B) + +case class TwoLong[ + @specialized(Char, Boolean, Byte, Short, Int, Long, Float, Double, Unit, AnyRef) A, + @specialized(Char, Boolean, Byte, Short, Int, Long, Float, Double, Unit, AnyRef) B +](v: A, w: B) + +case class TwoCool[ + @specialized(Specializable.Everything) A, + @specialized(Specializable.Everything) B +](v: A, w: B) + +case class TwoShort[ + @specialized() A, + @specialized() B +](v: A, w: B) + +case class TwoMinimal[ + @specialized(Int, AnyRef) A, + @specialized(Int, AnyRef) B +](v: A, w: B) + object Test { def main(args: Array[String]): Unit = { - println(Two("Hello", 12).getClass().getName()) - println(Two(12, "Hello").getClass().getName()) - println(Two("Hello", "World").getClass().getName()) - println(Two(12, 12).getClass().getName()) + println(Two("Hello", "World").getClass().getName()); + println(Two(12, "Hello").getClass().getName()); + println(Two("Hello", 12).getClass().getName()); + println(Two(12, 12).getClass().getName()); + + println(TwoLong("Hello", "World").getClass().getName()); + println(TwoLong(12, "Hello").getClass().getName()); + println(TwoLong("Hello", 12).getClass().getName()); + println(TwoLong(12, 12).getClass().getName()); + + println(TwoCool("Hello", "World").getClass().getName()); + println(TwoCool(12, "Hello").getClass().getName()); + println(TwoCool("Hello", 12).getClass().getName()); + println(TwoCool(12, 12).getClass().getName()); + + println(TwoShort("Hello", "World").getClass().getName()); + println(TwoShort(12, "Hello").getClass().getName()); + println(TwoShort("Hello", 12).getClass().getName()); + println(TwoShort(12, 12).getClass().getName()); + + println(TwoMinimal("Hello", "World").getClass().getName()); + println(TwoMinimal(12, "Hello").getClass().getName()); + println(TwoMinimal("Hello", 12).getClass().getName()); + println(TwoMinimal(12, 12).getClass().getName()); } } diff --git a/test/files/run/t4770.check b/test/files/run/t4770.check new file mode 100644 index 0000000000..38e5a831fa --- /dev/null +++ b/test/files/run/t4770.check @@ -0,0 +1,2 @@ +(a,2) +(2,a) diff --git a/test/files/run/t4770.scala b/test/files/run/t4770.scala new file mode 100644 index 0000000000..25bf3050c3 --- /dev/null +++ b/test/files/run/t4770.scala @@ -0,0 +1,15 @@ +package crasher { + class Z[@specialized A, @specialized(AnyRef) B](var a: A, var b: B) { + override def toString = "" + ((a, b)) + } + object O { + def apply[@specialized A, @specialized(AnyRef) B](a0: A, b0: B) = new Z(a0, b0) + } +} + +object Test { + def main(args: Array[String]): Unit = { + println(crasher.O("a", 2)) + println(crasher.O(2, "a")) + } +} diff --git a/test/pending/pos/t4123.scala b/test/pending/pos/t4123.scala new file mode 100644 index 0000000000..82ab16b4e4 --- /dev/null +++ b/test/pending/pos/t4123.scala @@ -0,0 +1,14 @@ +// /scala/trac/4123/a.scala +// Sun Feb 19 00:08:53 PST 2012 + +trait Iter[@specialized(Byte) +A] extends Iterator[A] { + self => + + override def map[B](f: (A) => B) = super.map(f) +} + +class ByteIter extends Iter[Byte] { + var i = 0 + def hasNext = i < 3 + def next = { i += 1 ; i.toByte } +} \ No newline at end of file diff --git a/test/pending/pos/t4436.scala b/test/pending/pos/t4436.scala new file mode 100644 index 0000000000..acbf0beae6 --- /dev/null +++ b/test/pending/pos/t4436.scala @@ -0,0 +1,3 @@ +trait Chunk[@specialized +A] { + def bippy[@specialized B >: A](e: B): Chunk[B] +} \ No newline at end of file diff --git a/test/pending/pos/t4717.scala b/test/pending/pos/t4717.scala new file mode 100644 index 0000000000..43cf412bc6 --- /dev/null +++ b/test/pending/pos/t4717.scala @@ -0,0 +1,7 @@ +trait Bug1[@specialized +A] extends TraversableOnce[A] { + def ++[B >: A](that: TraversableOnce[B]): Iterator[B] = new Iterator[B] { + lazy val it = that.toIterator + def hasNext = it.hasNext + def next = it.next + } +} \ No newline at end of file diff --git a/test/pending/pos/t4787.scala b/test/pending/pos/t4787.scala new file mode 100644 index 0000000000..cf3fe93c50 --- /dev/null +++ b/test/pending/pos/t4787.scala @@ -0,0 +1,4 @@ +trait MatrixImpl[@specialized A, @specialized B] { + def mapTo[ A2, B2, That <: MatrixImpl[A2, B2]](that: That)(f: A => A2) { + } +} diff --git a/test/pending/run/t4770.check b/test/pending/run/t4770.check deleted file mode 100644 index 38e5a831fa..0000000000 --- a/test/pending/run/t4770.check +++ /dev/null @@ -1,2 +0,0 @@ -(a,2) -(2,a) diff --git a/test/pending/run/t4770.scala b/test/pending/run/t4770.scala deleted file mode 100644 index 25bf3050c3..0000000000 --- a/test/pending/run/t4770.scala +++ /dev/null @@ -1,15 +0,0 @@ -package crasher { - class Z[@specialized A, @specialized(AnyRef) B](var a: A, var b: B) { - override def toString = "" + ((a, b)) - } - object O { - def apply[@specialized A, @specialized(AnyRef) B](a0: A, b0: B) = new Z(a0, b0) - } -} - -object Test { - def main(args: Array[String]): Unit = { - println(crasher.O("a", 2)) - println(crasher.O(2, "a")) - } -} -- cgit v1.2.3