Skip to content

Commit 0dba09b

Browse files
committed
Fall-back to "non-erased" method companion if no erased parameters are found
This is helpful when calling `derivedLambdaType` post-erasure
1 parent 5ff49e2 commit 0dba09b

File tree

2 files changed

+21
-28
lines changed

2 files changed

+21
-28
lines changed

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

+20-27
Original file line numberDiff line numberDiff line change
@@ -3922,26 +3922,13 @@ object Types {
39223922
case c: ErasedMethodCompanion => c.erasedParams(paramInfos)
39233923
case _ => super.erasedParams
39243924

3925-
// Mark erased classes as erased parameters as well.
3926-
def markErasedClasses(using Context): MethodType =
3927-
val isErasedClass = paramInfos.map(_.isErasedClass)
3928-
if isErasedClass.contains(true) then companion match
3929-
case c: ErasedMethodCompanion =>
3930-
val baseErasedParams = c.erasedParams(paramInfos)
3931-
val erasedParams = baseErasedParams.zipWithConserve(isErasedClass) { (a, b) => a || b }
3932-
if erasedParams == baseErasedParams then this
3933-
else MethodType.companion(
3934-
isContextual = isContextualMethod,
3935-
isImplicit = isImplicitMethod,
3936-
erasedParams = erasedParams
3937-
)(paramNames)(paramInfosExp, resultTypeExp)
3938-
case _ =>
3939-
MethodType.companion(
3940-
isContextual = isContextualMethod,
3941-
isImplicit = isImplicitMethod,
3942-
erasedParams = isErasedClass
3943-
)(paramNames)(paramInfosExp, resultTypeExp)
3944-
else this
3925+
/** Returns the corresponding companion, but without erased parameters */
3926+
final def companionWithoutErased = companion match
3927+
case ErasedImplicitMethodType => ImplicitMethodType
3928+
case ErasedContextualMethodType => ContextualMethodType
3929+
case ErasedMethodType => MethodType
3930+
case actual => actual
3931+
39453932

39463933
protected def prefixString: String = companion.prefixString
39473934
}
@@ -4038,7 +4025,7 @@ object Types {
40384025
tl => tl.integrate(params, resultType))
40394026
end fromSymbols
40404027

4041-
final def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(using Context): MethodType =
4028+
def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(using Context): MethodType =
40424029
checkValid(unique(new CachedMethodType(paramNames)(paramInfosExp, resultTypeExp, self)))
40434030

40444031
def checkValid(mt: MethodType)(using Context): mt.type = {
@@ -4062,18 +4049,24 @@ object Types {
40624049
else
40634050
if (hasErased) ErasedMethodType else MethodType
40644051
}
4065-
sealed abstract class ErasedMethodCompanion(prefixString: String)
4066-
extends MethodTypeCompanion("Erased" + prefixString) {
4052+
sealed abstract class ErasedMethodCompanion(withoutErased: MethodTypeCompanion)
4053+
extends MethodTypeCompanion("Erased" + withoutErased.prefixString) {
4054+
4055+
override def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(using Context): MethodType =
4056+
val mt = super.apply(paramNames)(paramInfosExp, resultTypeExp)
4057+
// assert(erasedParams(mt.paramInfos).contains(true), s"$mt must contain an erased parameter")
4058+
if erasedParams(mt.paramInfos).contains(true) then mt
4059+
else withoutErased(paramNames)(paramInfosExp, resultTypeExp)
40674060

40684061
def erasedParams(paramsInfo: List[Type])(using Context) =
4069-
paramsInfo.map(_.hasAnnotation(defn.ErasedParamAnnot))
4062+
paramsInfo.map(p => p.hasAnnotation(defn.ErasedParamAnnot) || p.isErasedClass)
40704063
}
40714064

4072-
object ErasedMethodType extends ErasedMethodCompanion("MethodType")
4065+
object ErasedMethodType extends ErasedMethodCompanion(MethodType)
40734066
object ContextualMethodType extends MethodTypeCompanion("ContextualMethodType")
4074-
object ErasedContextualMethodType extends ErasedMethodCompanion("ContextualMethodType")
4067+
object ErasedContextualMethodType extends ErasedMethodCompanion(ContextualMethodType)
40754068
object ImplicitMethodType extends MethodTypeCompanion("ImplicitMethodType")
4076-
object ErasedImplicitMethodType extends ErasedMethodCompanion("ImplicitMethodType")
4069+
object ErasedImplicitMethodType extends ErasedMethodCompanion(ImplicitMethodType)
40774070

40784071
/** A ternary extractor for MethodType */
40794072
object MethodTpe {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
13401340
val appDef0 = untpd.DefDef(nme.apply, List(params3), body, EmptyTree).withSpan(tree.span)
13411341
index(appDef0 :: Nil)
13421342
val appDef = typed(appDef0).asInstanceOf[DefDef]
1343-
val mt = appDef.symbol.info.asInstanceOf[MethodType].markErasedClasses
1343+
val mt = appDef.symbol.info.asInstanceOf[MethodType]
13441344
if (mt.isParamDependent)
13451345
report.error(em"$mt is an illegal function type because it has inter-parameter dependencies", tree.srcPos)
13461346
val resTpt = TypeTree(mt.nonDependentResultApprox).withSpan(body.span)

0 commit comments

Comments
 (0)