Skip to content

Commit f2e637b

Browse files
committed
Make all phantoms unused
This removes the necesity of erasing phantoms. This process is done by the erasure of `unused`.
1 parent a06d1a1 commit f2e637b

File tree

84 files changed

+233
-488
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+233
-488
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ class Compiler {
6868
new ShortcutImplicits, // Allow implicit functions without creating closures
6969
new CrossCastAnd, // Normalize selections involving intersection types.
7070
new Splitter), // Expand selections involving union types into conditionals
71-
List(new PhantomArgLift, // Extracts the evaluation of phantom arguments placing them before the call
72-
new UnusedDecls, // Removes all unused defs and vals decls (except for parameters)
71+
List(new UnusedDecls, // Removes all unused defs and vals decls (except for parameters)
7372
new VCInlineMethods, // Inlines calls to value class methods
7473
new SeqLiterals, // Express vararg arguments as arrays
7574
new InterceptedMethods, // Special handling of `==`, `|=`, `getClass` methods

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
437437
else if (tpw isRef defn.DoubleClass) Literal(Constant(0d))
438438
else if (tpw isRef defn.ByteClass) Literal(Constant(0.toByte))
439439
else if (tpw isRef defn.ShortClass) Literal(Constant(0.toShort))
440+
else if (tpw.isPhantom) Literal(Constant(null)).withType(tpw)
440441
else Literal(Constant(null)).select(defn.Any_asInstanceOf).appliedToType(tpe)
441442
}
442443

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,21 +1109,15 @@ class Definitions {
11091109

11101110
val any = enterCompleteClassSymbol(cls, tpnme.Any, Protected | Final | NoInitsTrait, Nil)
11111111
val nothing = enterCompleteClassSymbol(cls, tpnme.Nothing, Protected | Final | NoInitsTrait, List(any.typeRef))
1112-
enterMethod(cls, nme.assume_, ExprType(nothing.typeRef), Protected | Final | Method)
1112+
enterMethod(cls, nme.assume_, ExprType(nothing.typeRef), Protected | Final | Method | Unused)
11131113

11141114
cls
11151115
}
11161116
lazy val Phantom_AnyClass = PhantomClass.unforcedDecls.find(_.name eq tpnme.Any).asClass
11171117
lazy val Phantom_NothingClass = PhantomClass.unforcedDecls.find(_.name eq tpnme.Nothing).asClass
1118-
lazy val Phantom_assume = PhantomClass.unforcedDecls.find(_.name eq nme.assume_)
11191118

11201119
/** If the symbol is of the class scala.Phantom.Any or scala.Phantom.Nothing */
11211120
def isPhantomTerminalClass(sym: Symbol) = (sym eq Phantom_AnyClass) || (sym eq Phantom_NothingClass)
11221121

1123-
11241122
lazy val ErasedPhantomType: TypeRef = ctx.requiredClassRef("dotty.runtime.ErasedPhantom")
1125-
def ErasedPhantomClass(implicit ctx: Context) = ErasedPhantomType.symbol.asClass
1126-
1127-
def ErasedPhantom_UNIT(implicit ctx: Context) = ErasedPhantomClass.linkedClass.requiredValue("UNIT")
1128-
11291123
}

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

Lines changed: 0 additions & 33 deletions
This file was deleted.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ case class Signature(paramsSig: List[TypeName], resSig: TypeName) {
8484
* to the parameter part of this signature.
8585
*/
8686
def prepend(params: List[Type], isJava: Boolean)(implicit ctx: Context) =
87-
Signature(params.collect { case p if !p.isPhantom => sigName(p, isJava) } ++ paramsSig, resSig)
87+
Signature(params.map(p => sigName(p, isJava)) ++ paramsSig, resSig)
8888

8989
/** A signature is under-defined if its paramsSig part contains at least one
9090
* `tpnme.Uninstantiated`. Under-defined signatures arise when taking a signature

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
378378
else if (semiEraseVCs && isDerivedValueClass(sym)) eraseDerivedValueClassRef(tp)
379379
else if (sym == defn.ArrayClass) apply(tp.appliedTo(TypeBounds.empty)) // i966 shows that we can hit a raw Array type.
380380
else if (defn.isSyntheticFunctionClass(sym)) defn.erasedFunctionType(sym)
381-
else if (defn.isPhantomTerminalClass(sym)) PhantomErasure.erasedPhantomType
381+
else if (defn.isPhantomTerminalClass(sym)) defn.ErasedPhantomType
382382
else if (sym eq defn.PhantomClass) defn.ObjectType // To erase the definitions of Phantom.{assume, Any, Nothing}
383383
else eraseNormalClassRef(tp)
384384
case tp: AppliedType =>
@@ -399,10 +399,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
399399
case tp: MethodType =>
400400
def paramErasure(tpToErase: Type) =
401401
erasureFn(tp.isJavaMethod, semiEraseVCs, isConstructor, wildcardOK)(tpToErase)
402-
val (names, formals0) =
403-
if (tp.isUnusedMethod) (Nil, Nil)
404-
else if (tp.paramInfos.exists(_.isPhantom)) tp.paramNames.zip(tp.paramInfos).filterNot(_._2.isPhantom).unzip
405-
else (tp.paramNames, tp.paramInfos)
402+
val (names, formals0) = if (tp.isUnusedMethod) (Nil, Nil) else (tp.paramNames, tp.paramInfos)
406403
val formals = formals0.mapConserve(paramErasure)
407404
eraseResult(tp.resultType) match {
408405
case rt: MethodType =>
@@ -520,8 +517,6 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
520517
}
521518
if (defn.isSyntheticFunctionClass(sym))
522519
sigName(defn.erasedFunctionType(sym))
523-
else if (defn.isPhantomTerminalClass(tp.symbol))
524-
sigName(PhantomErasure.erasedPhantomType)
525520
else
526521
normalizeClass(sym.asClass).fullName.asTypeName
527522
case tp: AppliedType =>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =
129129
// Produce aligned accessors and constructor parameters. We have to adjust
130130
// for any outer parameters, which are last in the sequence of original
131131
// parameter accessors but come first in the constructor parameter list.
132-
val accessors = cls.paramAccessors.filterNot(x => x.isSetter || x.info.resultType.classSymbol == defn.ErasedPhantomClass)
132+
val accessors = cls.paramAccessors.filterNot(x => x.isSetter)
133133
val vparamsWithOuterLast = vparams match {
134134
case vparam :: rest if vparam.name == nme.OUTER => rest ::: vparam :: Nil
135135
case _ => vparams

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

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import ValueClasses._
2828
import TypeUtils._
2929
import ExplicitOuter._
3030
import core.Mode
31-
import core.PhantomErasure
3231
import reporting.trace
3332

3433
class Erasure extends Phase with DenotTransformer {
@@ -210,8 +209,6 @@ object Erasure {
210209
val tree1 =
211210
if (tree.tpe isRef defn.NullClass)
212211
adaptToType(tree, underlying)
213-
else if (wasPhantom(underlying))
214-
PhantomErasure.erasedParameterRef
215212
else if (!(tree.tpe <:< tycon)) {
216213
assert(!(tree.tpe.typeSymbol.isPrimitiveValueClass))
217214
val nullTree = Literal(Constant(null))
@@ -427,16 +424,9 @@ object Erasure {
427424
}
428425
}
429426

430-
if ((origSym eq defn.Phantom_assume) || (origSym.is(Flags.ParamAccessor) && wasPhantom(pt)))
431-
PhantomErasure.erasedAssume
432-
else recur(typed(tree.qualifier, AnySelectionProto))
427+
recur(typed(tree.qualifier, AnySelectionProto))
433428
}
434429

435-
override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): tpd.Tree =
436-
if (tree.symbol eq defn.Phantom_assume) PhantomErasure.erasedAssume
437-
else if (tree.symbol.is(Flags.Param) && wasPhantom(tree.typeOpt)) PhantomErasure.erasedParameterRef
438-
else super.typedIdent(tree, pt)
439-
440430
override def typedThis(tree: untpd.This)(implicit ctx: Context): Tree =
441431
if (tree.symbol == ctx.owner.lexicallyEnclosingClass || tree.symbol.isStaticOwner) promote(tree)
442432
else {
@@ -496,11 +486,9 @@ object Erasure {
496486
.withType(defn.ArrayOf(defn.ObjectType))
497487
args0 = bunchedArgs :: Nil
498488
}
499-
// Arguments are phantom if an only if the parameters are phantom, guaranteed by the separation of type lattices
500-
val args1 = args0.filterConserve(arg => !wasPhantom(arg.typeOpt))
501-
assert(args1 hasSameLengthAs mt.paramInfos)
502-
val args2 = args1.zipWithConserve(mt.paramInfos)(typedExpr)
503-
untpd.cpy.Apply(tree)(fun1, args2) withType mt.resultType
489+
assert(args0 hasSameLengthAs mt.paramInfos)
490+
val args1 = args0.zipWithConserve(mt.paramInfos)(typedExpr)
491+
untpd.cpy.Apply(tree)(fun1, args1) withType mt.resultType
504492
case _ =>
505493
throw new MatchError(i"tree $tree has unexpected type of function ${fun1.tpe.widen}, was ${fun.typeOpt.widen}")
506494
}
@@ -561,11 +549,6 @@ object Erasure {
561549
rhs1 = untpd.Block(paramDefs, rhs1)
562550
}
563551
vparamss1 = vparamss1.mapConserve(_.filterConserve(!_.symbol.is(Flags.Unused)))
564-
vparamss1 = vparamss1.mapConserve(_.filterConserve(vparam => !wasPhantom(vparam.tpe)))
565-
if (sym.is(Flags.ParamAccessor) && wasPhantom(ddef.tpt.tpe)) {
566-
sym.resetFlag(Flags.ParamAccessor)
567-
rhs1 = PhantomErasure.erasedParameterRef
568-
}
569552
val ddef1 = untpd.cpy.DefDef(ddef)(
570553
tparams = Nil,
571554
vparamss = vparamss1,
@@ -680,7 +663,4 @@ object Erasure {
680663

681664
def takesBridges(sym: Symbol)(implicit ctx: Context) =
682665
sym.isClass && !sym.is(Flags.Trait | Flags.Package)
683-
684-
private def wasPhantom(tp: Type)(implicit ctx: Context): Boolean =
685-
tp.widenDealias.classSymbol eq defn.ErasedPhantomClass
686666
}

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,6 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
174174
} else ddef
175175
}
176176

177-
override def transformValDef(vdef: tpd.ValDef)(implicit ctx: Context): tpd.Tree = {
178-
if (vdef.tpt.tpe.isPhantom) {
179-
if (vdef.symbol.is(Mutable)) ctx.error("var fields cannot have Phantom types", vdef.pos)
180-
else if (vdef.symbol.hasAnnotation(defn.VolatileAnnot)) ctx.error("Phantom fields cannot be @volatile", vdef.pos)
181-
}
182-
vdef
183-
}
184-
185177
override def transformStats(trees: List[Tree])(implicit ctx: Context): List[Tree] =
186178
ast.Trees.flatten(reorderAndComplete(trees)(ctx.withPhase(thisPhase.next)))
187179

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ import Decorators._
107107
if (sym eq defn.NothingClass) Throw(Literal(Constant(null)))
108108
else if (sym eq defn.NullClass) Literal(Constant(null))
109109
else if (sym eq defn.BoxedUnitClass) ref(defn.BoxedUnit_UNIT)
110-
else if (sym eq defn.ErasedPhantomClass) ref(defn.ErasedPhantom_UNIT)
111110
else {
112111
assert(false, sym + " has no erased bottom tree")
113112
EmptyTree
@@ -120,11 +119,8 @@ import Decorators._
120119
def adaptToField(tree: Tree): Tree =
121120
if (tree.isEmpty) tree else tree.ensureConforms(field.info.widen)
122121

123-
def isErasableBottomField(cls: Symbol): Boolean = {
124-
// TODO: For Scala.js, return false if this field is in a js.Object unless it is an ErasedPhantomClass.
125-
!field.isVolatile &&
126-
((cls eq defn.NothingClass) || (cls eq defn.NullClass) || (cls eq defn.BoxedUnitClass) || (cls eq defn.ErasedPhantomClass))
127-
}
122+
def isErasableBottomField(cls: Symbol): Boolean =
123+
!field.isVolatile && ((cls eq defn.NothingClass) || (cls eq defn.NullClass) || (cls eq defn.BoxedUnitClass))
128124

129125
if (sym.isGetter) {
130126
var rhs = tree.rhs.changeOwnerAfter(sym, field, thisPhase)

0 commit comments

Comments
 (0)