Skip to content

Change/drop not null #277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 13, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
* - otherwise, if T is a type paramter coming from Java, []Object
* - otherwise, Object
* - For a term ref p.x, the type <noprefix> # x.
* - For a typeref scala.Any, scala.AnyVal, scala.Singleon or scala.NotNull: |java.lang.Object|
* - For a typeref scala.Any, scala.AnyVal or scala.Singleton: |java.lang.Object|
* - For a typeref scala.Unit, |scala.runtime.BoxedUnit|.
* - For a typeref P.C where C refers to a class, <noprefix> # C.
* - For a typeref P.C where C refers to an alias type, the erasure of C's alias.
Expand Down Expand Up @@ -374,7 +374,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild

private def normalizeClass(cls: ClassSymbol)(implicit ctx: Context): ClassSymbol = {
if (cls.owner == defn.ScalaPackageClass) {
if (cls == defn.AnyClass || cls == defn.AnyValClass || cls == defn.SingletonClass || cls == defn.NotNullClass)
if (cls == defn.AnyClass || cls == defn.AnyValClass || cls == defn.SingletonClass)
return defn.ObjectClass
if (cls == defn.UnitClass)
return defn.BoxedUnitClass
Expand Down
1 change: 0 additions & 1 deletion src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ class ScalaSettings extends Settings.SettingGroup {
val Ybuilderdebug = ChoiceSetting("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none")
val Yreifycopypaste = BooleanSetting("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
val Yreplsync = BooleanSetting("-Yrepl-sync", "Do not use asynchronous code for repl startup")
val Ynotnull = BooleanSetting("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.")
val YmethodInfer = BooleanSetting("-Yinfer-argument-types", "Infer types for arguments of overriden methods.")
val etaExpandKeepsStar = BooleanSetting("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.")
val Yinvalidate = StringSetting("-Yinvalidate", "classpath-entry", "Invalidate classpath entry before run", "")
Expand Down
3 changes: 0 additions & 3 deletions src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ class Definitions {
RootClass, nme.dummyApply, 1,
pt => MethodType(List(FunctionType(Nil, PolyParam(pt, 0))), PolyParam(pt, 0)))

lazy val NotNullClass = ctx.requiredClass("scala.NotNull")

lazy val NothingClass: ClassSymbol = newCompleteClassSymbol(
ScalaPackageClass, tpnme.Nothing, AbstractFinal, List(AnyClass.typeRef))
lazy val NullClass: ClassSymbol = newCompleteClassSymbol(
Expand Down Expand Up @@ -348,7 +346,6 @@ class Definitions {
def AnyValType: Type = AnyValClass.typeRef
def ObjectType: Type = ObjectClass.typeRef
def AnyRefType: Type = AnyRefAlias.typeRef
def NotNullType: Type = NotNullClass.typeRef
def NothingType: Type = NothingClass.typeRef
def NullType: Type = NullClass.typeRef
def SeqType: Type = SeqClass.typeRef
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ object SymDenotations {

/** Is this symbol a class references to which that are supertypes of null? */
final def isNullableClass(implicit ctx: Context): Boolean =
isNonValueClass && !(this is ModuleClass) // todo: check that class does not derive from NotNull?
isNonValueClass && !(this is ModuleClass)

/** 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
10 changes: 7 additions & 3 deletions src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,7 @@ class TypeComparer(initctx: Context) extends DotClass {
if (cls2.isClass) {
val base = tp1.baseTypeRef(cls2)
if (base.exists && (base ne tp1)) return isSubType(base, tp2)
if ( cls2 == defn.SingletonClass && tp1.isStable
|| cls2 == defn.NotNullClass && tp1.isNotNull) return true
if (cls2 == defn.SingletonClass && tp1.isStable) return true
}
tryRebase3rd
}
Expand Down Expand Up @@ -777,8 +776,13 @@ class TypeComparer(initctx: Context) extends DotClass {
case TypeBounds(lo1, hi1) =>
isSubType(hi1, tp2)
case _ =>
def isNullable(tp: Type): Boolean = tp.dealias match {
case tp: TypeRef => tp.symbol.isNullableClass
case RefinedType(parent, _) => isNullable(parent)
case _ => false
}
(tp1.symbol eq NothingClass) && tp2.isInstanceOf[ValueType] ||
(tp1.symbol eq NullClass) && tp2.dealias.typeSymbol.isNullableClass
(tp1.symbol eq NullClass) && isNullable(tp2)
}
case tp1: SingletonType =>
isNewSubType(tp1.underlying.widenExpr, tp2) || {
Expand Down
19 changes: 19 additions & 0 deletions tests/pos/i262-null-subtyping.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
object O {
// This compiles
val a: { type T } = null;
val b: Any { type T } = null;

// This doesn't:
// found : Null
// required: AnyRef{T}
val c: AnyRef { type T } = null;

class A
class B

val d: A & B = null
val e: A | B = null

val f: (A & B) { def toString: String } = null
val g: (A | B) { def toString: String } = null
}