diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 5 | ||||
-rw-r--r-- | src/library/scala/collection/SeqLike.scala | 2 | ||||
-rw-r--r-- | src/library/scala/reflect/api/TreePrinters.scala | 41 | ||||
-rw-r--r-- | test/files/run/t5377.check | 18 | ||||
-rw-r--r-- | test/files/run/t5377.scala | 47 | ||||
-rw-r--r-- | test/files/specialized/spec-hlists.check | 2 | ||||
-rw-r--r-- | test/files/specialized/spec-hlists.scala | 29 |
7 files changed, 141 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 85c3a77dcb..fd826fb6d8 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1258,7 +1258,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { .format(tree, symbol.tpe, tree.tpe, env, specializedName(symbol, env))) if (!env.isEmpty) { // a method? val specCandidates = qual.tpe.member(specializedName(symbol, env)) - val specMember = specCandidates suchThat (s => doesConform(symbol, tree.tpe, s.tpe, env)) + val specMember = specCandidates suchThat { s => + doesConform(symbol, tree.tpe, qual.tpe.memberType(s), env) + } + log("[specSym] found: " + specCandidates.tpe + ", instantiated as: " + tree.tpe) log("[specSym] found specMember: " + specMember) if (specMember ne NoSymbol) diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index b6b4bfb96d..6d84b4276b 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -152,7 +152,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] with GenSeqLike[A, Repr] if (!hasNext) Iterator.empty.next - val result = (self.newBuilder ++= elms).result + val result = (self.newBuilder ++= elms.toList).result var i = idxs.length - 2 while(i >= 0 && idxs(i) >= idxs(i+1)) i -= 1 diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala index 15fba0e418..88ef450ed9 100644 --- a/src/library/scala/reflect/api/TreePrinters.scala +++ b/src/library/scala/reflect/api/TreePrinters.scala @@ -28,7 +28,21 @@ trait TreePrinters { self: Universe => */ def newTreePrinter(out: PrintWriter): TreePrinter + // emits more or less verbatim representation of the provided tree + // todo. when LiftCode becomes a macro, throw this code away and use that macro class RawTreePrinter(out: PrintWriter) extends TreePrinter { + import scala.reflect.api.Modifier + import scala.reflect.api.Modifier._ + + def copypasteModifier(mod: Modifier.Value): String = mod match { + case mod @ ( + `protected` | `private` | `override` | + `abstract` | `final` | `sealed` | + `implicit` | `lazy` | `macro` | + `case` | `trait`) => "`" + mod.toString + "`" + case mod => mod.toString + } + def print(args: Any*): Unit = args foreach { case EmptyTree => print("EmptyTree") @@ -48,10 +62,35 @@ trait TreePrinters { self: Universe => case arg => print(arg) } - print(if (it.hasNext) ", " else ")") + print(if (it.hasNext) ", " else "") } + print(")") if (typesPrinted) print(".setType(", tree.tpe, ")") + case list: List[_] => + print("List(") + val it = list.iterator + while (it.hasNext) { + print(it.next()) + print(if (it.hasNext) ", " else "") + } + print(")") + case mods: Modifiers => + val parts = collection.mutable.ListBuffer[String]() + parts += "Set(" + mods.allModifiers.map{copypasteModifier}.mkString(", ") + ")" + parts += "newTypeName(\"" + mods.privateWithin.toString + "\")" + parts += "List(" + mods.annotations.map{showRaw}.mkString(", ") + ")" + + var keep = 3 + if (keep == 3 && mods.annotations.isEmpty) keep -= 1 + if (keep == 2 && mods.privateWithin == EmptyTypeName) keep -= 1 + if (keep == 1 && mods.allModifiers.isEmpty) keep -= 1 + + print("Modifiers(", parts.take(keep).mkString(", "), ")") + case name: Name => + if (name.isTermName) print("newTermName(\"") else print("newTypeName(\"") + print(name.toString) + print("\")") case arg => out.print(arg) } diff --git a/test/files/run/t5377.check b/test/files/run/t5377.check new file mode 100644 index 0000000000..7bd0e297bf --- /dev/null +++ b/test/files/run/t5377.check @@ -0,0 +1,18 @@ +1 List(1) +1 List(1) +2 List(1, 2) List(2, 1) +2 List(1, 2) List(2, 1) +2 List(2, 1) List(1, 2) +2 List(2, 1) List(1, 2) +3 List(1, 2, 3) List(1, 3, 2) List(2, 1, 3) List(2, 3, 1) List(3, 1, 2) List(3, 2, 1) +3 List(1, 2, 3) List(1, 3, 2) List(2, 1, 3) List(2, 3, 1) List(3, 1, 2) List(3, 2, 1) +3 List(1, 3, 2) List(1, 2, 3) List(3, 1, 2) List(3, 2, 1) List(2, 1, 3) List(2, 3, 1) +3 List(1, 3, 2) List(1, 2, 3) List(3, 1, 2) List(3, 2, 1) List(2, 1, 3) List(2, 3, 1) +3 List(2, 1, 3) List(2, 3, 1) List(1, 2, 3) List(1, 3, 2) List(3, 2, 1) List(3, 1, 2) +3 List(2, 1, 3) List(2, 3, 1) List(1, 2, 3) List(1, 3, 2) List(3, 2, 1) List(3, 1, 2) +3 List(2, 3, 1) List(2, 1, 3) List(3, 2, 1) List(3, 1, 2) List(1, 2, 3) List(1, 3, 2) +3 List(2, 3, 1) List(2, 1, 3) List(3, 2, 1) List(3, 1, 2) List(1, 2, 3) List(1, 3, 2) +3 List(3, 1, 2) List(3, 2, 1) List(1, 3, 2) List(1, 2, 3) List(2, 3, 1) List(2, 1, 3) +3 List(3, 1, 2) List(3, 2, 1) List(1, 3, 2) List(1, 2, 3) List(2, 3, 1) List(2, 1, 3) +3 List(3, 2, 1) List(3, 1, 2) List(2, 3, 1) List(2, 1, 3) List(1, 3, 2) List(1, 2, 3) +3 List(3, 2, 1) List(3, 1, 2) List(2, 3, 1) List(2, 1, 3) List(1, 3, 2) List(1, 2, 3) diff --git a/test/files/run/t5377.scala b/test/files/run/t5377.scala new file mode 100644 index 0000000000..2e8fb1a6af --- /dev/null +++ b/test/files/run/t5377.scala @@ -0,0 +1,47 @@ +object Test { + def testPermutations1(num: Int, stream: Stream[Int]): Unit = { + val perm = stream.permutations + print(num) + while(perm.hasNext) { + print(" " + perm.next().toList) + } + println() + } + def testPermutations2(num: Int, stream: List[Int]): Unit = { + val perm = stream.permutations + print(num) + while(perm.hasNext) { + print(" " + perm.next().toList) + } + println() + } + + def main(args: Array[String]): Unit = { + testPermutations1(1, Stream(1)) + testPermutations2(1, List(1)) + + testPermutations1(2, Stream(1, 2)) + testPermutations2(2, List(1, 2)) + + testPermutations1(2, Stream(2, 1)) + testPermutations2(2, List(2, 1)) + + testPermutations1(3, Stream(1, 2, 3)) + testPermutations2(3, List(1, 2, 3)) + + testPermutations1(3, Stream(1, 3, 2)) + testPermutations2(3, List(1, 3, 2)) + + testPermutations1(3, Stream(2, 1, 3)) + testPermutations2(3, List(2, 1, 3)) + + testPermutations1(3, Stream(2, 3, 1)) + testPermutations2(3, List(2, 3, 1)) + + testPermutations1(3, Stream(3, 1, 2)) + testPermutations2(3, List(3, 1, 2)) + + testPermutations1(3, Stream(3, 2, 1)) + testPermutations2(3, List(3, 2, 1)) + } +} diff --git a/test/files/specialized/spec-hlists.check b/test/files/specialized/spec-hlists.check new file mode 100644 index 0000000000..0ab3339bbc --- /dev/null +++ b/test/files/specialized/spec-hlists.check @@ -0,0 +1,2 @@ +class HCons$mcI$sp +class HCons$mcI$sp diff --git a/test/files/specialized/spec-hlists.scala b/test/files/specialized/spec-hlists.scala new file mode 100644 index 0000000000..8c4ac8f610 --- /dev/null +++ b/test/files/specialized/spec-hlists.scala @@ -0,0 +1,29 @@ +/** Test contributed by Stefan Zeiger showing that HLists can be + * specialized. + */ + +sealed trait HList { + type Self <: HList + + type |: [E] = HCons[E, Self] + + final def |: [@specialized E](elem: E): |: [E] = new HCons[E, Self](elem, this.asInstanceOf[Self]) + + def m[@specialized E, T <: AnyRef](x: E): T = null.asInstanceOf[T] +} + +final class HCons[@specialized H, T <: HList](val head: H, val tail: T) extends HList { + type Self = HCons[H, T] +} + +final object HNil extends HList { + type Self = HNil.type +} + +object Test extends App { + val l1 = new HCons(42, "foo" |: HNil) + println(l1.getClass) + + val l2 = 42 |: "abc" |: HNil + println(l2.getClass) +} |