Skip to content

Commit 0b976ff

Browse files
committed
Some sweeping changes to argument handling for erased methods
Basically, I grepped for `isErasedMethod` and changed every argument handling code to make use of the `ErasedMethodCompanion`. There are be some pretty repetitive .zip(list of bool).flatMap((f, s) => if s then None else Some(f)) patterns, I wonder if there is any better way to write them?
1 parent 6c4d7bf commit 0b976ff

File tree

10 files changed

+56
-26
lines changed

10 files changed

+56
-26
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
259259
if tp.isContextualMethod then Given
260260
else if tp.isImplicitMethod then Implicit
261261
else EmptyFlags
262-
val maybeErased = if tp.isErasedMethod then Erased else EmptyFlags
262+
val maybeErased = if tp.isErasedMethod then Erased else EmptyFlags // TODO @natsukagami change this
263263

264264
def makeSym(info: Type) = newSymbol(sym, name, TermParam | maybeImplicit | maybeErased, info, coord = sym.coord)
265265

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,10 @@ object Denotations {
543543
case tp2: MethodType
544544
if TypeComparer.matchingMethodParams(tp1, tp2)
545545
&& tp1.isImplicitMethod == tp2.isImplicitMethod
546-
&& tp1.isErasedMethod == tp2.isErasedMethod =>
546+
&& tp1.isErasedMethod == tp2.isErasedMethod
547+
&& (!tp1.isErasedMethod || ( // same set of erased parameters
548+
tp1.companion.asInstanceOf[ErasedMethodCompanion].isErased ==
549+
tp2.companion.asInstanceOf[ErasedMethodCompanion].isErased)) =>
547550
val resType = infoMeet(tp1.resType, tp2.resType.subst(tp2, tp1), safeIntersection)
548551
if resType.exists then
549552
tp1.derivedLambdaType(mergeParamNames(tp1, tp2), tp1.paramInfos, resType)

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,13 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
638638
case tp: MethodType =>
639639
def paramErasure(tpToErase: Type) =
640640
erasureFn(sourceLanguage, semiEraseVCs, isConstructor, isSymbol, wildcardOK)(tpToErase)
641-
val (names, formals0) = if (tp.isErasedMethod) (Nil, Nil) else (tp.paramNames, tp.paramInfos)
641+
val (names, formals0) = if (tp.isErasedMethod)
642+
tp.paramNames
643+
.zip(tp.paramInfos)
644+
.zip(tp.companion.asInstanceOf[ErasedMethodCompanion].isErased)
645+
.flatMap((p, e) => if e then None else Some(p))
646+
.unzip
647+
else (tp.paramNames, tp.paramInfos)
642648
val formals = formals0.mapConserve(paramErasure)
643649
eraseResult(tp.resultType) match {
644650
case rt: MethodType =>

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,7 @@ object Types {
18371837
case mt: MethodType if !mt.isParamDependent =>
18381838
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
18391839
val isContextual = mt.isContextualMethod && !ctx.erasedTypes
1840-
val isErased = mt.isErasedMethod && !ctx.erasedTypes
1840+
val isErased = mt.isErasedMethod && !ctx.erasedTypes // TODO @natsukagami fix this
18411841
val result1 = mt.nonDependentResultApprox match {
18421842
case res: MethodType => res.toFunctionType(isJava)
18431843
case res => res
@@ -3691,7 +3691,11 @@ object Types {
36913691
else Signature(tp, sourceLanguage)
36923692
this match
36933693
case tp: MethodType =>
3694-
val params = if (isErasedMethod) Nil else tp.paramInfos
3694+
val params = if (isErasedMethod)
3695+
tp.paramInfos
3696+
.zip(tp.companion.asInstanceOf[ErasedMethodCompanion].isErased)
3697+
.flatMap((p, e) => if e then None else Some(p))
3698+
else tp.paramInfos
36953699
resultSignature.prependTermParams(params, sourceLanguage)
36963700
case tp: PolyType =>
36973701
resultSignature.prependTypeParams(tp.paramNames.length)
@@ -3902,9 +3906,7 @@ object Types {
39023906
companion.isInstanceOf[ErasedImplicitMethodType] ||
39033907
isContextualMethod
39043908
final override def isErasedMethod: Boolean =
3905-
companion.isInstanceOf[ErasedMethodType] ||
3906-
companion.isInstanceOf[ErasedImplicitMethodType] ||
3907-
companion.isInstanceOf[ErasedContextualMethodType]
3909+
companion.isInstanceOf[ErasedMethodCompanion]
39083910
final override def isContextualMethod: Boolean =
39093911
companion.eq(ContextualMethodType) ||
39103912
companion.isInstanceOf[ErasedContextualMethodType]
@@ -4030,11 +4032,14 @@ object Types {
40304032
}
40314033
private def erasedMt(t: String, isErased: List[Boolean]) =
40324034
s"Erased${t}(${isErased.map(if _ then "erased _" else "_").mkString(", ")})"
4033-
class ErasedMethodType(val isErased: List[Boolean]) extends MethodTypeCompanion(erasedMt("MethodType", isErased))
4035+
class ErasedMethodCompanion(prefixString: String, val isErased: List[Boolean])
4036+
extends MethodTypeCompanion(erasedMt(prefixString, isErased))
4037+
4038+
class ErasedMethodType(isErased: List[Boolean]) extends ErasedMethodCompanion("MethodType", isErased)
40344039
object ContextualMethodType extends MethodTypeCompanion("ContextualMethodType")
4035-
class ErasedContextualMethodType(val isErased: List[Boolean]) extends MethodTypeCompanion(erasedMt("ContextualMethodType", isErased))
4040+
class ErasedContextualMethodType(isErased: List[Boolean]) extends ErasedMethodCompanion("ContextualMethodType", isErased)
40364041
object ImplicitMethodType extends MethodTypeCompanion("ImplicitMethodType")
4037-
class ErasedImplicitMethodType(val isErased: List[Boolean]) extends MethodTypeCompanion(erasedMt("ImplicitMethodType", isErased))
4042+
class ErasedImplicitMethodType(isErased: List[Boolean]) extends ErasedMethodCompanion("ImplicitMethodType", isErased)
40384043

40394044
/** A ternary extractor for MethodType */
40404045
object MethodTpe {

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class TreePickler(pickler: TastyPickler) {
288288
var mods = EmptyFlags
289289
if tpe.isContextualMethod then mods |= Given
290290
else if tpe.isImplicitMethod then mods |= Implicit
291-
if tpe.isErasedMethod then mods |= Erased
291+
if tpe.isErasedMethod then mods |= Erased // TODO @natsukagami change this
292292
pickleMethodic(METHODtype, tpe, mods)
293293
case tpe: ParamRef =>
294294
assert(pickleParamRef(tpe), s"orphan parameter reference: $tpe")

compiler/src/dotty/tools/dotc/transform/ContextFunctionResults.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ object ContextFunctionResults:
9292
def normalParamCount(tp: Type): Int = tp.widenExpr.stripPoly match
9393
case mt @ MethodType(pnames) =>
9494
val rest = normalParamCount(mt.resType)
95-
if mt.isErasedMethod then rest else pnames.length + rest
95+
if mt.isErasedMethod then
96+
mt.companion.asInstanceOf[ErasedMethodCompanion].isErased.count(_ == false) + rest
97+
else pnames.length + rest
9698
case _ => contextParamCount(tp, contextResultCount(sym))
9799

98100
normalParamCount(sym.info)

compiler/src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,12 @@ object Erasure {
825825
val Apply(fun, args) = tree
826826
val origFun = fun.asInstanceOf[tpd.Tree]
827827
val origFunType = origFun.tpe.widen(using preErasureCtx)
828-
val ownArgs = if origFunType.isErasedMethod then Nil else args
828+
val erasedCompanion = if origFunType.isErasedMethod then
829+
Some(origFunType.asInstanceOf[MethodType].companion.asInstanceOf[ErasedMethodCompanion])
830+
else None
831+
val ownArgs = erasedCompanion.map { companion =>
832+
args.zip(companion.isErased).flatMap((a, e) => if e then None else Some(a))
833+
}.getOrElse(args)
829834
val fun1 = typedExpr(fun, AnyFunctionProto)
830835
fun1.tpe.widen match
831836
case mt: MethodType =>

compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,10 @@ object GenericSignatures {
304304
case mtpe: MethodType =>
305305
// erased method parameters do not make it to the bytecode.
306306
def effectiveParamInfoss(t: Type)(using Context): List[List[Type]] = t match {
307-
case t: MethodType if t.isErasedMethod => effectiveParamInfoss(t.resType)
307+
case t: MethodType if t.isErasedMethod =>
308+
t.paramInfos.zip(t.companion.asInstanceOf[ErasedMethodCompanion].isErased)
309+
.flatMap((i, e) => if e then None else Some(i))
310+
:: effectiveParamInfoss(t.resType)
308311
case t: MethodType => t.paramInfos :: effectiveParamInfoss(t.resType)
309312
case _ => Nil
310313
}

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -307,16 +307,18 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
307307
if (methType.isErasedMethod)
308308
tpd.cpy.Apply(tree)(
309309
tree.fun,
310-
tree.args.mapConserve(arg =>
311-
if methType.isResultDependent then
312-
Checking.checkRealizable(arg.tpe, arg.srcPos, "erased argument")
313-
if (methType.isImplicitMethod && arg.span.isSynthetic)
314-
arg match
315-
case _: RefTree | _: Apply | _: TypeApply if arg.symbol.is(Erased) =>
316-
dropInlines.transform(arg)
317-
case _ =>
318-
PruneErasedDefs.trivialErasedTree(arg)
319-
else dropInlines.transform(arg)))
310+
tree.args.zip(methType.companion.asInstanceOf[ErasedMethodCompanion].isErased).map((arg, isErased) =>
311+
if !isErased then arg
312+
else
313+
if methType.isResultDependent then
314+
Checking.checkRealizable(arg.tpe, arg.srcPos, "erased argument")
315+
if (methType.isImplicitMethod && arg.span.isSynthetic)
316+
arg match
317+
case _: RefTree | _: Apply | _: TypeApply if arg.symbol.is(Erased) =>
318+
dropInlines.transform(arg)
319+
case _ =>
320+
PruneErasedDefs.trivialErasedTree(arg)
321+
else dropInlines.transform(arg)))
320322
else
321323
tree
322324
def app1 =

compiler/src/dotty/tools/dotc/transform/PruneErasedDefs.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import ast.tpd
1313
import SymUtils._
1414
import config.Feature
1515
import Decorators.*
16+
import dotty.tools.dotc.core.Types.ErasedMethodCompanion
17+
import dotty.tools.dotc.core.Types.MethodType
1618

1719
/** This phase makes all erased term members of classes private so that they cannot
1820
* conflict with non-erased members. This is needed so that subsequent phases like
@@ -39,7 +41,9 @@ class PruneErasedDefs extends MiniPhase with SymTransformer { thisTransform =>
3941

4042
override def transformApply(tree: Apply)(using Context): Tree =
4143
if !tree.fun.tpe.widen.isErasedMethod then tree
42-
else cpy.Apply(tree)(tree.fun, tree.args.map(trivialErasedTree))
44+
else
45+
val comp = tree.fun.tpe.widen.asInstanceOf[MethodType].companion.asInstanceOf[ErasedMethodCompanion]
46+
cpy.Apply(tree)(tree.fun, tree.args.zip(comp.isErased).map((a, e) => if e then trivialErasedTree(a) else a))
4347

4448
override def transformValDef(tree: ValDef)(using Context): Tree =
4549
checkErasedInExperimental(tree.symbol)

0 commit comments

Comments
 (0)