@@ -1009,7 +1009,7 @@ class Typer extends Namer
1009
1009
yield param.name -> idx
1010
1010
}.toMap
1011
1011
if (paramIndex.size == params.length)
1012
- expr match {
1012
+ expr match
1013
1013
case untpd.TypedSplice (expr1) =>
1014
1014
expr1.tpe
1015
1015
case _ =>
@@ -1023,7 +1023,6 @@ class Typer extends Namer
1023
1023
nestedCtx.typerState.commit()
1024
1024
fnBody = cpy.Apply (fnBody)(untpd.TypedSplice (expr1), args)
1025
1025
expr1.tpe
1026
- }
1027
1026
else NoType
1028
1027
case _ =>
1029
1028
NoType
@@ -1041,28 +1040,38 @@ class Typer extends Namer
1041
1040
1042
1041
val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length)
1043
1042
1044
- /** Two attempts: First, if expected type is fully defined pick this one.
1045
- * Second, if function is of the form
1046
- * (x1, ..., xN) => f(... x1, ..., XN, ...)
1047
- * where each `xi` occurs exactly once in the argument list of `f` (in
1048
- * any order), and f has a method type MT, pick the corresponding parameter
1049
- * type in MT, if this one is fully defined.
1050
- * If both attempts fail, issue a "missing parameter type" error.
1051
- */
1052
- def inferredParamType (param : untpd.ValDef , formal : Type ): Type = {
1053
- if (isFullyDefined(formal, ForceDegree .noBottom)) return formal
1054
- calleeType.widen match {
1043
+ /** The inferred parameter type for a parameter in a lambda that does
1044
+ * not have an explicit type given.
1045
+ * An inferred parameter type I has two possible sources:
1046
+ * - the type S known from the context
1047
+ * - the "target type" T known from the callee `f` if the lambda is of a form like `x => f(x)`
1048
+ * If `T` exists, we know that `S <: I <: T`.
1049
+ *
1050
+ * The inference makes three attempts:
1051
+ *
1052
+ * 1. If the expected type `S` is already fully defined pick this one.
1053
+ * 2. Compute the target type `T` and make it known that `S <: T`.
1054
+ * If the expected type `S` can be fully defined under ForceDegree.noBottom,
1055
+ * pick this one (this might use the fact that S <: T for an upper approximation).
1056
+ * 3. Otherwise, if the target type `T` can be fully defined under ForceDegree.noBottom,
1057
+ * pick this one.
1058
+ *
1059
+ * If all attempts fail, issue a "missing parameter type" error.
1060
+ */
1061
+ def inferredParamType (param : untpd.ValDef , formal : Type ): Type =
1062
+ if isFullyDefined(formal, ForceDegree .none) then return formal
1063
+ val target = calleeType.widen match
1055
1064
case mtpe : MethodType =>
1056
1065
val pos = paramIndex(param.name)
1057
- if ( pos < mtpe.paramInfos.length) {
1066
+ if pos < mtpe.paramInfos.length then
1058
1067
val ptype = mtpe.paramInfos(pos)
1059
- if (isFullyDefined( ptype, ForceDegree .noBottom) && ! ptype.isRepeatedParam)
1060
- return ptype
1061
- }
1062
- case _ =>
1063
- }
1064
- errorType( AnonymousFunctionMissingParamType (param, params, tree, formal), param.sourcePos)
1065
- }
1068
+ if ptype.isRepeatedParam then NoType else ptype
1069
+ else NoType
1070
+ case _ => NoType
1071
+ if target.exists then formal <:< target
1072
+ if isFullyDefined(formal, ForceDegree .noBottom) then formal
1073
+ else if target.exists && isFullyDefined(target, ForceDegree .noBottom) then target
1074
+ else errorType( AnonymousFunctionMissingParamType (param, params, tree, formal), param.sourcePos)
1066
1075
1067
1076
def protoFormal (i : Int ): Type =
1068
1077
if (protoFormals.length == params.length) protoFormals(i)
0 commit comments