Skip to content

Commit a0dd1e4

Browse files
committed
Add a notNull field to Any
1 parent d027f6a commit a0dd1e4

File tree

4 files changed

+19
-3
lines changed

4 files changed

+19
-3
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ class Definitions {
254254
List(AnyClass.typeRef, NotNullClass.typeRef)))
255255
def AnyValType: TypeRef = AnyValClass.typeRef
256256

257-
@tu lazy val Any_== : TermSymbol = enterMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final)
257+
@tu lazy val Any_== : TermSymbol = enterMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final)
258258
@tu lazy val Any_!= : TermSymbol = enterMethod(AnyClass, nme.NE, methOfAny(BooleanType), Final)
259259
@tu lazy val Any_equals: TermSymbol = enterMethod(AnyClass, nme.equals_, methOfAny(BooleanType))
260260
@tu lazy val Any_hashCode: TermSymbol = enterMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType))
@@ -264,7 +264,8 @@ class Definitions {
264264
@tu lazy val Any_asInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, _.paramRefs(0), Final)
265265
@tu lazy val Any_typeTest: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOfPM, _ => BooleanType, Final | Synthetic | Artifact)
266266
@tu lazy val Any_typeCast: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOfPM, _.paramRefs(0), Final | Synthetic | Artifact | StableRealizable)
267-
// generated by pattern matcher, eliminated by erasure
267+
@tu lazy val Any_notNull: TermSymbol = newSymbol(AnyClass, nme._nn, Final | Erased, AndType(AnyClass.thisType, NotNullClass.typeRef)).entered
268+
// generated by pattern matcher, eliminated by erasure
268269

269270
/** def getClass[A >: this.type](): Class[? <: A] */
270271
@tu lazy val Any_getClass: TermSymbol =
@@ -275,7 +276,7 @@ class Definitions {
275276
bounds = TypeBounds.lower(AnyClass.thisType))
276277

277278
private def AnyMethods: List[TermSymbol] = List(Any_==, Any_!=, Any_equals, Any_hashCode,
278-
Any_toString, Any_##, Any_getClass, Any_isInstanceOf, Any_asInstanceOf, Any_typeTest, Any_typeCast)
279+
Any_toString, Any_##, Any_getClass, Any_isInstanceOf, Any_asInstanceOf, Any_typeTest, Any_typeCast, Any_notNull)
279280

280281
@tu lazy val ObjectClass: ClassSymbol = {
281282
val cls = ctx.requiredClass("java.lang.Object")

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ object StdNames {
493493
val name: N = "name"
494494
val nameDollar: N = "$name"
495495
val ne: N = "ne"
496+
val _nn: N = "$nn"
496497
val newFreeTerm: N = "newFreeTerm"
497498
val newFreeType: N = "newFreeType"
498499
val newScopeWith: N = "newScopeWith"

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ object Erasure {
426426
* e.m -> e.[]m if `m` is an array operation other than `clone`.
427427
*/
428428
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
429+
if tree.symbol == defn.Any_notNull then return typed(tree.qualifier, pt)
430+
429431
val qual1 = typed(tree.qualifier, AnySelectionProto)
430432

431433
def mapOwner(sym: Symbol): Symbol = {

tests/pos/notNull.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,16 @@ object Test with
1818
val y = notNull(identity(x)); val yc: Int = y
1919
val z = notNull(x); val zc: Int = z
2020
}
21+
locally {
22+
val x: Int | Null = ???
23+
val y = identity(x).$nn; val yc: Int = y
24+
val z = x.$nn; val zc: Int = z
25+
}
26+
class C { type T }
27+
locally {
28+
val x: C { type T = Int } = new C { type T = Int }
29+
val y: x.$nn.T = 33
30+
val z = y; val zc: Int = z
31+
}
32+
2133

0 commit comments

Comments
 (0)