Skip to content

Commit 04e3f91

Browse files
committed
Simplify how function value erased parameters are inferred
We can just extract erased parameter information when eta-expanding, and have no erasedness inference. That way, synthetic function values copy over their erased parameters, while handwritten lambdas need to be explicitly annotated.
1 parent 752347c commit 04e3f91

File tree

3 files changed

+16
-21
lines changed

3 files changed

+16
-21
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3918,6 +3918,10 @@ object Types {
39183918
companion.eq(ContextualMethodType) ||
39193919
companion.isInstanceOf[ErasedContextualMethodType]
39203920

3921+
def erasedParams: List[Boolean] = companion match
3922+
case c: ErasedMethodCompanion => c.isErased
3923+
case _ => paramInfos.map(_ => false)
3924+
39213925
def withoutErased(using Context): MethodType =
39223926
val newCompanion = companion match {
39233927
case _: ErasedMethodType => MethodType

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,9 @@ object EtaExpansion extends LiftImpure {
285285
val body = Apply(lifted, ids)
286286
if (mt.isContextualMethod) body.setApplyKind(ApplyKind.Using)
287287
val fn =
288-
if (mt.isContextualMethod) new untpd.FunctionWithMods(params, body, Modifiers(Given), params.map(_ => false))
289-
else if (mt.isImplicitMethod) new untpd.FunctionWithMods(params, body, Modifiers(Implicit), params.map(_ => false))
288+
if (mt.isContextualMethod) new untpd.FunctionWithMods(params, body, Modifiers(Given), mt.erasedParams)
289+
else if (mt.isImplicitMethod) new untpd.FunctionWithMods(params, body, Modifiers(Implicit), mt.erasedParams)
290+
else if (mt.isErasedMethod) new untpd.FunctionWithMods(params, body, Modifiers(), mt.erasedParams)
290291
else untpd.Function(params, body)
291292
if (defs.nonEmpty) untpd.Block(defs.toList map (untpd.TypedSplice(_)), fn) else fn
292293
}

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

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,14 +1444,6 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
14441444
NoType
14451445
}
14461446

1447-
lazy val calleeIsErased = calleeType.widen match {
1448-
case mt: MethodType if mt.isErasedMethod =>
1449-
val companion = mt.companion.asInstanceOf[ErasedMethodCompanion]
1450-
params.map(p => companion.isErased(paramIndex(p.name)))
1451-
// companion.isErased
1452-
case _ => params.map(_ => false)
1453-
}
1454-
14551447
pt match {
14561448
case pt: TypeVar
14571449
if untpd.isFunctionWithUnknownParamType(tree) && !calleeType.exists =>
@@ -1467,7 +1459,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
14671459
/** Returns the type and whether the parameter is erased */
14681460
def protoFormal(i: Int): (Type, Boolean) =
14691461
if (protoFormals.length == params.length) (protoFormals(i), isDefinedErased(i))
1470-
else (errorType(WrongNumberOfParameters(protoFormals.length), tree.srcPos), isDefinedErased(i))
1462+
else (errorType(WrongNumberOfParameters(protoFormals.length), tree.srcPos), false)
14711463

14721464
/** Is `formal` a product type which is elementwise compatible with `params`? */
14731465
def ptIsCorrectProduct(formal: Type) =
@@ -1504,23 +1496,21 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
15041496
val inferredParams: List[untpd.ValDef] =
15051497
for ((param, i) <- params.zipWithIndex) yield
15061498
val (formal, isErased) = protoFormal(i)
1507-
val (param0, isErased1) =
1508-
if (!param.tpt.isEmpty) (param, false)
1499+
val param0 =
1500+
if (!param.tpt.isEmpty) param
15091501
else
15101502
val knownFormal = isFullyDefined(formal, ForceDegree.failBottom)
1511-
val (paramType, isErased1) =
1512-
if knownFormal then (formal, false)
1513-
else
1514-
val tpe = inferredFromTarget(param, formal, calleeType, paramIndex)
1515-
.orElse(errorType(AnonymousFunctionMissingParamType(param, tree, formal), param.srcPos))
1516-
(tpe, calleeIsErased(i))
1503+
val paramType =
1504+
if knownFormal then formal
1505+
else inferredFromTarget(param, formal, calleeType, paramIndex)
1506+
.orElse(errorType(AnonymousFunctionMissingParamType(param, tree, formal), param.srcPos))
15171507
val paramTpt = untpd.TypedSplice(
15181508
(if knownFormal then InferredTypeTree() else untpd.TypeTree())
15191509
.withType(paramType.translateFromRepeated(toArray = false))
15201510
.withSpan(param.span.endPos)
15211511
)
1522-
(cpy.ValDef(param)(tpt = paramTpt), isErased1)
1523-
if isErased || isErased1 then param0.withAddedFlags(Flags.Erased) else param0
1512+
cpy.ValDef(param)(tpt = paramTpt)
1513+
if isErased then param0.withAddedFlags(Flags.Erased) else param0
15241514
desugared = desugar.makeClosure(inferredParams, fnBody, resultTpt, isContextual, tree.span)
15251515

15261516
typed(desugared, pt)

0 commit comments

Comments
 (0)