From 820e0bd94001e2732b119d217a12844e4720d165 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 13 Oct 2009 15:39:22 +0000 Subject: Fixed #2422 abd #2461 --- src/compiler/scala/tools/nsc/Global.scala | 2 +- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 2 +- .../scala/tools/nsc/transform/UnCurry.scala | 14 ++++++++---- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- test/files/pos/arrays2.scala | 12 +++++++++++ test/files/run/t493.scala | 22 +++++++++++++++++++ test/pending/neg/t1477.scala | 25 ++++++++++++++++++++++ 7 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 test/files/run/t493.scala create mode 100644 test/pending/neg/t1477.scala diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 7a6d53b5fb..bcf81c56e6 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -63,7 +63,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable val global: Global.this.type = Global.this } with TreeGen { def mkAttributedCast(tree: Tree, pt: Type): Tree = - typer.typed(mkAttributedCastUntyped(tree, pt)) + typer.typed(mkCast(tree, pt)) } /** Fold constants */ diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index dfa813b20f..89762ce258 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -131,7 +131,7 @@ abstract class TreeGen } /** Cast `tree' to type `pt' */ - def mkAttributedCastUntyped(tree: Tree, pt: Type): Tree = { + def mkCast(tree: Tree, pt: Type): Tree = { if (settings.debug.value) log("casting " + tree + ":" + tree.tpe + " to " + pt) assert(!tree.tpe.isInstanceOf[MethodType], tree) assert(!pt.typeSymbol.isPackageClass) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 12711a36c6..a0afdeabaf 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -392,7 +392,9 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { Select(predef, "wrap"+elemtp.typeSymbol.name+"Array") else TypeApply(Select(predef, "genericWrapArray"), List(TypeTree(elemtp))) - Apply(meth, List(tree)) + val adaptedTree = // need to cast to Array[elemtp], as arrays are not covariant + gen.mkCast(tree, arrayType(elemtp)) + Apply(meth, List(adaptedTree)) } } } @@ -401,11 +403,15 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { def sequenceToArray(tree: Tree) = { val toArraySym = tree.tpe member nme.toArray assert(toArraySym != NoSymbol) + def getManifest(tp: Type): Tree = { + val manifestOpt = localTyper.findManifest(tp, false) + if (!manifestOpt.tree.isEmpty) manifestOpt.tree + else if (tp.bounds.hi ne tp) getManifest(tp.bounds.hi) + else localTyper.getManifestTree(tree.pos, tp, false) + } atPhase(phase.next) { localTyper.typedPos(pos) { - Apply( - gen.mkAttributedSelect(tree, toArraySym), - List(localTyper.getManifestTree(tree.pos, tree.tpe.typeArgs.head, false))) + Apply(gen.mkAttributedSelect(tree, toArraySym), List(getManifest(tree.tpe.typeArgs.head))) } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 7c09df68d3..ebcd18082d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3946,7 +3946,7 @@ trait Typers { self: Analyzer => } def getManifestTree(pos: Position, tp: Type, full: Boolean): Tree = { - val manifestOpt = findManifest(tp, false) + val manifestOpt = findManifest(tp, full) if (manifestOpt.tree.isEmpty) { error(pos, "cannot find "+(if (full) "" else "class ")+"manifest for element type "+tp) Literal(Constant(null)) diff --git a/test/files/pos/arrays2.scala b/test/files/pos/arrays2.scala index 6f4a09a401..795c486e37 100644 --- a/test/files/pos/arrays2.scala +++ b/test/files/pos/arrays2.scala @@ -9,3 +9,15 @@ object arrays2 { } } +// #2422 +object arrays4 { + val args = Array[String]("World") + "Hello %1$s".format(args: _*) +} + +// #2461 +object arrays3 { + import scala.collection.JavaConversions._ + def apply[X](xs : X*) : java.util.List[X] = java.util.Arrays.asList(xs: _*) +} + diff --git a/test/files/run/t493.scala b/test/files/run/t493.scala new file mode 100644 index 0000000000..7aaad1fece --- /dev/null +++ b/test/files/run/t493.scala @@ -0,0 +1,22 @@ +object Test { + + val y = new collection.mutable.HashMap[String,Any] + val z = new collection.mutable.HashMap[String,Any] + + y("msg") = Array[String]("1","2") + + val array: Array[String] = Array[String]("1","2") + z("msg") = array + + def main(args:Array[String]) = { + + assert(y("msg").isInstanceOf[Array[_]]) + assert(z("msg").isInstanceOf[Array[_]]) + + // these work, without producing a match error + + (z.get("msg"): @unchecked) match { + case Some(_:Array[String]) => + } + } +} diff --git a/test/pending/neg/t1477.scala b/test/pending/neg/t1477.scala new file mode 100644 index 0000000000..0cc0cd5f7a --- /dev/null +++ b/test/pending/neg/t1477.scala @@ -0,0 +1,25 @@ +object Test extends Application { + trait A + trait B extends A + + trait C { + type U + trait D { type T >: B <: A } + type V <: D + val y: V#T = new B { } + } + + trait Middle extends C { + type V <: (D with U) + } + + class D extends Middle { + trait E + trait F { type T = E } + type U = F + def frob(arg : E) : E = arg + frob(y) + } + + new D +} -- cgit v1.2.3