@@ -3823,7 +3823,41 @@ object Types {
38233823 if (absMems.size == 1 )
38243824 absMems.head.info match {
38253825 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)
38273861 case _ =>
38283862 None
38293863 }
0 commit comments