@@ -612,7 +612,7 @@ class Typer extends Namer
612
612
var templ1 = templ
613
613
def isEligible (tp : Type ) = tp.exists && ! tp.typeSymbol.is(Final ) && ! tp.isRef(defn.AnyClass )
614
614
if (templ1.parents.isEmpty &&
615
- isFullyDefined(pt, ForceDegree .noBottom ) &&
615
+ isFullyDefined(pt, ForceDegree .flipBottom ) &&
616
616
isSkolemFree(pt) &&
617
617
isEligible(pt.underlyingClassRef(refinementOK = false )))
618
618
templ1 = cpy.Template (templ)(parents = untpd.TypeTree (pt) :: Nil )
@@ -1009,16 +1009,20 @@ 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 _ =>
1016
+ given nestedCtx as Context = ctx.fresh.setNewTyperState()
1016
1017
val protoArgs = args map (_ withType WildcardType )
1017
1018
val callProto = FunProto (protoArgs, WildcardType )(this , app.isGivenApply)
1018
1019
val expr1 = typedExpr(expr, callProto)
1019
- fnBody = cpy.Apply (fnBody)(untpd.TypedSplice (expr1), args)
1020
- expr1.tpe
1021
- }
1020
+ if nestedCtx.reporter.hasErrors then NoType
1021
+ else
1022
+ given Context = ctx
1023
+ nestedCtx.typerState.commit()
1024
+ fnBody = cpy.Apply (fnBody)(untpd.TypedSplice (expr1), args)
1025
+ expr1.tpe
1022
1026
else NoType
1023
1027
case _ =>
1024
1028
NoType
@@ -1030,42 +1034,53 @@ class Typer extends Namer
1030
1034
// try to instantiate `pt` if this is possible. If it does not
1031
1035
// work the error will be reported later in `inferredParam`,
1032
1036
// when we try to infer the parameter type.
1033
- isFullyDefined(pt, ForceDegree .noBottom )
1037
+ isFullyDefined(pt, ForceDegree .flipBottom )
1034
1038
case _ =>
1035
1039
}
1036
1040
1037
1041
val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length)
1038
1042
1039
- /** Two attempts: First, if expected type is fully defined pick this one.
1040
- * Second, if function is of the form
1041
- * (x1, ..., xN) => f(... x1, ..., XN, ...)
1042
- * where each `xi` occurs exactly once in the argument list of `f` (in
1043
- * any order), and f has a method type MT, pick the corresponding parameter
1044
- * type in MT, if this one is fully defined.
1045
- * If both attempts fail, issue a "missing parameter type" error.
1046
- */
1047
- def inferredParamType (param : untpd.ValDef , formal : Type ): Type = {
1048
- if (isFullyDefined(formal, ForceDegree .noBottom)) return formal
1049
- 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 under ForceDegree.failBottom
1053
+ * pick this one.
1054
+ * 2. Compute the target type `T` and make it known that `S <: T`.
1055
+ * If the expected type `S` can be fully defined under ForceDegree.flipBottom,
1056
+ * pick this one (this might use the fact that S <: T for an upper approximation).
1057
+ * 3. Otherwise, if the target type `T` can be fully defined under ForceDegree.flipBottom,
1058
+ * pick this one.
1059
+ *
1060
+ * If all attempts fail, issue a "missing parameter type" error.
1061
+ */
1062
+ def inferredParamType (param : untpd.ValDef , formal : Type ): Type =
1063
+ if isFullyDefined(formal, ForceDegree .failBottom) then return formal
1064
+ val target = calleeType.widen match
1050
1065
case mtpe : MethodType =>
1051
1066
val pos = paramIndex(param.name)
1052
- if ( pos < mtpe.paramInfos.length) {
1067
+ if pos < mtpe.paramInfos.length then
1053
1068
val ptype = mtpe.paramInfos(pos)
1054
- if (isFullyDefined( ptype, ForceDegree .noBottom) && ! ptype.isRepeatedParam)
1055
- return ptype
1056
- }
1057
- case _ =>
1058
- }
1059
- errorType( AnonymousFunctionMissingParamType (param, params, tree, formal), param.sourcePos)
1060
- }
1069
+ if ptype.isRepeatedParam then NoType else ptype
1070
+ else NoType
1071
+ case _ => NoType
1072
+ if target.exists then formal <:< target
1073
+ if isFullyDefined(formal, ForceDegree .flipBottom) then formal
1074
+ else if target.exists && isFullyDefined(target, ForceDegree .flipBottom) then target
1075
+ else errorType( AnonymousFunctionMissingParamType (param, params, tree, formal), param.sourcePos)
1061
1076
1062
1077
def protoFormal (i : Int ): Type =
1063
1078
if (protoFormals.length == params.length) protoFormals(i)
1064
1079
else errorType(WrongNumberOfParameters (protoFormals.length), tree.sourcePos)
1065
1080
1066
1081
/** Is `formal` a product type which is elementwise compatible with `params`? */
1067
1082
def ptIsCorrectProduct (formal : Type ) =
1068
- isFullyDefined(formal, ForceDegree .noBottom ) &&
1083
+ isFullyDefined(formal, ForceDegree .flipBottom ) &&
1069
1084
(defn.isProductSubType(formal) || formal.derivesFrom(defn.PairClass )) &&
1070
1085
productSelectorTypes(formal, tree.sourcePos).corresponds(params) {
1071
1086
(argType, param) =>
@@ -1379,7 +1394,7 @@ class Typer extends Namer
1379
1394
}
1380
1395
case _ =>
1381
1396
tree.withType(
1382
- if (isFullyDefined(pt, ForceDegree .noBottom )) pt
1397
+ if (isFullyDefined(pt, ForceDegree .flipBottom )) pt
1383
1398
else if (ctx.reporter.errorsReported) UnspecifiedErrorType
1384
1399
else errorType(i " cannot infer type; expected type $pt is not fully defined " , tree.sourcePos))
1385
1400
}
@@ -3054,7 +3069,7 @@ class Typer extends Namer
3054
3069
pt match {
3055
3070
case SAMType (sam)
3056
3071
if wtp <:< sam.toFunctionType() =>
3057
- // was ... && isFullyDefined(pt, ForceDegree.noBottom )
3072
+ // was ... && isFullyDefined(pt, ForceDegree.flipBottom )
3058
3073
// but this prevents case blocks from implementing polymorphic partial functions,
3059
3074
// since we do not know the result parameter a priori. Have to wait until the
3060
3075
// body is typechecked.
0 commit comments