diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-07-08 15:59:10 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-07-08 15:59:10 +0000 |
commit | 27cdc8ab7f0d688a8fa81dffae2e1b26ac342edb (patch) | |
tree | 590766e20b6c20494b927d3cfa690e211d77b03d | |
parent | 68aeeae4229a04a8d9d2235e160fd00b21e20926 (diff) | |
download | scala-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.scala | 15 | ||||
-rw-r--r-- | test/files/pos/t3477.scala | 7 |
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 |