@@ -1297,7 +1297,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
1297
1297
// # skipped implicit parameters in tp1 - # skipped implicit parameters in tp2
1298
1298
var implicitBalance : Int = 0
1299
1299
1300
- /** Widen the type of synthetic implied methods from the implementation class to the
1300
+ /** Widen the result type of synthetic implied methods from the implementation class to the
1301
1301
* type that's implemented. Example
1302
1302
*
1303
1303
* implied I[X] for T { ... }
@@ -1316,46 +1316,61 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
1316
1316
* objects, since these are anyway taken to be more specific than methods
1317
1317
* (by condition 3a above).
1318
1318
*/
1319
- def widenImplied (tp : Type , alt : TermRef ): Type =
1320
- if (alt.symbol.is(SyntheticImpliedMethod ))
1321
- tp.parents match {
1322
- case Nil => tp
1323
- case ps => ps.reduceLeft(AndType (_, _))
1324
- }
1325
- else tp
1319
+ def widenImplied (tp : Type , alt : TermRef ): Type = tp match {
1320
+ case mt : MethodType if mt.isImplicitMethod =>
1321
+ mt.derivedLambdaType(mt.paramNames, mt.paramInfos, widenImplied(mt.resultType, alt))
1322
+ case pt : PolyType =>
1323
+ pt.derivedLambdaType(pt.paramNames, pt.paramInfos, widenImplied(pt.resultType, alt))
1324
+ case _ =>
1325
+ if (alt.symbol.is(SyntheticImpliedMethod ))
1326
+ tp.parents match {
1327
+ case Nil => tp
1328
+ case ps => ps.reduceLeft(AndType (_, _))
1329
+ }
1330
+ else tp
1331
+ }
1326
1332
1327
1333
/** Drop any implicit parameter section */
1328
- def stripImplicit (tp : Type , alt : TermRef , weight : Int ): Type = tp match {
1334
+ def stripImplicit (tp : Type , weight : Int ): Type = tp match {
1329
1335
case mt : MethodType if mt.isImplicitMethod =>
1330
1336
implicitBalance += mt.paramInfos.length * weight
1331
- widenImplied( resultTypeApprox(mt), alt )
1337
+ resultTypeApprox(mt)
1332
1338
case pt : PolyType =>
1333
- pt.derivedLambdaType(pt.paramNames, pt.paramInfos, stripImplicit(pt.resultType, alt, weight))
1339
+ pt.derivedLambdaType(pt.paramNames, pt.paramInfos, stripImplicit(pt.resultType, weight))
1334
1340
case _ =>
1335
- widenImplied(tp, alt)
1341
+ tp
1336
1342
}
1337
1343
1338
1344
val owner1 = if (alt1.symbol.exists) alt1.symbol.owner else NoSymbol
1339
1345
val owner2 = if (alt2.symbol.exists) alt2.symbol.owner else NoSymbol
1340
1346
val ownerScore = compareOwner(owner1, owner2)
1341
1347
1342
- val tp1 = stripImplicit(alt1.widen, alt1, - 1 )
1343
- val tp2 = stripImplicit(alt2.widen, alt2, + 1 )
1344
- def winsType1 = isAsSpecific(alt1, tp1, alt2, tp2)
1345
- def winsType2 = isAsSpecific(alt2, tp2, alt1, tp1)
1346
-
1347
- overload.println(i " compare( $alt1, $alt2)? $tp1 $tp2 $ownerScore $winsType1 $winsType2" )
1348
+ def compareWithTypes (tp1 : Type , tp2 : Type ) = {
1349
+ def winsType1 = isAsSpecific(alt1, tp1, alt2, tp2)
1350
+ def winsType2 = isAsSpecific(alt2, tp2, alt1, tp1)
1351
+
1352
+ overload.println(i " compare( $alt1, $alt2)? $tp1 $tp2 $ownerScore $winsType1 $winsType2" )
1353
+ if (ownerScore == 1 )
1354
+ if (winsType1 || ! winsType2) 1 else 0
1355
+ else if (ownerScore == - 1 )
1356
+ if (winsType2 || ! winsType1) - 1 else 0
1357
+ else if (winsType1)
1358
+ if (winsType2) 0 else 1
1359
+ else
1360
+ if (winsType2) - 1 else 0
1361
+ }
1348
1362
1349
- def tieBreak = - implicitBalance.signum
1363
+ val fullType1 = widenImplied(alt1.widen, alt1)
1364
+ val fullType2 = widenImplied(alt2.widen, alt2)
1365
+ val strippedType1 = stripImplicit(fullType1, - 1 )
1366
+ val strippedType2 = stripImplicit(fullType2, + 1 )
1350
1367
1351
- if (ownerScore == 1 )
1352
- if (winsType1 || ! winsType2) 1 else tieBreak
1353
- else if (ownerScore == - 1 )
1354
- if (winsType2 || ! winsType1) - 1 else tieBreak
1355
- else if (winsType1)
1356
- if (winsType2) tieBreak else 1
1357
- else
1358
- if (winsType2) - 1 else tieBreak
1368
+ val result = compareWithTypes(strippedType1, strippedType2)
1369
+ if (result != 0 ) result
1370
+ else if (implicitBalance != 0 ) - implicitBalance.signum
1371
+ else if ((strippedType1 `ne` fullType1) || (strippedType2 `ne` fullType2))
1372
+ compareWithTypes(fullType1, fullType2)
1373
+ else 0
1359
1374
}}
1360
1375
1361
1376
def narrowMostSpecific (alts : List [TermRef ])(implicit ctx : Context ): List [TermRef ] = track(" narrowMostSpecific" ) {
0 commit comments