From 4dc846980edd1fc33a021e4f80b7403c843e1991 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 28 Sep 2010 15:46:41 +0000 Subject: closes #3859. review by odersky --- src/compiler/scala/tools/nsc/symtab/Definitions.scala | 2 ++ .../scala/tools/nsc/typechecker/Implicits.scala | 17 +++++++++-------- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 4 ++-- test/files/pos/t3859.scala | 4 ++++ 4 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 test/files/pos/t3859.scala 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 -- cgit v1.2.3