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