diff options
author | Lukas Rytz <lukas.rytz@epfl.ch> | 2012-05-23 03:48:50 -0700 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@epfl.ch> | 2012-05-23 03:48:50 -0700 |
commit | 94e5d76fb8632de1b6c34df63cb2bf3f1cd46fe3 (patch) | |
tree | 435af93e0b56b6cf17e8d22b9fdc28b5cc23ccaa /src | |
parent | 0f198a63d2f1a141b43f40f639d5fff8697510d0 (diff) | |
parent | 8de2caa560d2c820269fd30207fdd22dd7e48c6b (diff) | |
download | scala-94e5d76fb8632de1b6c34df63cb2bf3f1cd46fe3.tar.gz scala-94e5d76fb8632de1b6c34df63cb2bf3f1cd46fe3.tar.bz2 scala-94e5d76fb8632de1b6c34df63cb2bf3f1cd46fe3.zip |
Merge pull request #595 from som-snytt/ticket/3761-overload-byname-only
SI-3761: Overload resolution fails on by-name parameter
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 839cdee301..abe77ead9a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -305,9 +305,21 @@ trait Infer { } - def isCompatible(tp: Type, pt: Type): Boolean = { + /** "Compatible" means conforming after conversions. + * "Raising to a thunk" is not implicit; therefore, for purposes of applicability and + * specificity, an arg type `A` is considered compatible with cbn formal parameter type `=>A`. + * For this behavior, the type `pt` must have cbn params preserved; for instance, `formalTypes(removeByName = false)`. + * + * `isAsSpecific` no longer prefers A by testing applicability to A for both m(A) and m(=>A) + * since that induces a tie between m(=>A) and m(=>A,B*) [SI-3761] + */ + private def isCompatible(tp: Type, pt: Type): Boolean = { + def isCompatibleByName(tp: Type, pt: Type): Boolean = pt match { + case TypeRef(_, ByNameParamClass, List(res)) if !isByNameParamType(tp) => isCompatible(tp, res) + case _ => false + } val tp1 = normalize(tp) - (tp1 weak_<:< pt) || isCoercible(tp1, pt) + (tp1 weak_<:< pt) || isCoercible(tp1, pt) || isCompatibleByName(tp, pt) } def isCompatibleArgs(tps: List[Type], pts: List[Type]) = (tps corresponds pts)(isCompatible) @@ -662,7 +674,7 @@ trait Infer { case ExistentialType(tparams, qtpe) => isApplicable(undetparams, qtpe, argtpes0, pt) case MethodType(params, _) => - val formals = formalTypes(params map { _.tpe }, argtpes0.length) + val formals = formalTypes(params map { _.tpe }, argtpes0.length, removeByName = false) def tryTupleApply: Boolean = { // if 1 formal, 1 argtpe (a tuple), otherwise unmodified argtpes0 |