summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2010-07-08 15:59:10 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2010-07-08 15:59:10 +0000
commit27cdc8ab7f0d688a8fa81dffae2e1b26ac342edb (patch)
tree590766e20b6c20494b927d3cfa690e211d77b03d
parent68aeeae4229a04a8d9d2235e160fd00b21e20926 (diff)
downloadscala-27cdc8ab7f0d688a8fa81dffae2e1b26ac342edb.tar.gz
scala-27cdc8ab7f0d688a8fa81dffae2e1b26ac342edb.tar.bz2
scala-27cdc8ab7f0d688a8fa81dffae2e1b26ac342edb.zip
closes #3477.
note that all type parameters must be reported in error messages about failing type inference, but only type parameters that were inferred successfully should be substituted the idea of mapping type parameter symbols to the corresponding type ref in order to make substitution the identity does not seem to work, leading to errors like: src/library/scala/collection/immutable/SortedMap.scala:38: error: type mismatch; found : scala.collection.immutable.SortedMap[A,B(in method empty)] required: scala.collection.immutable.SortedMap[A,B(in trait SortedMap)] override def empty: SortedMap[A, B] = SortedMap.empty ^ (I guess that's why they were retracted before, but that wasn't done consistently, leading to #3152 -- my first attempt at fixing the latter lead to this bug... I've assigned #3152 to you Martin, as I can't decide how to fix it.) review by odersky
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala15
-rw-r--r--test/files/pos/t3477.scala7
2 files changed, 15 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 1993a8c23f..2f07fcd306 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -590,7 +590,7 @@ trait Infer {
* @throws NoInstance
*/
def methTypeArgs(tparams: List[Symbol], formals: List[Type], restpe: Type,
- argtpes: List[Type], pt: Type): (List[Symbol], List[Type], List[Symbol]) = {
+ argtpes: List[Type], pt: Type): (List[Type], (List[Symbol], List[Type], List[Symbol])) = { // AM: yes, this result type is evil
val tvars = tparams map freshVar
if (inferInfo)
println("methTypeArgs tparams = "+tparams+
@@ -642,7 +642,7 @@ trait Infer {
val targs = solvedTypes(tvars, tparams, tparams map varianceInTypes(formals),
false, lubDepth(formals) max lubDepth(argtpes))
// val res =
- adjustTypeArgs(tparams, targs, restpe)
+ (targs, adjustTypeArgs(tparams, targs, restpe))
// println("meth type args "+", tparams = "+tparams+", formals = "+formals+", restpe = "+restpe+", argtpes = "+argtpes+", underlying = "+(argtpes map (_.widen))+", pt = "+pt+", uninstantiated = "+uninstantiated.toList+", result = "+res) //DEBUG
// res
}
@@ -764,7 +764,7 @@ trait Infer {
isCompatibleArgs(argtpes, formals) && isWeaklyCompatible(restpe, pt)
} else {
try {
- val (okparams, okargs, leftUndet) = methTypeArgs(undetparams, formals, restpe, argtpes, pt)
+ val (_, (okparams, okargs, leftUndet)) = methTypeArgs(undetparams, formals, restpe, argtpes, pt)
// #2665: must use weak conformance, not regular one (follow the monomorphic case above)
(exprTypeArgs(leftUndet, restpe.instantiateTypeParams(okparams, okargs), pt, isWeaklyCompatible) ne null) &&
isWithinBounds(NoPrefix, NoSymbol, okparams, okargs)
@@ -1201,14 +1201,15 @@ trait Infer {
}
}
- /** Substitite free type variables <code>undetparams</code> of application
+ /** Substitute free type variables <code>undetparams</code> of application
* <code>fn(args)</code>, given prototype <code>pt</code>.
*
* @param fn ...
* @param undetparams ...
* @param args ...
* @param pt ...
- * @return Return the list of type parameters that remain uninstantiated.
+ * @return The type parameters that remain uninstantiated,
+ * and that thus have not been substituted.
*/
def inferMethodInstance(fn: Tree, undetparams: List[Symbol],
args: List[Tree], pt0: Type): List[Symbol] = fn.tpe match {
@@ -1223,8 +1224,8 @@ trait Infer {
val formals = formalTypes(params0 map (_.tpe), args.length)
val argtpes = actualTypes(args map (_.tpe.deconst), formals.length)
val restpe = fn.tpe.resultType(argtpes)
- val (okparams, okargs, leftUndet) = methTypeArgs(undetparams, formals, restpe, argtpes, pt)
- checkBounds(fn.pos, NoPrefix, NoSymbol, okparams, okargs, "inferred ")
+ val (allargs, (okparams, okargs, leftUndet)) = methTypeArgs(undetparams, formals, restpe, argtpes, pt)
+ checkBounds(fn.pos, NoPrefix, NoSymbol, undetparams, allargs, "inferred ")
val treeSubst = new TreeTypeSubstituter(okparams, okargs)
treeSubst.traverse(fn)
treeSubst.traverseTrees(args)
diff --git a/test/files/pos/t3477.scala b/test/files/pos/t3477.scala
new file mode 100644
index 0000000000..660aa55736
--- /dev/null
+++ b/test/files/pos/t3477.scala
@@ -0,0 +1,7 @@
+class J3 {
+ def f[K, K1 >: K, V](x: Map[K1, V]): Map[K, V] = error("")
+}
+
+object Test {
+ (new J3).f(Map[Int, Int]())
+} \ No newline at end of file