Skip to content

Commit c0b395b

Browse files
committed
Merge branch 'erasure-annot' into insertAttr
2 parents 20631be + 5c3c9d1 commit c0b395b

File tree

10 files changed

+245
-37
lines changed

10 files changed

+245
-37
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class Compiler {
109109
new TupleOptimizations, // Optimize generic operations on tuples
110110
new LetOverApply, // Lift blocks from receivers of applications
111111
new ArrayConstructors) :: // Intercept creation of (non-generic) arrays and intrinsify.
112+
List(new ErasurePreservation) :: //
112113
List(new Erasure) :: // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
113114
List(new ElimErasedValueType, // Expand erased value types to their underlying implementation types
114115
new PureStats, // Remove pure stats from blocks

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,7 @@ class Definitions {
11001100
@tu lazy val RetainsArgAnnot: ClassSymbol = requiredClass("scala.annotation.retainsArg")
11011101
@tu lazy val PublicInBinaryAnnot: ClassSymbol = requiredClass("scala.annotation.publicInBinary")
11021102
@tu lazy val WitnessNamesAnnot: ClassSymbol = requiredClass("scala.annotation.internal.WitnessNames")
1103+
@tu lazy val ErasurePreservationAnnot: ClassSymbol = requiredClass("scala.annotation.internal.ErasurePreservation")
11031104

11041105
@tu lazy val JavaRepeatableAnnot: ClassSymbol = requiredClass("java.lang.annotation.Repeatable")
11051106

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@ import util.Chars.isOperatorPart
2727
import config.{Config, Feature}
2828
import config.Feature.sourceVersion
2929
import config.SourceVersion.*
30+
import reporting.*
31+
import dotty.tools.dotc.core.Decorators.i
3032

3133
import dotty.tools.dotc.util.SourcePosition
3234
import dotty.tools.dotc.ast.untpd.{MemberDef, Modifiers, PackageDef, RefTree, Template, TypeDef, ValOrDefDef}
3335
import cc.*
3436
import dotty.tools.dotc.parsing.JavaParsers
3537
import dotty.tools.dotc.transform.TreeExtractors.BinaryOp
38+
import dotty.tools.dotc.transform.InstructionTypeArguments
39+
import dotty.tools.dotc.transform.InvokeReturnType
3640

3741
class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
3842

@@ -462,7 +466,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
462466

463467
toTextLocal(expr) ~ "." ~ selectorsText
464468

465-
tree match {
469+
(if tree.hasAttachment(InvokeReturnType) then Str("InvokeReturnType("+tree.attachment(InvokeReturnType).toString + ") ") else Str("")) ~
470+
(if tree.hasAttachment(InstructionTypeArguments) then Str("InstructionTypeArguments("+tree.attachment(InstructionTypeArguments).toString + ") ") else Str("")) ~
471+
(tree match {
466472
case id: Trees.SearchFailureIdent[?] =>
467473
tree.typeOpt match {
468474
case reason: Implicits.SearchFailureType =>
@@ -850,7 +856,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
850856
toText(pname) ~ " : " ~ toText(tycon) ~ (" as " ~ toText(ownName) `provided` !ownName.isEmpty)
851857
case _ =>
852858
tree.fallbackToText(this)
853-
}
859+
})
854860
}
855861

856862
override protected def toTextCapturing(tp: Type, refs: GeneralCaptureSet, boxText: Text): Text = tp match

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

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -928,18 +928,18 @@ object Erasure {
928928
* with more than `MaxImplementedFunctionArity` parameters to use a single
929929
* parameter of type `[]Object`.
930930
*/
931-
override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(using Context): Tree = trace(i"typedDefDef $sym,"+s" ${atPhase(ctx.phaseId-1)(sym.info)}") {// Possible Annotation target
932-
atPhase(ctx.phaseId-1)(sym.info) match
933-
case pt: PolyType =>
934-
def toTypeB(tp: Type): TypeB = tp match
935-
case tpr: TypeParamRef => TypeB.M(tpr.paramNum)
936-
case _ => TypeB.None
937-
pt.resType match
938-
case mt: MethodType =>
939-
sym.addAnnotation(ErasedInfo(pt.paramInfos.size, mt.paramInfos.map(toTypeB), toTypeB(mt.resType)))
940-
case other =>
941-
sym.addAnnotation(ErasedInfo(pt.paramInfos.size, Nil, toTypeB(other.widenExpr)))
942-
case _ => ()
931+
override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(using Context): Tree = // trace(i"typedDefDef $sym,"+s" ${atPhase(ctx.phaseId-1)(sym.info)}") {// Possible Annotation target
932+
// atPhase(ctx.phaseId-1)(sym.info) match
933+
// case pt: PolyType =>
934+
// def toTypeB(tp: Type): TypeB = tp match
935+
// case tpr: TypeParamRef => TypeB.M(tpr.paramNum)
936+
// case _ => TypeB.None
937+
// pt.resType match
938+
// case mt: MethodType =>
939+
// sym.addAnnotation(ErasedInfo(pt.paramInfos.size, mt.paramInfos.map(toTypeB), toTypeB(mt.resType)))
940+
// case other =>
941+
// sym.addAnnotation(ErasedInfo(pt.paramInfos.size, Nil, toTypeB(other.widenExpr)))
942+
// case _ => ()
943943
if sym.isEffectivelyErased || sym.name.is(BodyRetainerName) then
944944
erasedDef(sym)
945945
else
@@ -983,7 +983,7 @@ object Erasure {
983983
tpt = untpd.TypedSplice(TypeTree(restpe).withSpan(ddef.tpt.span)),
984984
rhs = rhs1)
985985
super.typedDefDef(ddef1, sym)
986-
}
986+
// }
987987
end typedDefDef
988988

989989
/** The outer parameter definition of a constructor if it needs one */
@@ -1122,22 +1122,4 @@ object Erasure {
11221122

11231123
private def takesBridges(sym: Symbol)(using Context): Boolean =
11241124
sym.isClass && !sym.isOneOf(Flags.Trait | Flags.Package)
1125-
}
1126-
1127-
enum TypeB:
1128-
case None
1129-
case M(x: Int)
1130-
// case class TypeB(tp: Type)
1131-
1132-
class ErasedInfo(paramCount: Int, paramType: List[TypeB], returnType: TypeB) extends Annotation {
1133-
override def tree(using Context) =
1134-
tpd.New(defn.SourceFileAnnot.typeRef,
1135-
List(tpd.Literal(Constant(toString))))
1136-
1137-
override def toString =
1138-
s"$paramCount, $paramType, $returnType"
1139-
1140-
def getParamCount: Int = paramCount
1141-
def getParamType: List[TypeB] = paramType
1142-
def getReturnType: TypeB = returnType
11431125
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package dotty.tools
2+
package dotc
3+
package transform
4+
5+
import ast.Trees
6+
import core.Phases.*
7+
import core.DenotTransformers.*
8+
import core.Annotations.*
9+
import core.Denotations.*
10+
import core.SymDenotations.*
11+
import core.Symbols.*
12+
import core.Contexts.*
13+
import core.Types.*
14+
import core.Names.*
15+
import core.Constants.*
16+
import core.Decorators.*
17+
import typer.NoChecking
18+
import ast.{tpd, untpd}
19+
import reporting.*
20+
import dotty.tools.dotc.transform.MegaPhase.MiniPhase
21+
import dotty.tools.dotc.util.Property
22+
23+
class ErasurePreservation extends MiniPhase with InfoTransformer {
24+
25+
override def phaseName: String = ErasurePreservation.name
26+
27+
override def description: String = ErasurePreservation.description
28+
29+
def toTypeA(tp: Type)(using Context): TypeA = trace(s"toTypeA ${tp}") {tp match
30+
case tpr: TypeParamRef => TypeA.M(tpr.paramNum)
31+
case tr: TypeRef =>
32+
// println(tr.symbol.owner.paramSymss)
33+
if tr.isRef(defn.IntClass) then TypeA.Int else
34+
if tr.symbol.isTypeParam then
35+
val ind = tr.symbol.owner.paramSymss.head.indexWhere(tr.isRef(_))
36+
if ind != -1 then TypeA.M(ind)
37+
else TypeA.Ref
38+
else TypeA.Ref
39+
case _ => assert(false)
40+
}
41+
42+
43+
def toTypeB(tp: Type)(using Context): TypeB = tp match
44+
case tpr: TypeParamRef => TypeB.M(tpr.paramNum)
45+
case _ => TypeB.None
46+
47+
def toReturnTypeB(tp: Type)(using Context): TypeB = tp match
48+
case tr: TypeRef =>
49+
// println(tr.symbol.owner.paramSymss)
50+
if tr.symbol.isTypeParam then
51+
val ind = tr.symbol.owner.paramSymss.head.indexWhere(tr.isRef(_))
52+
if ind != -1 then TypeB.M(ind)
53+
else TypeB.None
54+
else TypeB.None
55+
case _ => TypeB.None
56+
57+
58+
override def transformInfo(tp: Type, sym: Symbol)(using Context): Type =
59+
tp match
60+
case pt: PolyType =>
61+
pt.resType match
62+
case mt: MethodType =>
63+
sym.addAnnotation(ErasedInfo(pt.paramInfos.size, mt.paramInfos.map(toTypeB), toTypeB(mt.resType)))
64+
case other =>
65+
sym.addAnnotation(ErasedInfo(pt.paramInfos.size, Nil, toTypeB(other.widenExpr)))
66+
case _ => ()
67+
tp
68+
69+
override def transformApply(tree: tpd.Apply)(using Context): tpd.Tree =
70+
tree.putAttachment(InvokeReturnType, toReturnTypeB(tree.tpe))
71+
tree
72+
73+
override def transformTypeApply(tree: tpd.TypeApply)(using Context): tpd.Tree =
74+
val args = tree.args.map(_.tpe).map(toTypeA)
75+
tree.fun.putAttachment(InstructionTypeArguments, args) // Pattern match args based on their types
76+
tree
77+
78+
}
79+
80+
object ErasurePreservation {
81+
val name: String = "erasure preservation"
82+
val description: String = "preserve information in annotations before erasure"
83+
}
84+
85+
enum TypeA:
86+
case Int
87+
case M(x: Int)
88+
case K(x: Int)
89+
case Ref
90+
91+
enum TypeB:
92+
case None
93+
case M(x: Int)
94+
// case class TypeB(tp: Type)
95+
96+
object InstructionTypeArguments extends Property.StickyKey[List[TypeA]]
97+
object InvokeReturnType extends Property.StickyKey[TypeB]
98+
99+
class ErasedInfo(paramCount: Int, paramType: List[TypeB], returnType: TypeB) extends Annotation {
100+
override def tree(using Context) =
101+
tpd.New(defn.ErasurePreservationAnnot.typeRef,
102+
List(tpd.Literal(Constant(toString))))
103+
104+
override def toString =
105+
s"$paramCount, $paramType, $returnType"
106+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package scala.annotation.internal
2+
3+
import scala.annotation.Annotation
4+
5+
class ErasurePreservation(path: String) extends Annotation {
6+
7+
}

0 commit comments

Comments
 (0)