Skip to content

Commit 46edcbd

Browse files
committed
Slightly change how erased parameters are inferred in closures
Erasedness will now always be inferred from the function body, especially when `calleeType` value is available. Otherwise, it's better just to stick to the original definition. The target type is not considered, and type checking should fail when signatures do not match.
1 parent 6286c0f commit 46edcbd

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,15 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
14411441
NoType
14421442
}
14431443

1444+
val calleeIsErased = calleeType.widen match {
1445+
case mt: MethodType if mt.isErasedMethod =>
1446+
val companion = mt.companion.asInstanceOf[ErasedMethodCompanion]
1447+
params.map(p => companion.isErased(paramIndex(p.name)))
1448+
// companion.isErased
1449+
case _ => params.map(_ => false)
1450+
}
1451+
// println(s"callee type = ${calleeType.widen}")
1452+
14441453
pt match {
14451454
case pt: TypeVar
14461455
if untpd.isFunctionWithUnknownParamType(tree) && !calleeType.exists =>
@@ -1453,15 +1462,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
14531462

14541463
val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length, tree.srcPos)
14551464

1456-
val protoIsErased = pt match {
1457-
case RefinedType(_, _, mt: MethodType) if mt.isErasedMethod =>
1458-
mt.companion.asInstanceOf[ErasedMethodCompanion].isErased
1459-
case _ => List.fill(protoFormals.length)(false)
1460-
}
1461-
14621465
/** Returns the type and whether the parameter is erased */
14631466
def protoFormal(i: Int): (Type, Boolean) =
1464-
if (protoFormals.length == params.length) (protoFormals(i), protoIsErased(i) || isDefinedErased(i))
1467+
if (protoFormals.length == params.length) (protoFormals(i), calleeIsErased(i) || isDefinedErased(i))
14651468
else (errorType(WrongNumberOfParameters(protoFormals.length), tree.srcPos), isDefinedErased(i))
14661469

14671470
/** Is `formal` a product type which is elementwise compatible with `params`? */
@@ -1500,7 +1503,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
15001503
for ((param, i) <- params.zipWithIndex) yield
15011504
if (!param.tpt.isEmpty) param
15021505
else
1503-
val (formal, isProtoErased) = protoFormal(i)
1506+
val (formal, isErased) = protoFormal(i)
15041507
val knownFormal = isFullyDefined(formal, ForceDegree.failBottom)
15051508
val paramType =
15061509
if knownFormal then formal
@@ -1511,8 +1514,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
15111514
.withType(paramType.translateFromRepeated(toArray = false))
15121515
.withSpan(param.span.endPos)
15131516
)
1514-
val isErased = isProtoErased || paramType.hasAnnotation(defn.ErasedParamAnnot)
1515-
cpy.ValDef(param)(tpt = paramTpt)
1517+
val param1 = if isErased then param.withAddedFlags(Flags.Erased) else param
1518+
cpy.ValDef(param1)(tpt = paramTpt)
15161519
desugared = desugar.makeClosure(inferredParams, fnBody, resultTpt, isContextual, tree.span)
15171520

15181521
typed(desugared, pt)

0 commit comments

Comments
 (0)