@@ -612,18 +612,24 @@ trait Applications extends Compatibility {
612
612
}
613
613
}
614
614
615
+ /** The degree to which an argument has to match a formal parameter */
616
+ enum ArgMatch :
617
+ case SubType // argument is a relaxed subtype of formal
618
+ case Compatible // argument is compatible with formal
619
+ case CompatibleCAP // capture-converted argument is compatible with formal
620
+
615
621
/** Subclass of Application for the cases where we are interested only
616
622
* in a "can/cannot apply" answer, without needing to construct trees or
617
623
* issue error messages.
618
624
*/
619
- abstract class TestApplication [Arg ](methRef : TermRef , funType : Type , args : List [Arg ], resultType : Type , captureWild : Boolean )(using Context )
625
+ abstract class TestApplication [Arg ](methRef : TermRef , funType : Type , args : List [Arg ], resultType : Type , argMatch : ArgMatch )(using Context )
620
626
extends Application [Arg ](methRef, funType, args, resultType) {
621
627
type TypedArg = Arg
622
628
type Result = Unit
623
629
624
630
def applyKind = ApplyKind .Regular
625
631
626
- protected def argOK (arg : TypedArg , formal : Type ): Boolean = argType(arg, formal) match {
632
+ protected def argOK (arg : TypedArg , formal : Type ): Boolean = argType(arg, formal) match
627
633
case ref : TermRef if ref.denot.isOverloaded =>
628
634
// in this case we could not resolve overloading because no alternative
629
635
// matches expected type
@@ -633,15 +639,17 @@ trait Applications extends Compatibility {
633
639
case SAMType (sam) => argtpe <:< sam.toFunctionType(isJava = formal.classSymbol.is(JavaDefined ))
634
640
case _ => false
635
641
}
636
- isCompatible(argtpe, formal)
637
- || ctx.mode.is(Mode .ImplicitsEnabled ) && SAMargOK
638
- || captureWild
639
- && {
640
- val argtpe1 = argtpe.widen
641
- val captured = captureWildcards(argtpe1)
642
- (captured ne argtpe1) && (captured <:< formal.widenExpr)
643
- }
644
- }
642
+ if argMatch == ArgMatch .SubType then
643
+ argtpe relaxed_<:< formal.widenExpr
644
+ else
645
+ isCompatible(argtpe, formal)
646
+ || ctx.mode.is(Mode .ImplicitsEnabled ) && SAMargOK
647
+ || argMatch == ArgMatch .CompatibleCAP
648
+ && {
649
+ val argtpe1 = argtpe.widen
650
+ val captured = captureWildcards(argtpe1)
651
+ (captured ne argtpe1) && isCompatible(captured, formal.widenExpr)
652
+ }
645
653
646
654
/** The type of the given argument */
647
655
protected def argType (arg : Arg , formal : Type ): Type
@@ -661,8 +669,8 @@ trait Applications extends Compatibility {
661
669
/** Subclass of Application for applicability tests with type arguments and value
662
670
* argument trees.
663
671
*/
664
- class ApplicableToTrees (methRef : TermRef , args : List [Tree ], resultType : Type , captureWild : Boolean )(using Context )
665
- extends TestApplication (methRef, methRef.widen, args, resultType, captureWild ) {
672
+ class ApplicableToTrees (methRef : TermRef , args : List [Tree ], resultType : Type , argMatch : ArgMatch )(using Context )
673
+ extends TestApplication (methRef, methRef.widen, args, resultType, argMatch ) {
666
674
def argType (arg : Tree , formal : Type ): Type =
667
675
if untpd.isContextualClosure(arg) && defn.isContextFunctionType(formal) then arg.tpe
668
676
else normalize(arg.tpe, formal)
@@ -672,18 +680,9 @@ trait Applications extends Compatibility {
672
680
def harmonizeArgs (args : List [Tree ]): List [Tree ] = harmonize(args)
673
681
}
674
682
675
- /** Subclass of Application for applicability tests with type arguments and value
676
- * argument trees.
677
- */
678
- class ApplicableToTreesDirectly (methRef : TermRef , args : List [Tree ], resultType : Type )(using Context )
679
- extends ApplicableToTrees (methRef, args, resultType, captureWild = false ) {
680
- override def argOK (arg : TypedArg , formal : Type ): Boolean =
681
- argType(arg, formal) relaxed_<:< formal.widenExpr
682
- }
683
-
684
683
/** Subclass of Application for applicability tests with value argument types. */
685
- class ApplicableToTypes (methRef : TermRef , args : List [Type ], resultType : Type , captureWild : Boolean )(using Context )
686
- extends TestApplication (methRef, methRef, args, resultType, captureWild ) {
684
+ class ApplicableToTypes (methRef : TermRef , args : List [Type ], resultType : Type , argMatch : ArgMatch )(using Context )
685
+ extends TestApplication (methRef, methRef, args, resultType, argMatch ) {
687
686
def argType (arg : Type , formal : Type ): Type = arg
688
687
def treeToArg (arg : Tree ): Type = arg.tpe
689
688
def isVarArg (arg : Type ): Boolean = arg.isRepeatedParam
@@ -1330,39 +1329,32 @@ trait Applications extends Compatibility {
1330
1329
/** Is given method reference applicable to argument trees `args`?
1331
1330
* @param resultType The expected result type of the application
1332
1331
*/
1333
- def isApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type , keepConstraint : Boolean , captureWild : Boolean )(using Context ): Boolean = {
1332
+ def isApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type , keepConstraint : Boolean , argMatch : ArgMatch )(using Context ): Boolean = {
1334
1333
def isApp (using Context ): Boolean =
1335
- new ApplicableToTrees (methRef, args, resultType, captureWild ).success
1334
+ new ApplicableToTrees (methRef, args, resultType, argMatch ).success
1336
1335
if (keepConstraint) isApp else explore(isApp)
1337
1336
}
1338
1337
1339
- /** Is given method reference applicable to argument trees `args` without inferring views
1340
- * or capturing wildcards?
1341
- * @param resultType The expected result type of the application
1342
- */
1343
- def isDirectlyApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type )(using Context ): Boolean =
1344
- explore(new ApplicableToTreesDirectly (methRef, args, resultType).success)
1345
-
1346
1338
/** Is given method reference applicable to argument types `args`?
1347
1339
* @param resultType The expected result type of the application
1348
1340
*/
1349
- def isApplicableMethodRef (methRef : TermRef , args : List [Type ], resultType : Type , captureWild : Boolean )(using Context ): Boolean =
1350
- explore(new ApplicableToTypes (methRef, args, resultType, captureWild ).success)
1341
+ def isApplicableMethodRef (methRef : TermRef , args : List [Type ], resultType : Type , argMatch : ArgMatch )(using Context ): Boolean =
1342
+ explore(new ApplicableToTypes (methRef, args, resultType, argMatch ).success)
1351
1343
1352
1344
/** Is given type applicable to argument trees `args`, possibly after inserting an `apply`?
1353
1345
* @param resultType The expected result type of the application
1354
1346
*/
1355
1347
def isApplicableType (tp : Type , args : List [Tree ], resultType : Type , keepConstraint : Boolean )(using Context ): Boolean =
1356
1348
onMethod(tp, args.nonEmpty) {
1357
- isApplicableMethodRef(_, args, resultType, keepConstraint, captureWild = false )
1349
+ isApplicableMethodRef(_, args, resultType, keepConstraint, ArgMatch . Compatible )
1358
1350
}
1359
1351
1360
1352
/** Is given type applicable to argument types `args`, possibly after inserting an `apply`?
1361
1353
* @param resultType The expected result type of the application
1362
1354
*/
1363
1355
def isApplicableType (tp : Type , args : List [Type ], resultType : Type )(using Context ): Boolean =
1364
1356
onMethod(tp, args.nonEmpty) {
1365
- isApplicableMethodRef(_, args, resultType, captureWild = false )
1357
+ isApplicableMethodRef(_, args, resultType, ArgMatch . Compatible )
1366
1358
}
1367
1359
1368
1360
private def onMethod (tp : Type , followApply : Boolean )(p : TermRef => Boolean )(using Context ): Boolean = tp match {
@@ -1493,9 +1485,9 @@ trait Applications extends Compatibility {
1493
1485
|| {
1494
1486
if tp1.isVarArgsMethod then
1495
1487
tp2.isVarArgsMethod
1496
- && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType , captureWild = false )
1488
+ && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType , ArgMatch . Compatible )
1497
1489
else
1498
- isApplicableMethodRef(alt2, tp1.paramInfos, WildcardType , captureWild = false )
1490
+ isApplicableMethodRef(alt2, tp1.paramInfos, WildcardType , ArgMatch . Compatible )
1499
1491
}
1500
1492
case tp1 : PolyType => // (2)
1501
1493
inContext(ctx.fresh.setExploreTyperState()) {
@@ -1804,7 +1796,7 @@ trait Applications extends Compatibility {
1804
1796
}
1805
1797
1806
1798
def narrowByTypes (alts : List [TermRef ], argTypes : List [Type ], resultType : Type ): List [TermRef ] =
1807
- alts.filterConserve(isApplicableMethodRef(_, argTypes, resultType, captureWild = true ))
1799
+ alts.filterConserve(isApplicableMethodRef(_, argTypes, resultType, ArgMatch . CompatibleCAP ))
1808
1800
1809
1801
/** Normalization steps before checking arguments:
1810
1802
*
@@ -1873,11 +1865,11 @@ trait Applications extends Compatibility {
1873
1865
1874
1866
def narrowByTrees (alts : List [TermRef ], args : List [Tree ], resultType : Type ): List [TermRef ] = {
1875
1867
val alts2 = alts.filterConserve(alt =>
1876
- isDirectlyApplicableMethodRef (alt, args, resultType)
1868
+ isApplicableMethodRef (alt, args, resultType, keepConstraint = false , ArgMatch . SubType )
1877
1869
)
1878
1870
if (alts2.isEmpty && ! ctx.isAfterTyper)
1879
1871
alts.filterConserve(alt =>
1880
- isApplicableMethodRef(alt, args, resultType, keepConstraint = false , captureWild = true )
1872
+ isApplicableMethodRef(alt, args, resultType, keepConstraint = false , ArgMatch . CompatibleCAP )
1881
1873
)
1882
1874
else
1883
1875
alts2
0 commit comments