summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2009-11-24 09:09:49 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2009-11-24 09:09:49 +0000
commitc46145f0408b30bbd126d293ccf67792f307479a (patch)
treec36f529ae8272b368f1efb20dce6758a8d4e8a0b
parentef3fb07b53cf4468332461c9d5cf523019bcd9c9 (diff)
downloadscala-c46145f0408b30bbd126d293ccf67792f307479a.tar.gz
scala-c46145f0408b30bbd126d293ccf67792f307479a.tar.bz2
scala-c46145f0408b30bbd126d293ccf67792f307479a.zip
close #2665 and close #2667: use weak conforman...
close #2665 and close #2667: use weak conformance in polymorphic case of isApplicable reviewed by: odersky exprTypeArgs now takes a comparison function: isWeaklyCompatible is ) passed in isApplicable's typesCompatible (to mimic what happens in the ) monomorphic case Martin: please review as this is different from my ) original proposal (that one broke type inference, this one passes all ) tests and does not slow down quick.comp )
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
-rw-r--r--test/files/pos/t2665.scala3
-rw-r--r--test/files/pos/t2667.scala6
4 files changed, 17 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 712d469662..d11f263677 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -496,9 +496,9 @@ trait Infer {
* @param pt ...
* @return ...
*/
- private def exprTypeArgs(tparams: List[Symbol], restpe: Type, pt: Type): List[Type] = {
+ private def exprTypeArgs(tparams: List[Symbol], restpe: Type, pt: Type, checkCompat: (Type, Type) => Boolean = isCompatible): List[Type] = {
val tvars = tparams map freshVar
- if (isCompatible(restpe.instantiateTypeParams(tparams, tvars), pt)) {
+ if (checkCompat(restpe.instantiateTypeParams(tparams, tvars), pt)) {
try {
// If the restpe is an implicit method, and the expected type is fully defined
// optimze type varianbles wrt to the implicit formals only; ignore the result type.
@@ -788,7 +788,8 @@ trait Infer {
try {
val uninstantiated = new ListBuffer[Symbol]
val targs = methTypeArgs(undetparams, formals, restpe, argtpes, pt, uninstantiated)
- (exprTypeArgs(uninstantiated.toList, restpe.instantiateTypeParams(undetparams, targs), pt) ne null) &&
+ // #2665: must use weak conformance, not regular one (follow the monorphic case above)
+ (exprTypeArgs(uninstantiated.toList, restpe.instantiateTypeParams(undetparams, targs), pt, isWeaklyCompatible) ne null) &&
isWithinBounds(NoPrefix, NoSymbol, undetparams, targs)
} catch {
case ex: NoInstance => false
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 1a8db1f27d..c3ca5d7e30 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2148,6 +2148,10 @@ trait Typers { self: Analyzer =>
val pre = fun.symbol.tpe.prefix
var sym = fun.symbol filter { alt =>
+ // must use pt as expected type, not WildcardType (a tempting quick fix to #2665)
+ // now fixed by using isWeaklyCompatible in exprTypeArgs
+ // TODO: understand why exactly -- some types were not inferred anymore (`ant clean quick.bin` failed)
+ // (I had expected inferMethodAlternative to pick up the slack introduced by using WildcardType here)
isApplicableSafe(context.undetparams, followApply(pre.memberType(alt)), argtypes, pt)
}
if (sym hasFlag OVERLOADED) {
diff --git a/test/files/pos/t2665.scala b/test/files/pos/t2665.scala
new file mode 100644
index 0000000000..3163e31326
--- /dev/null
+++ b/test/files/pos/t2665.scala
@@ -0,0 +1,3 @@
+object Test {
+ val x: Unit = Array("")
+} \ No newline at end of file
diff --git a/test/files/pos/t2667.scala b/test/files/pos/t2667.scala
new file mode 100644
index 0000000000..b214cc7f37
--- /dev/null
+++ b/test/files/pos/t2667.scala
@@ -0,0 +1,6 @@
+object A {
+ def foo(x: Int, y: Int*): Int = 45
+ def foo[T](x: T*): Int = 55
+
+ val x: Unit = foo(23, 23f)
+} \ No newline at end of file