Skip to content

Commit

Permalink
Remove scala.Phantom
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Feb 25, 2018
1 parent b567b8d commit 3aaac8d
Show file tree
Hide file tree
Showing 127 changed files with 54 additions and 1,933 deletions.
1 change: 0 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/tpd.scala
Expand Up @@ -442,7 +442,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
else if (tpw isRef defn.DoubleClass) Literal(Constant(0d))
else if (tpw isRef defn.ByteClass) Literal(Constant(0.toByte))
else if (tpw isRef defn.ShortClass) Literal(Constant(0.toShort))
else if (tpw.isPhantom) Literal(Constant(null)).withType(tpw)
else Literal(Constant(null)).select(defn.Any_asInstanceOf).appliedToType(tpe)
}

Expand Down
21 changes: 1 addition & 20 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Expand Up @@ -1161,8 +1161,7 @@ class Definitions {
NullClass,
NothingClass,
SingletonClass,
EqualsPatternClass,
PhantomClass)
EqualsPatternClass)

lazy val syntheticCoreClasses = syntheticScalaClasses ++ List(
EmptyPackageVal,
Expand Down Expand Up @@ -1191,22 +1190,4 @@ class Definitions {
}
}

// ----- Phantoms ---------------------------------------------------------

lazy val PhantomClass: ClassSymbol = {
val cls = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.Phantom, NoInitsTrait, List(AnyType)))

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

cls
}
lazy val Phantom_AnyClass = PhantomClass.unforcedDecls.find(_.name eq tpnme.Any).asClass
lazy val Phantom_NothingClass = PhantomClass.unforcedDecls.find(_.name eq tpnme.Nothing).asClass

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

lazy val ErasedPhantomType: TypeRef = ctx.requiredClassRef("dotty.runtime.ErasedPhantom")
}
1 change: 0 additions & 1 deletion compiler/src/dotty/tools/dotc/core/StdNames.scala
Expand Up @@ -241,7 +241,6 @@ object StdNames {
final val SourceFileATTR: N = "SourceFile"
final val SyntheticATTR: N = "Synthetic"

final val Phantom: N = "Phantom"

// ----- Term names -----------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Expand Up @@ -667,7 +667,7 @@ object SymDenotations {

/** Is this symbol a class references to which that are supertypes of null? */
final def isNullableClass(implicit ctx: Context): Boolean =
isClass && !isValueClass && !(this is ModuleClass) && symbol != defn.NothingClass && !defn.isPhantomTerminalClass(symbol)
isClass && !isValueClass && !(this is ModuleClass) && symbol != defn.NothingClass

/** Is this definition accessible as a member of tree with type `pre`?
* @param pre The type of the tree from which the selection is made
Expand Down
12 changes: 3 additions & 9 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Expand Up @@ -50,7 +50,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
private[this] var myAnyClass: ClassSymbol = null
private[this] var myNothingClass: ClassSymbol = null
private[this] var myNullClass: ClassSymbol = null
private[this] var myPhantomNothingClass: ClassSymbol = null
private[this] var myObjectClass: ClassSymbol = null
private[this] var myAnyType: TypeRef = null
private[this] var myNothingType: TypeRef = null
Expand All @@ -67,10 +66,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
if (myNullClass == null) myNullClass = defn.NullClass
myNullClass
}
def PhantomNothingClass = {
if (myPhantomNothingClass == null) myPhantomNothingClass = defn.Phantom_NothingClass
myPhantomNothingClass
}
def ObjectClass = {
if (myObjectClass == null) myObjectClass = defn.ObjectClass
myObjectClass
Expand Down Expand Up @@ -287,7 +282,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
if (recur(info1.alias, tp2)) return true
if (tp1.prefix.isStable) return false
case _ =>
if (tp1 eq NothingType) return tp1 == tp2.bottomType
if (tp1 eq NothingType) return true
}
thirdTry
case tp1: TypeParamRef =>
Expand Down Expand Up @@ -586,9 +581,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case _ => false
}
val sym1 = tp1.symbol
(sym1 eq NothingClass) && tp2.isValueTypeOrLambda && !tp2.isPhantom ||
(sym1 eq NullClass) && isNullable(tp2) ||
(sym1 eq PhantomNothingClass) && tp1.topType == tp2.topType
(sym1 eq NothingClass) && tp2.isValueTypeOrLambda ||
(sym1 eq NullClass) && isNullable(tp2)
}
case tp1 @ AppliedType(tycon1, args1) =>
compareAppliedType1(tp1, tycon1, args1)
Expand Down
2 changes: 0 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeErasure.scala
Expand Up @@ -380,8 +380,6 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
else if (semiEraseVCs && isDerivedValueClass(sym)) eraseDerivedValueClassRef(tp)
else if (sym == defn.ArrayClass) apply(tp.appliedTo(TypeBounds.empty)) // i966 shows that we can hit a raw Array type.
else if (defn.isSyntheticFunctionClass(sym)) defn.erasedFunctionType(sym)
else if (defn.isPhantomTerminalClass(sym)) defn.ErasedPhantomType
else if (sym eq defn.PhantomClass) defn.ObjectType // To erase the definitions of Phantom.{assume, Any, Nothing}
else eraseNormalClassRef(tp)
case tp: AppliedType =>
if (tp.tycon.isRef(defn.ArrayClass)) eraseArray(tp)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/TypeOps.scala
Expand Up @@ -42,7 +42,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
case pre: SuperType => toPrefix(pre.thistpe, cls, thiscls)
case _ =>
if (thiscls.derivesFrom(cls) && pre.baseType(thiscls).exists)
if (variance <= 0 && !isLegalPrefix(pre)) range(pre.bottomType, pre)
if (variance <= 0 && !isLegalPrefix(pre)) range(defn.NothingType, pre)
else pre
else if ((pre.termSymbol is Package) && !(thiscls is Package))
toPrefix(pre.select(nme.PACKAGE), cls, thiscls)
Expand Down
53 changes: 6 additions & 47 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Expand Up @@ -193,59 +193,18 @@ object Types {
}
}

/** Returns true if the type is a phantom type
* - true if XYZ extends scala.Phantom and this type is upper bounded XYZ.Any
* - false otherwise
*/
final def isPhantom(implicit ctx: Context): Boolean = phantomLatticeType.exists

/** Returns the top type of the lattice
* - XYX.Any if XYZ extends scala.Phantom and this type is upper bounded XYZ.Any
* - scala.Any otherwise
*/
final def topType(implicit ctx: Context): Type = {
val lattice = phantomLatticeType
if (lattice.exists) lattice.select(tpnme.Any)
else defn.AnyType
}

/** Returns the bottom type of the lattice
* - XYZ.Nothing if XYZ extends scala.Phantom and this type is upper bounded XYZ.Any
* - scala.Nothing otherwise
*/
final def bottomType(implicit ctx: Context): Type = {
val lattice = phantomLatticeType
if (lattice.exists) lattice.select(tpnme.Nothing)
else defn.NothingType
}

/** Is this type exactly Nothing (no vars, aliases, refinements etc allowed)? */
def isBottomType(implicit ctx: Context): Boolean = this match {
case tp: TypeRef =>
val sym = tp.symbol
(sym eq defn.NothingClass) || (sym eq defn.Phantom_NothingClass)
case tp: TypeRef => tp.symbol eq defn.NothingClass
case _ => false
}

/** Is this type exactly Any (no vars, aliases, refinements etc allowed)? */
def isTopType(implicit ctx: Context): Boolean = this match {
case tp: TypeRef =>
val sym = tp.symbol
(sym eq defn.AnyClass) || (sym eq defn.Phantom_AnyClass)
case tp: TypeRef => tp.symbol eq defn.AnyClass
case _ => false
}

/** Returns the type of the phantom lattice (i.e. the prefix of the phantom type)
* - XYZ if XYZ extends scala.Phantom and this type is upper bounded XYZ.Any
* - NoType otherwise
*/
private final def phantomLatticeType(implicit ctx: Context): Type = widen match {
case tp: ClassInfo if defn.isPhantomTerminalClass(tp.classSymbol) => tp.prefix
case tp: TypeProxy => tp.underlying.phantomLatticeType
case tp: AndOrType => tp.tp1.phantomLatticeType
case _ => NoType
}

/** Is this type a (possibly aliased) singleton type? */
def isSingleton(implicit ctx: Context) = dealias.isInstanceOf[SingletonType]

Expand Down Expand Up @@ -2860,7 +2819,7 @@ object Types {
val dropDependencies = new ApproximatingTypeMap {
def apply(tp: Type) = tp match {
case tp @ TermParamRef(thisLambdaType, _) =>
range(tp.bottomType, atVariance(1)(apply(tp.underlying)))
range(defn.NothingType, atVariance(1)(apply(tp.underlying)))
case _ => mapOver(tp)
}
}
Expand Down Expand Up @@ -4177,7 +4136,7 @@ object Types {
case Range(infoLo: TypeBounds, infoHi: TypeBounds) =>
assert(variance == 0)
if (!infoLo.isAlias && !infoHi.isAlias) propagate(infoLo, infoHi)
else range(tp.bottomType, tp.parent)
else range(defn.NothingType, tp.parent)
case Range(infoLo, infoHi) =>
propagate(infoLo, infoHi)
case _ =>
Expand Down Expand Up @@ -4209,7 +4168,7 @@ object Types {
else tp.derivedTypeBounds(lo, hi)

override protected def derivedSuperType(tp: SuperType, thistp: Type, supertp: Type) =
if (isRange(thistp) || isRange(supertp)) range(thistp.bottomType, thistp.topType)
if (isRange(thistp) || isRange(supertp)) range(defn.NothingType, defn.AnyType)
else tp.derivedSuperType(thistp, supertp)

override protected def derivedAppliedType(tp: AppliedType, tycon: Type, args: List[Type]): Type =
Expand Down Expand Up @@ -4246,7 +4205,7 @@ object Types {
if (distributeArgs(args, tp.typeParams))
range(tp.derivedAppliedType(tycon, loBuf.toList),
tp.derivedAppliedType(tycon, hiBuf.toList))
else range(tp.bottomType, tp.topType)
else range(defn.NothingType, defn.AnyType)
// TODO: can we give a better bound than `topType`?
}
}
Expand Down
Expand Up @@ -212,8 +212,6 @@ object GenericSignatures {
else
jsig(unboxedSeen, toplevel, primitiveOK)
}
else if (tp.isPhantom)
jsig(defn.ErasedPhantomType)
else if (sym.isClass)
classSig
else
Expand Down Expand Up @@ -242,7 +240,7 @@ object GenericSignatures {
// unused method parameters do not make it to the bytecode.
def effectiveParamInfoss(t: Type)(implicit ctx: Context): List[List[Type]] = t match {
case t: MethodType if t.isUnusedMethod => effectiveParamInfoss(t.resType)
case t: MethodType => t.paramInfos.filterNot(_.isPhantom) :: effectiveParamInfoss(t.resType)
case t: MethodType => t.paramInfos :: effectiveParamInfoss(t.resType)
case _ => Nil
}
val params = effectiveParamInfoss(mtpe).flatten
Expand Down
69 changes: 0 additions & 69 deletions compiler/src/dotty/tools/dotc/transform/PhantomArgLift.scala

This file was deleted.

2 changes: 0 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
Expand Up @@ -121,8 +121,6 @@ object ErrorReporting {
val expected1 = dropJavaMethod(expected)
if ((found1 eq found) != (expected eq expected1) && (found1 <:< expected1))
"\n(Note that Scala's and Java's representation of this type differs)"
else if (found.topType != expected.topType)
"\n(Note that the types are in different universes, see Phantom types)"
else if (ctx.settings.explainTypes.value)
"\n" + ctx.typerState.show + "\n" + TypeComparer.explained((found <:< expected)(_))
else
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Namer.scala
Expand Up @@ -1120,7 +1120,7 @@ class Namer { typer: Typer =>
val deskolemize = new ApproximatingTypeMap {
def apply(tp: Type) = /*trace(i"deskolemize($tp) at $variance", show = true)*/ {
tp match {
case tp: SkolemType => range(tp.bottomType, atVariance(1)(apply(tp.info)))
case tp: SkolemType => range(defn.NothingType, atVariance(1)(apply(tp.info)))
case _ => mapOver(tp)
}
}
Expand Down

0 comments on commit 3aaac8d

Please sign in to comment.