@@ -1104,6 +1104,20 @@ class Typer extends Namer
1104
1104
newTypeVar(apply(bounds.orElse(TypeBounds .empty)).bounds)
1105
1105
case _ => mapOver(t)
1106
1106
}
1107
+ def extractInUnion (t : Type ): Seq [Type ] = t match {
1108
+ case t : OrType =>
1109
+ extractInUnion(t.tp1) ++ extractInUnion(t.tp2)
1110
+ case t : TypeParamRef =>
1111
+ extractInUnion(ctx.typerState.constraint.entry(t).bounds.hi)
1112
+ case t if defn.isNonRefinedFunction(t) =>
1113
+ Seq (t)
1114
+ case SAMType (_ : MethodType ) =>
1115
+ Seq (t)
1116
+ case _ =>
1117
+ Nil
1118
+ }
1119
+ def defaultResult = (List .tabulate(defaultArity)(alwaysWildcardType), untpd.TypeTree ())
1120
+
1107
1121
val pt1 = pt.stripTypeVar.dealias
1108
1122
if (pt1 ne pt1.dropDependentRefinement)
1109
1123
&& defn.isContextFunctionType(pt1.nonPrivateMember(nme.apply).info.finalResultType)
@@ -1112,22 +1126,25 @@ class Typer extends Namer
1112
1126
i """ Implementation restriction: Expected result type $pt1
1113
1127
|is a curried dependent context function type. Such types are not yet supported. """ ,
1114
1128
tree.srcPos)
1115
- pt1 match {
1129
+
1130
+ val elems = extractInUnion(pt1)
1131
+ if elems.length != 1 then
1132
+ // The union type containing multiple function types is ignored
1133
+ defaultResult
1134
+ else elems.head match {
1116
1135
case pt1 if defn.isNonRefinedFunction(pt1) =>
1117
1136
// if expected parameter type(s) are wildcards, approximate from below.
1118
1137
// if expected result type is a wildcard, approximate from above.
1119
1138
// this can type the greatest set of admissible closures.
1120
1139
(pt1.argTypesLo.init, typeTree(interpolateWildcards(pt1.argTypesHi.last)))
1121
1140
case SAMType (sam @ MethodTpe (_, formals, restpe)) =>
1122
1141
(formals,
1123
- if (sam.isResultDependent)
1124
- untpd.DependentTypeTree (syms => restpe.substParams(sam, syms.map(_.termRef)))
1125
- else
1126
- typeTree(restpe))
1127
- case tp : TypeParamRef =>
1128
- decomposeProtoFunction(ctx.typerState.constraint.entry(tp).bounds.hi, defaultArity, tree)
1142
+ if (sam.isResultDependent)
1143
+ untpd.DependentTypeTree (syms => restpe.substParams(sam, syms.map(_.termRef)))
1144
+ else
1145
+ typeTree(restpe))
1129
1146
case _ =>
1130
- ( List .tabulate(defaultArity)(alwaysWildcardType), untpd. TypeTree ())
1147
+ defaultResult
1131
1148
}
1132
1149
}
1133
1150
@@ -1355,14 +1372,22 @@ class Typer extends Namer
1355
1372
}
1356
1373
1357
1374
def typedClosure (tree : untpd.Closure , pt : Type )(using Context ): Tree = {
1375
+ def extractInUnion (t : Type ): Seq [Type ] = t match {
1376
+ case t : OrType =>
1377
+ extractInUnion(t.tp1) ++ extractInUnion(t.tp2)
1378
+ case SAMType (_) =>
1379
+ Seq (t)
1380
+ case _ =>
1381
+ Nil
1382
+ }
1358
1383
val env1 = tree.env mapconserve (typed(_))
1359
1384
val meth1 = typedUnadapted(tree.meth)
1360
1385
val target =
1361
1386
if (tree.tpt.isEmpty)
1362
1387
meth1.tpe.widen match {
1363
1388
case mt : MethodType =>
1364
- pt.stripNull match {
1365
- case pt @ SAMType (sam)
1389
+ extractInUnion(pt) match {
1390
+ case Seq ( pt @ SAMType (sam) )
1366
1391
if ! defn.isFunctionType(pt) && mt <:< sam =>
1367
1392
// SAMs of the form C[?] where C is a class cannot be conversion targets.
1368
1393
// The resulting class `class $anon extends C[?] {...}` would be illegal,
0 commit comments