diff options
author | Martin Odersky <odersky@gmail.com> | 2010-04-12 11:52:39 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2010-04-12 11:52:39 +0000 |
commit | cfe47e4b74cc166af31cc130b0830112c46bdc61 (patch) | |
tree | 7716cb0c8cb0179f0b09328779e0c2ac06621025 | |
parent | bed1ffb1c357e09c05ea6a58bd19a75510f1822e (diff) | |
download | scala-cfe47e4b74cc166af31cc130b0830112c46bdc61.tar.gz scala-cfe47e4b74cc166af31cc130b0830112c46bdc61.tar.bz2 scala-cfe47e4b74cc166af31cc130b0830112c46bdc61.zip |
Closes #3224. Review by retronym.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 15 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 6 | ||||
-rw-r--r-- | test/files/neg/t3224.check | 6 | ||||
-rwxr-xr-x | test/files/neg/t3224.scala | 30 |
4 files changed, 52 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index c0b54cb4f0..c8d3308077 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -802,6 +802,14 @@ trait Infer { (argtpes1, argPos, namesOK) } + /** don't do a () to (()) conversion for methods whose second parameter + * is a varargs. This is a fairly kludgey way to address #3224. + * We'll probably find a better way to do this by identifying + * tupled and n-ary methods, but thiws is something for a future major revision. + */ + def isUnitForVarArgs(args: List[AnyRef], params: List[Symbol]): Boolean = + args.length == 0 && params.length == 2 && isVarArgs(params) + /** Is there an instantiation of free type variables <code>undetparams</code> * such that function type <code>ftpe</code> is applicable to * <code>argtpes</code> and its result conform to <code>pt</code>? @@ -833,14 +841,15 @@ trait Infer { def tryTupleApply: Boolean = { // if 1 formal, 1 argtpe (a tuple), otherwise unmodified argtpes0 - val tupleArgTpe = actualTypes(argtpes0 map { + val tupleArgTpes = actualTypes(argtpes0 map { // no assignment is treated as named argument here case NamedType(name, tp) => UnitClass.tpe case tp => tp }, formals.length) - argtpes0.length != tupleArgTpe.length && - isApplicable(undetparams, ftpe, tupleArgTpe, pt) + argtpes0.length != tupleArgTpes.length && + !isUnitForVarArgs(argtpes0, params) && + isApplicable(undetparams, ftpe, tupleArgTpes, pt) } def typesCompatible(argtpes: List[Type]) = { val restpe = ftpe.resultType(argtpes) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 284b12e501..3fe937f241 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2327,12 +2327,14 @@ trait Typers { self: Analyzer => // if 1 formal, 1 arg (a tuple), otherwise unmodified args val tupleArgs = actualArgs(tree.pos.makeTransparent, args, formals.length) - if (tupleArgs.length != args.length) { + if (tupleArgs.length != args.length && !isUnitForVarArgs(args, params)) { // expected one argument, but got 0 or >1 ==> try applying to tuple // the inner "doTypedApply" does "extractUndetparams" => restore when it fails val savedUndetparams = context.undetparams silent(_.doTypedApply(tree, fun, tupleArgs, mode, pt)) match { - case t: Tree => Some(t) + case t: Tree => +// println("tuple conversion to "+t+" for "+mt)//DEBUG + Some(t) case ex => context.undetparams = savedUndetparams None diff --git a/test/files/neg/t3224.check b/test/files/neg/t3224.check new file mode 100644 index 0000000000..de196f15be --- /dev/null +++ b/test/files/neg/t3224.check @@ -0,0 +1,6 @@ +/home/odersky/workspace/scala/test/files/neg/t3224.scala:29: error: polymorphic expression cannot be instantiated to expected type; + found : [T]Array[T] + required: List[?] + println(Texts textL Array()); println(Texts textL Array(1)); println(Texts textL Array(1, 1)) + ^ +one error found diff --git a/test/files/neg/t3224.scala b/test/files/neg/t3224.scala new file mode 100755 index 0000000000..0e24baf28a --- /dev/null +++ b/test/files/neg/t3224.scala @@ -0,0 +1,30 @@ +object Texts{ + def textL[T](list: List[T]) = { + list match{ + case List() => "Empty" + case List(_) => "One" + case List(_*) => "Many" + } + } + + def textA[T](array: Array[T]) = { + array match{ + case Array() => "Empty" + case Array(_) => "One" + case Array(_*) => "Many" + } + } +} + +object Test extends Application { + + implicit def array2list[T](array: Array[T]) = { + println(array.toList.size) + array.toList + } + + + println(Texts textL List()); println(Texts textL List(1)); println(Texts textL List(1, 1)); + + println(Texts textL Array()); println(Texts textL Array(1)); println(Texts textL Array(1, 1)) +} |