@@ -916,6 +916,8 @@ final class Analyzer(config: CommonPhaseConfig, initial: Boolean,
916
916
private def computeMostSpecificProxyMatch (candidates : List [MethodInfo ])(
917
917
implicit from : From ): Future [MethodInfo ] = {
918
918
919
+ implicit val ec = workTracker.ec
920
+
919
921
/* From the JavaDoc of java.lang.Class.getMethod:
920
922
*
921
923
* If more than one [candidate] method is found in C, and one of these
@@ -924,31 +926,36 @@ final class Analyzer(config: CommonPhaseConfig, initial: Boolean,
924
926
* chosen arbitrarily.
925
927
*/
926
928
927
- val resultTypes = candidates.map(c => c.methodName.resultTypeRef)
929
+ def ifMostSpecific (candidate : MethodInfo ): Future [Option [MethodInfo ]] = {
930
+ val specificityChecks = for {
931
+ otherCandidate <- candidates
932
+ if candidate != otherCandidate
933
+ } yield {
934
+ isMoreSpecific(otherCandidate.methodName.resultTypeRef,
935
+ candidate.methodName.resultTypeRef)
936
+ }
928
937
929
- // We must not use Future.traverse since otherwise we might run things on
930
- // the non-main thread.
931
- val specificityChecks = resultTypes.map { x =>
932
- for (y <- resultTypes if x != y)
933
- yield isMoreSpecific(y, x)
938
+ for {
939
+ moreSpecific <- Future .find(specificityChecks)(identity)
940
+ } yield {
941
+ if (moreSpecific.isEmpty) Some (candidate)
942
+ else None
943
+ }
934
944
}
935
945
936
- // Starting here, we just do data juggling, so it can run on any thread.
937
- locally {
938
- implicit val iec = workTracker.ec
946
+ val specificCandidates = candidates.map(ifMostSpecific)
939
947
940
- val hasMoreSpecific = Future .traverse(specificityChecks)(
941
- checks => Future .sequence(checks).map(_.contains(true )))
942
-
943
- hasMoreSpecific.map { hms =>
944
- val targets = candidates.zip(hms).filterNot(_._2).map(_._1)
945
-
946
- /* This last step (chosen arbitrarily) causes some soundness issues of
947
- * the implementation of reflective calls. This is bug-compatible with
948
- * Scala/JVM.
949
- */
950
- targets.head
951
- }
948
+ /* This last step (chosen arbitrarily) causes some soundness issues of
949
+ * the implementation of reflective calls. This is bug-compatible with
950
+ * Scala/JVM.
951
+ */
952
+ for {
953
+ candidate <- Future .find(specificCandidates)(_.nonEmpty)
954
+ } yield {
955
+ /* First get: There must be a most specific candidate.
956
+ * Second get: That's our find condition from above.
957
+ */
958
+ candidate.get.get
952
959
}
953
960
}
954
961
0 commit comments