Skip to content

Commit 9920e23

Browse files
committed
Fix phantom Nothing.
1 parent eb69396 commit 9920e23

File tree

3 files changed

+32
-12
lines changed

3 files changed

+32
-12
lines changed

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -551,14 +551,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
551551
case OrType(tp1, tp2) => isNullable(tp1) || isNullable(tp2)
552552
case _ => false
553553
}
554-
def isPhantom(tp: Type): Boolean = tp.widenDealias match {
555-
case tp: TypeRef => defn.isPhantomAnyClass(tp.symbol)
556-
case tp: RefinedOrRecType => isPhantom(tp.parent)
557-
case tp: AndOrType => isPhantom(tp.tp1)
558-
case _ => false
559-
}
560-
if (tp1.symbol eq NothingClass) tp2.isValueTypeOrLambda && !isPhantom(tp2)
561-
else if (tp1.symbol eq NullClass) isNullable(tp2) && !isPhantom(tp2)
554+
if (tp1.symbol eq NothingClass) tp2.isValueTypeOrLambda && (tp2.topType.classSymbol eq AnyClass)
555+
else if (tp1.symbol eq NullClass) isNullable(tp2) && (tp2.topType.classSymbol eq AnyClass)
562556
else if (defn.isPhantomNothingClass(tp1.symbol)) tp2.isValueTypeOrLambda && (tp1.topType == tp2.topType)
563557
else false
564558
}

compiler/src/dotty/tools/dotc/transform/phantom/PhantomTypeErasure.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@ class PhantomTypeErasure extends MiniPhaseTransform with InfoTransformer {
3838
private def erasePhantomAnyType(tp: Type)(implicit ctx: Context): Type = {
3939
val erasePhantomAnyTypeMap = new DeepTypeMap {
4040
override def apply(tp: Type): Type = tp match {
41-
case tp: TypeRef if defn.isPhantomAnyClass(tp.symbol) || defn.isPhantomNothingClass(tp.symbol) =>
42-
defn.ErasedPhantomType
43-
case tp: TypeRef if tp.typeSymbol eq defn.PhantomClass =>
44-
defn.ErasedPhantomLatticeType
41+
case tp: TypeRef =>
42+
val sym = tp.classSymbol
43+
if (defn.isPhantomAnyClass(sym) || defn.isPhantomNothingClass(sym)) defn.ErasedPhantomType
44+
else if (sym eq defn.PhantomClass) defn.ErasedPhantomLatticeType
45+
else mapOver(tp)
4546
case tp: MethodType if tp.resultType.isPhantom =>
4647
// Erase return type to Object to match FunctionN erased return type
4748
val methodType = if (tp.isImplicit) ImplicitMethodType else MethodType

tests/neg/phantom-bottom.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
class BooFunDef1 {
3+
import Boo._
4+
5+
def fun0(x: Foo): x.Y = Boo.nothing
6+
7+
def fun1(x: Foo): x.Y = ??? // error
8+
def fun2(x: Foo): x.Y = null // error
9+
def fun3(x: Foo): x.Y = Boo2.nothing // error
10+
}
11+
12+
class Foo {
13+
type Y <: Boo.BooAny
14+
}
15+
16+
object Boo extends Phantom {
17+
type BooAny = this.Any
18+
type BooNothing = this.Nothing
19+
def nothing: BooNothing = assume[BooNothing]
20+
}
21+
22+
object Boo2 extends Phantom {
23+
type BooNothing2 = this.Nothing
24+
def nothing: BooNothing2 = assume[BooNothing2]
25+
}

0 commit comments

Comments
 (0)