summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2010-09-28 15:46:41 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2010-09-28 15:46:41 +0000
commit4dc846980edd1fc33a021e4f80b7403c843e1991 (patch)
tree1a6159c00649c803668d625462ddf97d1cd459e5
parent9058008d344442e181b852b65e81da18af0fa800 (diff)
downloadscala-4dc846980edd1fc33a021e4f80b7403c843e1991.tar.gz
scala-4dc846980edd1fc33a021e4f80b7403c843e1991.tar.bz2
scala-4dc846980edd1fc33a021e4f80b7403c843e1991.zip
closes #3859.
review by odersky
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala17
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
-rw-r--r--test/files/pos/t3859.scala4
4 files changed, 17 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 4b5632f7d8..34cc26ee99 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -225,6 +225,8 @@ trait Definitions extends reflect.generic.StandardDefinitions {
lazy val Array_clone = getMember(ArrayClass, nme.clone_)
lazy val ArrayModule = getModule("scala.Array")
+ def isArray_Apply(sym: Symbol): Boolean = sym.owner == ArrayModule.moduleClass && sym.name == nme.apply
+
// reflection / structural types
lazy val SoftReferenceClass = getClass("java.lang.ref.SoftReference")
lazy val WeakReferenceClass = getClass("java.lang.ref.WeakReference")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 392223e1e2..ad39736ba3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -789,7 +789,7 @@ self: Analyzer =>
* reflect.Manifest for type 'tp'. An EmptyTree is returned if
* no manifest is found. todo: make this instantiate take type params as well?
*/
- private def manifestOfType(tp: Type, full: Boolean): Tree = {
+ private def manifestOfType(tp: Type, full: Boolean): SearchResult = {
/** Creates a tree that calls the factory method called constructor in object reflect.Manifest */
def manifestFactoryCall(constructor: String, tparg: Type, args: Tree*): Tree =
@@ -814,8 +814,10 @@ self: Analyzer =>
inferImplicit(tree, appliedType(manifestClass.typeConstructor, List(tp)), true, false, context).tree
def findSubManifest(tp: Type) = findManifest(tp, if (full) FullManifestClass else OptManifestClass)
+ def mot(tp0: Type)(implicit from: List[Symbol] = List(), to: List[Type] = List()): SearchResult = {
+ implicit def wrapResult(tree: Tree): SearchResult =
+ if (tree == EmptyTree) SearchFailure else new SearchResult(tree, new TreeTypeSubstituter(from, to))
- def mot(tp0: Type): Tree = {
val tp1 = tp0.normalize
tp1 match {
case ThisType(_) | SingleType(_, _) if !(tp1 exists {tp => tp.typeSymbol.isExistentiallyBound}) => // can't generate a reference to a value that's abstracted over by an existential
@@ -849,7 +851,7 @@ self: Analyzer =>
manifestFactoryCall("wildcardType", tp,
findManifest(tp.bounds.lo), findManifest(tp.bounds.hi))
} else if(undetParams contains sym) { // looking for a manifest of a type parameter that hasn't been inferred by now, can't do much, but let's not fail
- mot(NothingClass.tpe) // TODO: should we include the mapping from sym -> NothingClass.tpe in the SearchResult? (it'll get instantiated to nothing anyway, I think)
+ mot(NothingClass.tpe)(sym :: from, NothingClass.tpe :: to) // #3859: need to include the mapping from sym -> NothingClass.tpe in the SearchResult
} else {
EmptyTree // a manifest should have been found by normal searchImplicit
}
@@ -875,13 +877,12 @@ self: Analyzer =>
*/
private def implicitManifestOrOfExpectedType(pt: Type): SearchResult = pt.dealias match {
case TypeRef(_, FullManifestClass, List(arg)) =>
- wrapResult(manifestOfType(arg, true))
+ manifestOfType(arg, true)
case TypeRef(_, PartialManifestClass, List(arg)) =>
- wrapResult(manifestOfType(arg, false))
+ manifestOfType(arg, false)
case TypeRef(_, OptManifestClass, List(arg)) =>
- val itree = manifestOfType(arg, false)
- wrapResult(if (itree == EmptyTree) gen.mkAttributedRef(NoManifest)
- else itree)
+ val res = manifestOfType(arg, false)
+ if (res == SearchFailure) wrapResult(gen.mkAttributedRef(NoManifest)) else res
case TypeRef(_, tsym, _) if (tsym.isAbstractType) =>
implicitManifestOrOfExpectedType(pt.bounds.lo)
case _ =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 742f792e84..49e3505946 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2679,7 +2679,7 @@ trait Typers { self: Analyzer =>
// and Array.apply(x: Int, xs: Int*): Array[Int] (and similar)
case Apply(fun, args) =>
val typedFun = typed(fun, funMode(mode), WildcardType)
- if (typedFun.symbol.owner == ArrayModule.moduleClass && typedFun.symbol.name == nme.apply)
+ if (isArray_Apply(typedFun.symbol))
pt match {
case TypeRef(_, ArrayClass, targ :: _) =>
trees2ConstArg(args, targ)
@@ -3404,7 +3404,7 @@ trait Typers { self: Analyzer =>
res.tpe = res.tpe.notNull
}
*/
- if (fun2.symbol == Array_apply) {
+ if (isArray_Apply(fun2.symbol)) {
val checked = gen.mkCheckInit(res)
// this check is needed to avoid infinite recursion in Duplicators
// (calling typed1 more than once for the same tree)
diff --git a/test/files/pos/t3859.scala b/test/files/pos/t3859.scala
new file mode 100644
index 0000000000..83d4c37b29
--- /dev/null
+++ b/test/files/pos/t3859.scala
@@ -0,0 +1,4 @@
+class Test {
+ def foo: Unit = bar(Array(): _*)
+ def bar(values: AnyRef*): Unit = ()
+} \ No newline at end of file