Skip to content

Commit 972effe

Browse files
committed
Adapt the compiler to generate non-nullable types.
For `This` nodes and `IsInstanceOf` nodes. We only active the relevant deserialization hacks when reading IR from before 1.17.
1 parent fed13a7 commit 972effe

File tree

4 files changed

+26
-19
lines changed

4 files changed

+26
-19
lines changed

compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,19 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
152152
private val fieldsMutatedInCurrentClass = new ScopedVar[mutable.Set[Name]]
153153
private val generatedSAMWrapperCount = new ScopedVar[VarBox[Int]]
154154

155+
def currentThisTypeNullable: jstpe.Type =
156+
encodeClassType(currentClassSym)
157+
155158
def currentThisType: jstpe.Type = {
156-
encodeClassType(currentClassSym) match {
159+
currentThisTypeNullable match {
157160
case tpe @ jstpe.ClassType(cls, _) =>
158-
jstpe.BoxedClassToPrimType.getOrElse(cls, tpe)
159-
case tpe =>
161+
jstpe.BoxedClassToPrimType.getOrElse(cls, tpe.toNonNullable)
162+
case tpe @ jstpe.AnyType =>
163+
// We are in a JS class, in which even `this` is nullable
160164
tpe
165+
case tpe =>
166+
throw new AssertionError(
167+
s"Unexpected IR this type $tpe for class ${currentClassSym.get}")
161168
}
162169
}
163170

@@ -2125,7 +2132,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
21252132
mutableLocalVars += thisSym
21262133

21272134
val thisLocalIdent = encodeLocalSym(thisSym)
2128-
val thisLocalType = currentThisType
2135+
val thisLocalType = currentThisTypeNullable
21292136

21302137
val genRhs = {
21312138
/* #3267 In default methods, scalac will type its _$this
@@ -2222,7 +2229,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
22222229
* @param tree
22232230
* The tree to adapt.
22242231
* @param tpe
2225-
* The target type, which must be either `AnyType` or `ClassType(_)`.
2232+
* The target type, which must be either `AnyType` or `ClassType`.
22262233
*/
22272234
private def forceAdapt(tree: js.Tree, tpe: jstpe.Type): js.Tree = {
22282235
if (tree.tpe == tpe || tpe == jstpe.AnyType) {
@@ -2670,7 +2677,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
26702677
js.This()(currentThisType)
26712678
} { thisLocalIdent =>
26722679
// .copy() to get the correct position
2673-
js.VarRef(thisLocalIdent.copy())(currentThisType)
2680+
js.VarRef(thisLocalIdent.copy())(currentThisTypeNullable)
26742681
}
26752682
}
26762683

@@ -3333,7 +3340,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
33333340
val isTailJumpThisLocalVar = formalArgSym.name == nme.THIS
33343341

33353342
val tpe =
3336-
if (isTailJumpThisLocalVar) currentThisType
3343+
if (isTailJumpThisLocalVar) currentThisTypeNullable
33373344
else toIRType(formalArgSym.tpe)
33383345

33393346
val fixedActualArg =
@@ -3561,7 +3568,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
35613568
// The Scala type system prevents x.isInstanceOf[Null] and ...[Nothing]
35623569
assert(sym != NullClass && sym != NothingClass,
35633570
s"Found a .isInstanceOf[$sym] at $pos")
3564-
js.IsInstanceOf(value, toIRType(to))
3571+
js.IsInstanceOf(value, toIRType(to).toNonNullable)
35653572
}
35663573
}
35673574

@@ -6334,7 +6341,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
63346341
}
63356342
val className = encodeClassName(currentClassSym).withSuffix(suffix)
63366343

6337-
val classType = jstpe.ClassType(className)
6344+
val thisType = jstpe.ClassType(className, nullable = false)
63386345

63396346
// val f: Any
63406347
val fFieldIdent = js.FieldIdent(FieldName(className, SimpleFieldName("f")))
@@ -6353,10 +6360,10 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
63536360
jstpe.NoType,
63546361
Some(js.Block(List(
63556362
js.Assign(
6356-
js.Select(js.This()(classType), fFieldIdent)(jstpe.AnyType),
6363+
js.Select(js.This()(thisType), fFieldIdent)(jstpe.AnyType),
63576364
fParamDef.ref),
63586365
js.ApplyStatically(js.ApplyFlags.empty.withConstructor(true),
6359-
js.This()(classType),
6366+
js.This()(thisType),
63606367
ir.Names.ObjectClass,
63616368
js.MethodIdent(ir.Names.NoArgConstructorName),
63626369
Nil)(jstpe.NoType)))))(
@@ -6404,7 +6411,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
64046411
}.map((ensureBoxed _).tupled)
64056412

64066413
val call = js.JSFunctionApply(
6407-
js.Select(js.This()(classType), fFieldIdent)(jstpe.AnyType),
6414+
js.Select(js.This()(thisType), fFieldIdent)(jstpe.AnyType),
64086415
actualParams)
64096416

64106417
val body = fromAny(call, enteringPhase(currentRun.posterasurePhase) {

compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
930930

931931
private sealed abstract class RTTypeTest
932932

933-
private case class PrimitiveTypeTest(tpe: jstpe.Type, rank: Int)
933+
private case class PrimitiveTypeTest(tpe: jstpe.PrimType, rank: Int)
934934
extends RTTypeTest
935935

936936
// scalastyle:off equals.hash.code

ir/shared/src/main/scala/org/scalajs/ir/Serializers.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,7 +1234,7 @@ object Serializers {
12341234
case TagIsInstanceOf =>
12351235
val expr = readTree()
12361236
val testType0 = readType()
1237-
val testType = if (true /* hacks.use16 */) { // scalastyle:ignore
1237+
val testType = if (hacks.use16) {
12381238
testType0 match {
12391239
case ClassType(className, true) => ClassType(className, nullable = false)
12401240
case ArrayType(arrayTypeRef, true) => ArrayType(arrayTypeRef, nullable = false)
@@ -1298,7 +1298,7 @@ object Serializers {
12981298

12991299
case TagThis =>
13001300
val tpe = readType()
1301-
if (true /* hacks.use16 */) // scalastyle:ignore
1301+
if (hacks.use16)
13021302
This()(thisTypeForHack)
13031303
else
13041304
This()(tpe)
@@ -1307,7 +1307,7 @@ object Serializers {
13071307
val arrow = readBoolean()
13081308
val captureParams = readParamDefs()
13091309
val (params, restParam) = readParamDefsWithRest()
1310-
val body = if (false /* !hacks.use16 */) { // scalastyle:ignore
1310+
val body = if (!hacks.use16) {
13111311
readTree()
13121312
} else {
13131313
val prevThisTypeForHack = thisTypeForHack
@@ -1416,7 +1416,7 @@ object Serializers {
14161416
val originalName = readOriginalName()
14171417
val kind = ClassKind.fromByte(readByte())
14181418

1419-
if (true /* hacks.use16 */) { // scalastyle:ignore
1419+
if (hacks.use16) {
14201420
thisTypeForHack = {
14211421
if (kind.isJSType)
14221422
AnyType

project/JavaLangObject.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ object JavaLangObject {
2626
implicit val DummyPos = NoPosition
2727

2828
// ClassType(Object) is normally invalid, but not in this class def
29-
val ThisType = ClassType(ObjectClass)
29+
val ThisType = ClassType(ObjectClass, nullable = false)
3030

3131
val ObjectClassRef = ClassRef(ObjectClass)
3232
val ClassClassRef = ClassRef(ClassClass)
@@ -101,7 +101,7 @@ object JavaLangObject {
101101
Nil,
102102
AnyType,
103103
Some {
104-
If(IsInstanceOf(This()(ThisType), ClassType(CloneableClass)), {
104+
If(IsInstanceOf(This()(ThisType), ClassType(CloneableClass, nullable = false)), {
105105
Clone(AsInstanceOf(This()(ThisType), ClassType(CloneableClass)))
106106
}, {
107107
Throw(New(ClassName("java.lang.CloneNotSupportedException"),

0 commit comments

Comments
 (0)