diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-09-28 15:46:41 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-09-28 15:46:41 +0000 |
commit | 4dc846980edd1fc33a021e4f80b7403c843e1991 (patch) | |
tree | 1a6159c00649c803668d625462ddf97d1cd459e5 | |
parent | 9058008d344442e181b852b65e81da18af0fa800 (diff) | |
download | scala-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.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 4 | ||||
-rw-r--r-- | test/files/pos/t3859.scala | 4 |
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 |