@@ -1197,17 +1197,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1197
1197
)
1198
1198
end typedIf
1199
1199
1200
- /** Decompose function prototype into a list of parameter prototypes, an optional list
1201
- * describing whether the parameter prototypes come from WildcardTypes, and a result prototype
1202
- * tree, using WildcardTypes where a type is not known.
1200
+ /** Decompose function prototype into a list of parameter prototypes and a result
1201
+ * prototype tree, using WildcardTypes where a type is not known.
1203
1202
* For the result type we do this even if the expected type is not fully
1204
1203
* defined, which is a bit of a hack. But it's needed to make the following work
1205
1204
* (see typers.scala and printers/PlainPrinter.scala for examples).
1206
1205
*
1207
1206
* def double(x: Char): String = s"$x$x"
1208
1207
* "abc" flatMap double
1209
1208
*/
1210
- private def decomposeProtoFunction (pt : Type , defaultArity : Int , pos : SrcPos )(using Context ): (List [Type ], Option [ List [ Boolean ]], untpd.Tree ) = {
1209
+ private def decomposeProtoFunction (pt : Type , defaultArity : Int , pos : SrcPos )(using Context ): (List [Type ], untpd.Tree ) = {
1211
1210
def typeTree (tp : Type ) = tp match {
1212
1211
case _ : WildcardType => new untpd.InferredTypeTree ()
1213
1212
case _ => untpd.InferredTypeTree (tp)
@@ -1235,26 +1234,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1235
1234
// if expected parameter type(s) are wildcards, approximate from below.
1236
1235
// if expected result type is a wildcard, approximate from above.
1237
1236
// this can type the greatest set of admissible closures.
1238
- // However, we still keep the information on whether expected parameter types were
1239
- // wildcards, in case of types inferred from target being more specific
1240
-
1241
- val fromWildcards = pt1.argInfos.init.map{
1242
- case bounds @ TypeBounds (nt, at) if nt == defn.NothingType && at == defn.AnyType => true
1243
- case bounds => false
1244
- }
1245
-
1246
- (pt1.argTypesLo.init, Some (fromWildcards), typeTree(interpolateWildcards(pt1.argTypesHi.last)))
1237
+ (pt1.argTypesLo.init, typeTree(interpolateWildcards(pt1.argTypesHi.last)))
1247
1238
case RefinedType (parent, nme.apply, mt @ MethodTpe (_, formals, restpe))
1248
1239
if defn.isNonRefinedFunction(parent) && formals.length == defaultArity =>
1249
- (formals, None , untpd.DependentTypeTree (syms => restpe.substParams(mt, syms.map(_.termRef))))
1240
+ (formals, untpd.DependentTypeTree (syms => restpe.substParams(mt, syms.map(_.termRef))))
1250
1241
case SAMType (mt @ MethodTpe (_, formals, restpe)) =>
1251
- (formals, None ,
1242
+ (formals,
1252
1243
if (mt.isResultDependent)
1253
1244
untpd.DependentTypeTree (syms => restpe.substParams(mt, syms.map(_.termRef)))
1254
1245
else
1255
1246
typeTree(restpe))
1256
1247
case _ =>
1257
- (List .tabulate(defaultArity)(alwaysWildcardType), None , untpd.TypeTree ())
1248
+ (List .tabulate(defaultArity)(alwaysWildcardType), untpd.TypeTree ())
1258
1249
}
1259
1250
}
1260
1251
}
@@ -1276,7 +1267,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1276
1267
* If both attempts fail, return `NoType`.
1277
1268
*/
1278
1269
def inferredFromTarget (
1279
- param : untpd.ValDef , formal : Type , calleeType : Type , paramIndex : Name => Int , isWildcardParam : Boolean )(using Context ): Type =
1270
+ param : untpd.ValDef , formal : Type , calleeType : Type , paramIndex : Name => Int )(using Context ): Type =
1280
1271
val target = calleeType.widen match
1281
1272
case mtpe : MethodType =>
1282
1273
val pos = paramIndex(param.name)
@@ -1289,7 +1280,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1289
1280
else NoType
1290
1281
case _ => NoType
1291
1282
if target.exists then formal <:< target
1292
- if ! isWildcardParam && isFullyDefined(formal, ForceDegree .flipBottom) then formal
1283
+ if ! formal.isExactlyNothing && isFullyDefined(formal, ForceDegree .flipBottom) then formal
1293
1284
else if target.exists && isFullyDefined(target, ForceDegree .flipBottom) then target
1294
1285
else NoType
1295
1286
@@ -1466,7 +1457,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1466
1457
case _ =>
1467
1458
}
1468
1459
1469
- val (protoFormals, areWildcardParams, resultTpt) = decomposeProtoFunction(pt, params.length, tree.srcPos)
1460
+ val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length, tree.srcPos)
1470
1461
1471
1462
def protoFormal (i : Int ): Type =
1472
1463
if (protoFormals.length == params.length) protoFormals(i)
@@ -1509,21 +1500,19 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1509
1500
if (! param.tpt.isEmpty) param
1510
1501
else
1511
1502
val formal = protoFormal(i)
1512
- val isWildcardParam = areWildcardParams.map(list => if i < list.length then list(i) else false ).getOrElse(false )
1513
1503
val knownFormal = isFullyDefined(formal, ForceDegree .failBottom)
1514
- // Since decomposeProtoFunction eagerly approximates function arguments
1515
- // from below, then in the case that the argument was also identified as
1516
- // a wildcard type we try to prioritize inferring from target, if possible.
1517
- // See issue 16405 (tests/run/16405.scala)
1518
- val (usingFormal, paramType) =
1519
- if ! isWildcardParam && knownFormal then (true , formal)
1520
- else
1521
- val fromTarget = inferredFromTarget(param, formal, calleeType, paramIndex, isWildcardParam)
1522
- if fromTarget.exists then (false , fromTarget)
1523
- else if knownFormal then (true , formal)
1524
- else (false , errorType(AnonymousFunctionMissingParamType (param, tree, formal), param.srcPos))
1504
+ // If the expected formal is Nothin, try to prioritize inferring from target,
1505
+ // if possible. See issue 16405 (tests/run/16405.scala)
1506
+ val paramType =
1507
+ if knownFormal && ! formal.isExactlyNothing then
1508
+ formal
1509
+ else
1510
+ inferredFromTarget(param, formal, calleeType, paramIndex).orElse(
1511
+ if knownFormal then formal
1512
+ else errorType(AnonymousFunctionMissingParamType (param, tree, formal), param.srcPos)
1513
+ )
1525
1514
val paramTpt = untpd.TypedSplice (
1526
- (if usingFormal then InferredTypeTree () else untpd.TypeTree ())
1515
+ (if knownFormal then InferredTypeTree () else untpd.TypeTree ())
1527
1516
.withType(paramType.translateFromRepeated(toArray = false ))
1528
1517
.withSpan(param.span.endPos)
1529
1518
)
@@ -1594,7 +1583,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1594
1583
typedMatchFinish(tree, tpd.EmptyTree , defn.ImplicitScrutineeTypeRef , cases1, pt)
1595
1584
}
1596
1585
else {
1597
- val (protoFormals, _, _ ) = decomposeProtoFunction(pt, 1 , tree.srcPos)
1586
+ val (protoFormals, _) = decomposeProtoFunction(pt, 1 , tree.srcPos)
1598
1587
val checkMode =
1599
1588
if (pt.isRef(defn.PartialFunctionClass )) desugar.MatchCheck .None
1600
1589
else desugar.MatchCheck .Exhaustive
0 commit comments