Skip to content

Commit 1d22ee4

Browse files
committed
SI-10194: Fix abstract type resolution for overloaded HOFs
Types in the applicable overload alternatives need to be seen from the respective owners of the individual alternative, not from the target’s owner (which can be a subtype of the types that define the methods).
1 parent c8b8005 commit 1d22ee4

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,15 +3333,15 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
33333333
def handleOverloaded = {
33343334
val undetparams = context.undetparams
33353335

3336-
def funArgTypes(tps: List[Type]) = tps.map { tp =>
3337-
val relTp = tp.asSeenFrom(pre, fun.symbol.owner)
3336+
def funArgTypes(tpAlts: List[(Type, Symbol)]) = tpAlts.map { case (tp, alt) =>
3337+
val relTp = tp.asSeenFrom(pre, alt.owner)
33383338
val argTps = functionOrSamArgTypes(relTp)
33393339
//println(s"funArgTypes $argTps from $relTp")
33403340
argTps.map(approximateAbstracts)
33413341
}
33423342

3343-
def functionProto(argTps: List[Type]): Type =
3344-
try functionType(funArgTypes(argTps).transpose.map(lub), WildcardType)
3343+
def functionProto(argTpWithAlt: List[(Type, Symbol)]): Type =
3344+
try functionType(funArgTypes(argTpWithAlt).transpose.map(lub), WildcardType)
33453345
catch { case _: IllegalArgumentException => WildcardType }
33463346

33473347
// To propagate as much information as possible to typedFunction, which uses the expected type to
@@ -3355,21 +3355,21 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
33553355
// do not receive special treatment: they are typed under WildcardType.)
33563356
val altArgPts =
33573357
if (settings.isScala212 && args.exists(treeInfo.isFunctionMissingParamType))
3358-
try alts.map(alt => formalTypes(alt.info.paramTypes, argslen)).transpose // do least amount of work up front
3358+
try alts.map(alt => formalTypes(alt.info.paramTypes, argslen).map(ft => (ft, alt))).transpose // do least amount of work up front
33593359
catch { case _: IllegalArgumentException => args.map(_ => Nil) } // fail safe in case formalTypes fails to align to argslen
33603360
else args.map(_ => Nil) // will type under argPt == WildcardType
33613361

33623362
val (args1, argTpes) = context.savingUndeterminedTypeParams() {
33633363
val amode = forArgMode(fun, mode)
33643364

3365-
map2(args, altArgPts) { (arg, argPts) =>
3365+
map2(args, altArgPts) { (arg, argPtAlts) =>
33663366
def typedArg0(tree: Tree) = {
33673367
// if we have an overloaded HOF such as `(f: Int => Int)Int <and> (f: Char => Char)Char`,
33683368
// and we're typing a function like `x => x` for the argument, try to collapse
33693369
// the overloaded type into a single function type from which `typedFunction`
33703370
// can derive the argument type for `x` in the function literal above
33713371
val argPt =
3372-
if (argPts.nonEmpty && treeInfo.isFunctionMissingParamType(tree)) functionProto(argPts)
3372+
if (argPtAlts.nonEmpty && treeInfo.isFunctionMissingParamType(tree)) functionProto(argPtAlts)
33733373
else WildcardType
33743374

33753375
val argTyped = typedArg(tree, amode, BYVALmode, argPt)

test/files/pos/overloaded_ho_fun.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,18 @@ object sorting {
4949
// def andThen[C](g: Bijection[B, C]): Bijection[A, C] = ???
5050
// def compose[T](g: Bijection[T, A]) = g andThen this
5151
// }
52+
53+
object SI10194 {
54+
trait X[A] {
55+
def map[B](f: A => B): Unit
56+
}
57+
58+
trait Y[A] extends X[A] {
59+
def map[B](f: A => B)(implicit ordering: Ordering[B]): Unit
60+
}
61+
62+
trait Z[A] extends Y[A]
63+
64+
(null: Y[Int]).map(x => x.toString) // compiled
65+
(null: Z[Int]).map(x => x.toString) // didn't compile
66+
}

0 commit comments

Comments
 (0)