@@ -1217,8 +1217,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1217
1217
)
1218
1218
end typedIf
1219
1219
1220
- /** Decompose function prototype into a list of parameter prototypes and a result prototype
1221
- * tree, using WildcardTypes where a type is not known.
1220
+ /** Decompose function prototype into a list of parameter prototypes and a result
1221
+ * prototype tree, using WildcardTypes where a type is not known.
1222
+ * Note: parameter prototypes may be TypeBounds.
1222
1223
* For the result type we do this even if the expected type is not fully
1223
1224
* defined, which is a bit of a hack. But it's needed to make the following work
1224
1225
* (see typers.scala and printers/PlainPrinter.scala for examples).
@@ -1254,7 +1255,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1254
1255
// if expected parameter type(s) are wildcards, approximate from below.
1255
1256
// if expected result type is a wildcard, approximate from above.
1256
1257
// this can type the greatest set of admissible closures.
1257
- (pt1.argTypesLo.init, typeTree(interpolateWildcards(pt1.argTypesHi.last)))
1258
+
1259
+ (pt1.argInfos.init, typeTree(interpolateWildcards(pt1.argInfos.last.hiBound)))
1258
1260
case RefinedType (parent, nme.apply, mt @ MethodTpe (_, formals, restpe))
1259
1261
if defn.isNonRefinedFunction(parent) && formals.length == defaultArity =>
1260
1262
(formals, untpd.DependentTypeTree (syms => restpe.substParams(mt, syms.map(_.termRef))))
@@ -1300,7 +1302,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1300
1302
else NoType
1301
1303
case _ => NoType
1302
1304
if target.exists then formal <:< target
1303
- if isFullyDefined(formal, ForceDegree .flipBottom) then formal
1305
+ if ! formal.isExactlyNothing && isFullyDefined(formal, ForceDegree .flipBottom) then formal
1304
1306
else if target.exists && isFullyDefined(target, ForceDegree .flipBottom) then target
1305
1307
else NoType
1306
1308
@@ -1493,11 +1495,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1493
1495
}
1494
1496
1495
1497
var desugared : untpd.Tree = EmptyTree
1496
- if protoFormals.length == 1 && params.length != 1 && ptIsCorrectProduct(protoFormals.head) then
1497
- val isGenericTuple =
1498
- protoFormals.head.derivesFrom(defn.TupleClass )
1499
- && ! defn.isTupleClass(protoFormals.head.typeSymbol)
1500
- desugared = desugar.makeTupledFunction(params, fnBody, isGenericTuple)
1498
+ if protoFormals.length == 1 && params.length != 1 then
1499
+ val firstFormal = protoFormals.head.loBound
1500
+ if ptIsCorrectProduct(firstFormal) then
1501
+ val isGenericTuple =
1502
+ firstFormal.derivesFrom(defn.TupleClass )
1503
+ && ! defn.isTupleClass(firstFormal.typeSymbol)
1504
+ desugared = desugar.makeTupledFunction(params, fnBody, isGenericTuple)
1501
1505
else if protoFormals.length > 1 && params.length == 1 then
1502
1506
def isParamRef (scrut : untpd.Tree ): Boolean = scrut match
1503
1507
case untpd.Annotated (scrut1, _) => isParamRef(scrut1)
@@ -1519,12 +1523,20 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
1519
1523
for ((param, i) <- params.zipWithIndex) yield
1520
1524
if (! param.tpt.isEmpty) param
1521
1525
else
1522
- val formal = protoFormal(i)
1526
+ val formalBounds = protoFormal(i)
1527
+ val formal = formalBounds.loBound
1528
+ val isBottomFromWildcard = (formalBounds ne formal) && formal.isExactlyNothing
1523
1529
val knownFormal = isFullyDefined(formal, ForceDegree .failBottom)
1530
+ // If the expected formal is a TypeBounds wildcard argument with Nothing as lower bound,
1531
+ // try to prioritize inferring from target. See issue 16405 (tests/run/16405.scala)
1524
1532
val paramType =
1525
- if knownFormal then formal
1526
- else inferredFromTarget(param, formal, calleeType, paramIndex)
1527
- .orElse(errorType(AnonymousFunctionMissingParamType (param, tree, formal), param.srcPos))
1533
+ if knownFormal && ! isBottomFromWildcard then
1534
+ formal
1535
+ else
1536
+ inferredFromTarget(param, formal, calleeType, paramIndex).orElse(
1537
+ if knownFormal then formal
1538
+ else errorType(AnonymousFunctionMissingParamType (param, tree, formal), param.srcPos)
1539
+ )
1528
1540
val paramTpt = untpd.TypedSplice (
1529
1541
(if knownFormal then InferredTypeTree () else untpd.TypeTree ())
1530
1542
.withType(paramType.translateFromRepeated(toArray = false ))
0 commit comments