@@ -2698,46 +2698,26 @@ class Typer extends Namer
2698
2698
case tree : Closure => cpy.Closure (tree)(tpt = TypeTree (pt)).withType(pt)
2699
2699
}
2700
2700
2701
- /** Replace every top-level occurrence of a wildcard type argument by
2702
- * a skolem type
2703
- */
2704
- def captureWildcards (tp : Type )(implicit ctx : Context ): Type = tp match {
2705
- case tp : AndOrType => tp.derivedAndOrType(captureWildcards(tp.tp1), captureWildcards(tp.tp2))
2706
- case tp : RefinedType => tp.derivedRefinedType(captureWildcards(tp.parent), tp.refinedName, tp.refinedInfo)
2707
- case tp : RecType => tp.derivedRecType(captureWildcards(tp.parent))
2708
- case tp : LazyRef => captureWildcards(tp.ref)
2709
- case tp : AnnotatedType => tp.derivedAnnotatedType(captureWildcards(tp.parent), tp.annot)
2710
- case tp @ AppliedType (tycon, args) if tp.hasWildcardArg =>
2711
- tycon.typeParams match {
2712
- case tparams @ ((_ : Symbol ) :: _) =>
2713
- val args1 = args.map {
2714
- case TypeBounds (lo, hi) =>
2715
- val skolem = SkolemType (defn.TypeBoxType .appliedTo(lo, hi))
2716
- TypeRef (skolem, defn.TypeBox_CAP )
2717
- case arg => arg
2718
- }
2719
- val boundss = tparams.map(_.paramInfo.subst(tparams.asInstanceOf [List [TypeSymbol ]], args1))
2720
- for ((newArg, oldArg, bounds) <- (args1, args, boundss).zipped)
2721
- if (newArg `ne` oldArg) {
2722
- val TypeRef (skolem @ SkolemType (app @ AppliedType (typeBox, lo :: hi :: Nil )), _) = newArg
2723
- skolem.info = app.derivedAppliedType(
2724
- typeBox, (lo | bounds.loBound) :: (hi & bounds.hiBound) :: Nil )
2725
- }
2726
- tp.derivedAppliedType(tycon, args1)
2727
- case _ =>
2728
- tp
2729
- }
2730
- case _ => tp
2701
+ def hasWildcardArg (tp : Type ): Boolean = tp match {
2702
+ case tp : AppliedType => tp.hasWildcardArg
2703
+ case tp : AndOrType => hasWildcardArg(tp.tp1) || hasWildcardArg(tp.tp2)
2704
+ case _ : SingletonType | _ : HKTypeLambda => false
2705
+ case tp : TypeProxy => hasWildcardArg(tp.superType)
2706
+ case _ => false
2731
2707
}
2732
2708
2733
2709
def adaptToSubType (wtp : Type ): Tree = {
2734
2710
// try converting a constant to the target type
2735
2711
val folded = ConstFold (tree, pt)
2736
- if (folded ne tree) return adaptConstant(folded, folded.tpe.asInstanceOf [ConstantType ])
2737
-
2738
- // Try to capture wildcards in type
2739
- val captured = captureWildcards(wtp)
2740
- if (captured `ne` wtp) return readapt(tree.cast(captured))
2712
+ if (folded ne tree)
2713
+ return adaptConstant(folded, folded.tpe.asInstanceOf [ConstantType ])
2714
+
2715
+ // If tree's type is not stable and has wildcard arguments, make it
2716
+ // stable by casting it to a skolem. I.e. a tree `t` of widened type `T`
2717
+ // gets widened to `t.$asInstanceOf$[SkolemType(T)]`. This will enable
2718
+ // capture comversion in the subsequent subtype check.
2719
+ if (! tree.tpe.isStable && hasWildcardArg(wtp) && ! ctx.isAfterTyper)
2720
+ return readapt(tree.cast(SkolemType (wtp)))
2741
2721
2742
2722
// drop type if prototype is Unit
2743
2723
if (pt isRef defn.UnitClass ) {
0 commit comments