@@ -1364,7 +1364,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
1364
1364
* Two trials: First, without implicits or SAM conversions enabled. Then,
1365
1365
* if the fist finds no eligible candidates, with implicits and SAM conversions enabled.
1366
1366
*/
1367
- def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] = track(" resolveOverloaded" ) {
1367
+ def resolveOverloaded (alts : List [TermRef ], pt : Type , pos : Position = NoPosition )(implicit ctx : Context ): List [TermRef ] = track(" resolveOverloaded" ) {
1368
1368
1369
1369
/** Is `alt` a method or polytype whose result type after the first value parameter
1370
1370
* section conforms to the expected type `resultType`? If `resultType`
@@ -1409,9 +1409,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
1409
1409
case _ => chosen
1410
1410
}
1411
1411
1412
- var found = resolveOverloaded(alts, pt, Nil )(ctx.retractMode(Mode .ImplicitsEnabled ))
1412
+ var found = resolveOverloaded(alts, pt, Nil , pos )(ctx.retractMode(Mode .ImplicitsEnabled ))
1413
1413
if (found.isEmpty && ctx.mode.is(Mode .ImplicitsEnabled ))
1414
- found = resolveOverloaded(alts, pt, Nil )
1414
+ found = resolveOverloaded(alts, pt, Nil , pos )
1415
1415
found match {
1416
1416
case alt :: Nil => adaptByResult(alt) :: Nil
1417
1417
case _ => found
@@ -1423,7 +1423,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
1423
1423
* called twice from the public `resolveOverloaded` method, once with
1424
1424
* implicits and SAM conversions enabled, and once without.
1425
1425
*/
1426
- private def resolveOverloaded (alts : List [TermRef ], pt : Type , targs : List [Type ])(implicit ctx : Context ): List [TermRef ] = track(" resolveOverloaded" ) {
1426
+ private def resolveOverloaded (alts : List [TermRef ], pt : Type , targs : List [Type ], pos : Position )(implicit ctx : Context ): List [TermRef ] = track(" resolveOverloaded" ) {
1427
1427
1428
1428
def isDetermined (alts : List [TermRef ]) = alts.isEmpty || alts.tail.isEmpty
1429
1429
@@ -1511,19 +1511,27 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
1511
1511
1512
1512
case pt @ PolyProto (targs1, pt1) if targs.isEmpty =>
1513
1513
val alts1 = alts filter pt.isMatchedBy
1514
- resolveOverloaded(alts1, pt1, targs1.tpes)
1514
+ resolveOverloaded(alts1, pt1, targs1.tpes, pos )
1515
1515
1516
1516
case defn.FunctionOf (args, resultType, _, _) =>
1517
1517
narrowByTypes(alts, args, resultType)
1518
1518
1519
1519
case pt =>
1520
1520
val noSam = alts filter (normalizedCompatible(_, pt))
1521
1521
if (noSam.isEmpty) {
1522
+ /*
1523
+ * the case should not be moved to the enclosing match
1524
+ * since SAM type must be considered only if there are no candidates
1525
+ * For example, the second f should be chosen for the following code:
1526
+ * def f(x: String): Unit = ???
1527
+ * def f: java.io.OutputStream = ???
1528
+ * new java.io.ObjectOutputStream(f)
1529
+ */
1522
1530
pt match {
1523
1531
case SAMType (mtp) =>
1524
1532
val sam = narrowByTypes(alts, mtp.paramInfos, mtp.resultType)
1525
1533
if (sam.nonEmpty && ! pt.classSymbol.hasAnnotation(defn.FunctionalInterfaceAnnot ))
1526
- ctx.warning(ex " $pt does not have the @FunctionalInterface annotation. " , ctx.tree. pos)
1534
+ ctx.warning(ex " ${sam.head.designator} is eta-expanded even though $ pt does not have the @FunctionalInterface annotation. " , pos)
1527
1535
sam
1528
1536
case _ => noSam
1529
1537
}
@@ -1536,7 +1544,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
1536
1544
if (noDefaults.length == 1 ) noDefaults // return unique alternative without default parameters if it exists
1537
1545
else {
1538
1546
val deepPt = pt.deepenProto
1539
- if (deepPt ne pt) resolveOverloaded(alts, deepPt, targs)
1547
+ if (deepPt ne pt) resolveOverloaded(alts, deepPt, targs, pos )
1540
1548
else alts
1541
1549
}
1542
1550
}
0 commit comments