8000 Merge pull request #4439 from gzm0/use-type · scala-js/scala-js@bdfe1a0 · GitHub
[go: up one dir, main page]

Skip to content

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bdfe1a0

Browse files
authored
Merge pull request #4439 from gzm0/use-type
Base stat/expr checking on the type system in IRChecker
2 parents 95c6419 + 9015fc1 commit bdfe1a0

File tree

6 files changed

+230
-239
lines changed

6 files changed

+230
-239
lines changed

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,8 +2225,12 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
22252225
}
22262226

22272227
case If(cond, thenp, elsep) =>
2228+
val tpe =
2229+
if (isStat) jstpe.NoType
2230+
else toIRType(tree.tpe)
2231+
22282232
js.If(genExpr(cond), genStatOrExpr(thenp, isStat),
2229-
genStatOrExpr(elsep, isStat))(toIRType(tree.tpe))
2233+
genStatOrExpr(elsep, isStat))(tpe)
22302234

22312235
case Return(expr) =>
22322236
js.Return(toIRType(expr.tpe) match {
@@ -2690,7 +2694,10 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
26902694
val Try(block, catches, finalizer) = tree
26912695

26922696
val blockAST = genStatOrExpr(block, isStat)
2693-
val resultType = toIRType(tree.tpe)
2697+
2698+
val resultType =
2699+
if (isSt 8000 at) jstpe.NoType
2700+
else toIRType(tree.tpe)
26942701

26952702
val handled =
26962703
if (catches.isEmpty) blockAST

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

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,13 @@ object Serializers {
11991199
else Some(readParamDefs())
12001200
val superClass = readOptClassIdent()
12011201
val parents = readClassIdents()
1202+
1203+
/* jsSuperClass is not hacked like in readMemberDef.bodyHack15. The
1204+
* compilers before 1.6 always use a simple VarRef() as jsSuperClass,
1205+
* when there is one, so no hack is required.
1206+
*/
12021207
val jsSuperClass = readOptTree()
1208+
12031209
val jsNativeLoadSpec = readJSNativeLoadSpec()
12041210
val memberDefs = readMemberDefs(name.name, kind)
12051211
val topL 8000 evelExportDefs = readTopLevelExportDefs(name.name, kind)
@@ -1213,6 +1219,35 @@ object Serializers {
12131219
implicit val pos = readPosition()
12141220
val tag = readByte()
12151221

1222+
def bodyHack15(body: Tree, isStat: Boolean): Tree = {
1223+
if (!hacks.use15) {
1224+
body
1225+
} else {
1226+
// #4442 Patch If and TryCatch nodes in statement position to have type NoType
1227+
new Transformers.Transformer {
1228+
override def transform(tree: Tree, isStat: Boolean): Tree = {
1229+
val newTree = super.transform(tree, isStat)
1230+
if (isStat && newTree.tpe != NoType) {
1231+
newTree match {
1232+
case If(cond, thenp, elsep) =>
1233+
If(cond, thenp, elsep)(NoType)(newTree.pos)
1234+
case Match(selector, cases, default) =>
1235+
Match(selector, cases, default)(NoType)(newTree.pos)
1236+
case TryCatch(block, errVar, errVarOriginalName, handler) =>
1237+
TryCatch(block, errVar, errVarOriginalName, handler)(NoType)(newTree.pos)
1238+
case _ =>
1239+
newTree
1240+
}
1241+
} else {
1242+
newTree
1243+
}
1244+
}
1245+
}.transform(body, isStat)
1246+
}
1247+
}
1248+
1249+
def bodyHack15Expr(body: Tree): Tree = bodyHack15(body, isStat = false)
1250+
12161251
(tag: @switch) match {
12171252
case TagFieldDef =>
12181253
val flags = MemberFlags.fromBits(readInt())
@@ -1312,7 +1347,8 @@ object Serializers {
13121347
MethodDef(flags, name, originalName, args, resultType, patchedBody)(
13131348
patchedOptimizerHints, optHash)
13141349
} else {
1315-
MethodDef(flags, name, originalName, args, resultType, body)(
1350+
val patchedBody = body.map(bodyHack15(_, isStat = resultType == NoType))
1351+
MethodDef(flags, name, originalName, args, resultType, patchedBody)(
13161352
optimizerHints, optHash)
13171353
}
13181354

@@ -1324,18 +1360,19 @@ object Serializers {
13241360
assert(len >= 0)
13251361

13261362
val flags = MemberFlags.fromBits(readInt())
1327-
val name = readTree()
1363+
val name = bodyHack15Expr(readTree())
13281364
val (params, restParam) = readParamDefsWithRest()
1329-
JSMethodDef(flags, name, params, restParam, readTree())(
1365+
val body = bodyHack15Expr(readTree())
1366+
JSMethodDef(flags, name, params, restParam, body)(
13301367
OptimizerHints.fromBits(readInt()), optHash)
13311368

13321369
case TagJSPropertyDef =>
13331370
val flags = MemberFlags.fromBits(readInt())
1334-
val name = readTree()
1335-
val getterBody = readOptTree()
1371+
val name = bodyHack15Expr(readTree())
1372+
val getterBody = readOptTree().map(bodyHack15Expr(_))
13361373
val setterArgAndBody = {
13371374
if (readBoolean())
1338-
Some((readParamDef(), readTree()))
1375+
Some((readParamDef(), bodyHack15Expr(readTree())))
13391376
else
13401377
None
13411378
}
@@ -1752,6 +1789,8 @@ object Serializers {
17521789
private val use13: Boolean = use12 || sourceVersion == "1.3"
17531790

17541791
val use14: Boolean = use13 || sourceVersion == "1.4"
1792+
1793+
val use15: Boolean = use14 || sourceVersion == "1.5"
17551794
}
17561795

17571796
/** Names needed for hacks. */

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

Lines changed: 62 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -289,78 +289,75 @@ object Types {
289289
}
290290

291291
/** Tests whether a type `lhs` is a subtype of `rhs` (or equal).
292-
* [[NoType]] is never a subtype or supertype of anything (including
293-
* itself). All other types are subtypes of themselves.
294292
* @param isSubclass A function testing whether a class/interface is a
295293
* subclass of another class/interface.
296294
*/
297295
def isSubtype(lhs: Type, rhs: Type)(
298296
isSubclass: (ClassName, ClassName) => Boolean): Boolean = {
299-
300-
(lhs != NoType && rhs != NoType) && {
301-
(lhs == rhs) ||
302-
((lhs, rhs) match {
303-
case (_, AnyType) => true
304-
case (NothingType, _) => true
305-
306-
case (ClassType(lhsClass), ClassType(rhsClass)) =>
307-
isSubclass(lhsClass, rhsClass)
308-
309-
case (NullType, ClassType(_)) => true
310-
case (NullType, ArrayType(_)) => true
311-
312-
case (UndefType, ClassType(className)) =>
313-
isSubclass(BoxedUnitClass, className)
314-
case (BooleanType, ClassType(className)) =>
315-
isSubclass(BoxedBooleanClass, className)
316-
case (CharType, ClassType(className)) =>
317-
isSubclass(BoxedCharacterClass, className)
318-
case (ByteType, ClassType(className)) =>
319-
isSubclass(BoxedByteClass, className)
320-
case (ShortType, ClassType(className)) =>
321-
isSubclass(BoxedShortClass, className)
322-
case (IntType, ClassType(className)) =>
323-
isSubclass(BoxedIntegerClass, className)
324-
case (LongType, ClassType(className)) =>
325-
isSubclass(BoxedLongClass, className)
326-
case (FloatType, ClassType(className)) =>
327-
isSubclass(BoxedFloatClass, className)
328-
case (DoubleType, ClassType(className)) =>
329-
isSubclass(BoxedDoubleClass, className)
330-
case (StringType, ClassType(className)) =>
331-
isSubclass(BoxedStringClass, className)
332-
333-
case (ArrayType(ArrayTypeRef(lhsBase, lhsDims)),
334-
ArrayType(ArrayTypeRef(rhsBase, rhsDims))) =>
335-
if (lhsDims < rhsDims) {
336-
false // because Array[A] </: Array[Array[A]]
337-
} else if (lhsDims > rhsDims) {
338-
rhsBase match {
339-
case ClassRef(ObjectClass) =>
340-
true // because Array[Array[A]] <: Array[Object]
341-
case _ =>
342-
false
343-
}
344-
} else { // lhsDims == rhsDims
345-
// lhsBase must be <: rhsBase
346-
(lhsBase, rhsBase) match {
347-
case (ClassRef(lhsBaseName), ClassRef(rhsBaseName)) =>
348-
/* All things must be considered subclasses of Object for this
349-
* purpose, even JS types and interfaces, which do not have
350-
* Object in their ancestors.
351-
*/
352-
rhsBaseName == ObjectClass || isSubclass(lhsBaseName, rhsBaseName)
353-
case _ =>
354-
lhsBase eq rhsBase
355-
}
297+
(lhs == rhs) ||
298+
((lhs, rhs) < F987 span class="pl-k">match {
299+
case (_, NoType) => true
300+
case (NoType, _) => false
301+
case (_, AnyType) => true
302+
case (NothingType, _) => true
303+
304+
case (ClassType(lhsClass), ClassType(rhsClass)) =>
305+
isSubclass(lhsClass, rhsClass)
306+
307+
case (NullType, ClassType(_)) => true
308+
case (NullType, ArrayType(_)) => true
309+
310+
case (UndefType, ClassType(className)) =>
311+
isSubclass(BoxedUnitClass, className)
312+
case (BooleanType, ClassType(className)) =>
313+
isSubclass(BoxedBooleanClass, className)
314+
case (CharType, ClassType(className)) =>
315+
isSubclass(BoxedCharacterClass, className)
316+
case (ByteType, ClassType(className)) =>
317+
isSubclass(BoxedByteClass, className)
318+
case (ShortType, ClassType(className)) =>
319+
isSubclass(BoxedShortClass, className)
320+
case (IntType, ClassType(className)) =>
321+
isSubclass(BoxedIntegerClass, className)
322+
case (LongType, ClassType(className)) =>
323+
isSubclass(BoxedLongClass, className)
324+
case (FloatType, ClassType(className)) =>
325+
isSubclass(BoxedFloatClass, className)
326+
case (DoubleType, ClassType(className)) =>
327+
isSubclass(BoxedDoubleClass, className)
328+
case (StringType, ClassType(className)) =>
329+
isSubclass(BoxedStringClass, className)
330+
331+
case (ArrayType(ArrayTypeRef(lhsBase, lhsDims)),
332+
ArrayType(ArrayTypeRef(rhsBase, rhsDims))) =>
333+
if (lhsDims < rhsDims) {
334+
false // because Array[A] </: Array[Array[A]]
335+
} else if (lhsDims > rhsDims) {
336+
rhsBase match {
337+
case ClassRef(ObjectClass) =>
338+
true // because Array[Array[A]] <: Array[Object]
339+
case _ =>
340+
false
341+
}
342+
} else { // lhsDims == rhsDims
343+
// lhsBase must be <: rhsBase
344+
(lhsBase, rhsBase) match {
345+
case (ClassRef(lhsBaseName), ClassRef(rhsBaseName)) =>
346+
/* All things must be considered subclasses of Object for this
347+
* purpose, even JS types and interfaces, which do not have
348+
* Object in their ancestors.
349+
*/
350+
rhsBaseName == ObjectClass || isSubclass(lhsBaseName, rhsBaseName)
351+
case _ =>
352+
lhsBase eq rhsBase
356353
}
354+
}
357355

358-
case (ArrayType(_), ClassType(className)) =>
359-
AncestorsOfPseudoArrayClass.contains(className)
356+
case (ArrayType(_), ClassType(className)) =>
357+
AncestorsOfPseudoArrayClass.contains(className)
360358

361-
case _ =>
362-
false
363-
})
364-
}
359+
case _ =>
360+
false
361+
})
365362
}
366363
}

0 commit comments

Comments
 (0)
0