@@ -79,6 +79,8 @@ object Typer {
79
79
* search was tried on a tree. This will in some cases be reported in error messages
80
80
*/
81
81
private [typer] val HiddenSearchFailure = new Property .Key [SearchFailure ]
82
+
83
+ val isBounds : Type => Boolean = _.isInstanceOf [TypeBounds ]
82
84
}
83
85
84
86
class Typer extends Namer
@@ -1917,7 +1919,7 @@ class Typer extends Namer
1917
1919
val elemTpes = (elems, pts).zipped.map((elem, pt) =>
1918
1920
ctx.typeComparer.widenInferred(elem.tpe, pt))
1919
1921
val resTpe = (elemTpes :\ (defn.UnitType : Type ))(defn.PairType .appliedTo(_, _))
1920
- app1.asInstance (resTpe)
1922
+ app1.cast (resTpe)
1921
1923
}
1922
1924
}
1923
1925
}
@@ -2697,10 +2699,47 @@ class Typer extends Namer
2697
2699
case tree : Closure => cpy.Closure (tree)(tpt = TypeTree (pt)).withType(pt)
2698
2700
}
2699
2701
2702
+ /** Replace every top-level occurrence of a wildcard type argument by
2703
+ * a skolem type
2704
+ */
2705
+ def captureWildcards (tp : Type )(implicit ctx : Context ): Type = tp match {
2706
+ case tp : AndOrType => tp.derivedAndOrType(captureWildcards(tp.tp1), captureWildcards(tp.tp2))
2707
+ case tp : RefinedType => tp.derivedRefinedType(captureWildcards(tp.parent), tp.refinedName, tp.refinedInfo)
2708
+ case tp : RecType => tp.derivedRecType(captureWildcards(tp.parent))
2709
+ case tp : LazyRef => captureWildcards(tp.ref)
2710
+ case tp : AnnotatedType => tp.derivedAnnotatedType(captureWildcards(tp.parent), tp.annot)
2711
+ case tp @ AppliedType (tycon, args) if args.exists(isBounds) =>
2712
+ tycon.typeParams match {
2713
+ case tparams @ ((_ : Symbol ) :: _) =>
2714
+ val args1 = args.map {
2715
+ case TypeBounds (lo, hi) =>
2716
+ val skolem = SkolemType (defn.TypeBoxType .appliedTo(lo, hi))
2717
+ TypeRef (skolem, defn.TypeBox_CAP )
2718
+ case arg => arg
2719
+ }
2720
+ val boundss = tparams.map(_.paramInfo.subst(tparams.asInstanceOf [List [TypeSymbol ]], args1))
2721
+ for ((newArg, oldArg, bounds) <- (args1, args, boundss).zipped)
2722
+ if (newArg `ne` oldArg) {
2723
+ val TypeRef (skolem @ SkolemType (app @ AppliedType (typeBox, lo :: hi :: Nil )), _) = newArg
2724
+ skolem.info = app.derivedAppliedType(
2725
+ typeBox, (lo | bounds.loBound) :: (hi & bounds.hiBound) :: Nil )
2726
+ }
2727
+ tp.derivedAppliedType(tycon, args1)
2728
+ case _ =>
2729
+ tp
2730
+ }
2731
+ case _ => tp
2732
+ }
2733
+
2700
2734
def adaptToSubType (wtp : Type ): Tree = {
2701
2735
// try converting a constant to the target type
2702
2736
val folded = ConstFold (tree, pt)
2703
2737
if (folded ne tree) return adaptConstant(folded, folded.tpe.asInstanceOf [ConstantType ])
2738
+
2739
+ // Try to capture wildcards in type
2740
+ val captured = captureWildcards(wtp)
2741
+ if (captured `ne` wtp) return readapt(tree.cast(captured))
2742
+
2704
2743
// drop type if prototype is Unit
2705
2744
if (pt isRef defn.UnitClass ) {
2706
2745
// local adaptation makes sure every adapted tree conforms to its pt
@@ -2709,6 +2748,7 @@ class Typer extends Namer
2709
2748
checkStatementPurity(tree1)(tree, ctx.owner)
2710
2749
return tpd.Block (tree1 :: Nil , Literal (Constant (())))
2711
2750
}
2751
+
2712
2752
// convert function literal to SAM closure
2713
2753
tree match {
2714
2754
case closure(Nil , id @ Ident (nme.ANON_FUN ), _)
@@ -2725,6 +2765,7 @@ class Typer extends Namer
2725
2765
}
2726
2766
case _ =>
2727
2767
}
2768
+
2728
2769
// try an extension method in scope
2729
2770
pt match {
2730
2771
case SelectionProto (name, mbrType, _, _) =>
@@ -2749,6 +2790,7 @@ class Typer extends Namer
2749
2790
}
2750
2791
case _ =>
2751
2792
}
2793
+
2752
2794
// try an implicit conversion
2753
2795
val prevConstraint = ctx.typerState.constraint
2754
2796
def recover (failure : SearchFailureType ) =
0 commit comments