@@ -3823,7 +3823,41 @@ object Types {
3823
3823
if (absMems.size == 1 )
3824
3824
absMems.head.info match {
3825
3825
case mt : MethodType if ! mt.isParamDependent =>
3826
- Some (mt)
3826
+ val cls = tp.classSymbol
3827
+
3828
+ // Given a SAM type such as:
3829
+ //
3830
+ // import java.util.function.Function
3831
+ // Function[_ >: String, _ <: Int]
3832
+ //
3833
+ // the single abstract method will have type:
3834
+ //
3835
+ // (x: Function[_ >: String, _ <: Int]#T): Function[_ >: String, _ <: Int]#R
3836
+ //
3837
+ // which is not implementable outside of the scope of Function.
3838
+ //
3839
+ // To avoid this kind of issue, we approximate references to
3840
+ // parameters of the SAM type by their bounds, this way in the
3841
+ // above example we get:
3842
+ //
3843
+ // (x: String): Int
3844
+ val approxParams = new ApproximatingTypeMap {
3845
+ def apply (tp : Type ): Type = tp match {
3846
+ case tp : TypeRef if tp.symbol.is(ClassTypeParam ) && tp.symbol.owner == cls =>
3847
+ tp.info match {
3848
+ case TypeAlias (alias) =>
3849
+ mapOver(alias)
3850
+ case TypeBounds (lo, hi) =>
3851
+ range(atVariance(- variance)(apply(lo)), apply(hi))
3852
+ case _ =>
3853
+ range(defn.NothingType , defn.AnyType ) // should happen only in error cases
3854
+ }
3855
+ case _ =>
3856
+ mapOver(tp)
3857
+ }
3858
+ }
3859
+ val approx = approxParams(mt).asInstanceOf [MethodType ]
3860
+ Some (approx)
3827
3861
case _ =>
3828
3862
None
3829
3863
}
0 commit comments