@@ -1009,7 +1009,7 @@ class Typer extends Namer
10091009 yield param.name -> idx
10101010 }.toMap
10111011 if (paramIndex.size == params.length)
1012- expr match {
1012+ expr match
10131013 case untpd.TypedSplice (expr1) =>
10141014 expr1.tpe
10151015 case _ =>
@@ -1023,7 +1023,6 @@ class Typer extends Namer
10231023 nestedCtx.typerState.commit()
10241024 fnBody = cpy.Apply (fnBody)(untpd.TypedSplice (expr1), args)
10251025 expr1.tpe
1026- }
10271026 else NoType
10281027 case _ =>
10291028 NoType
@@ -1041,28 +1040,38 @@ class Typer extends Namer
10411040
10421041 val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length)
10431042
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
10551064 case mtpe : MethodType =>
10561065 val pos = paramIndex(param.name)
1057- if ( pos < mtpe.paramInfos.length) {
1066+ if pos < mtpe.paramInfos.length then
10581067 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)
10661075
10671076 def protoFormal (i : Int ): Type =
10681077 if (protoFormals.length == params.length) protoFormals(i)
0 commit comments