Skip to content

Commit 5a3ab17

Browse files
committed
Address reviewer feedback
1 parent 6d93b8b commit 5a3ab17

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@ import Contexts.Context, Types._, Constants._, Decorators._, Symbols._
88
import TypeUtils._, TypeErasure._
99

1010

11-
/** Implements partial `isInstanceOf` evaluation according to the matrix on:
12-
* https://github.com/lampepfl/dotty/issues/1255
11+
/** Implements partial evaluation of `sc.isInstanceOf[Sel]` according to:
12+
*
13+
* +-------------+----------------------------+----------------------------+------------------+
14+
* | Sel\sc | trait | class | final class |
15+
* +-------------+----------------------------+----------------------------+------------------+
16+
* | trait | ? | ? | statically known |
17+
* | class | ? | false if classes unrelated | statically known |
18+
* | final class | false if classes unrelated | false if classes unrelated | statically known |
19+
* +-------------+----------------------------+----------------------------+------------------+
1320
*
1421
* This is a generalized solution to raising an error on unreachable match
1522
* cases and warnings on other statically known results of `isInstanceOf`.
@@ -36,26 +43,28 @@ class IsInstanceOfEvaluator extends MiniPhaseTransform { thisTransformer =>
3643
* the correct warnings, or an error if statically known to be false in
3744
* match
3845
*/
39-
def handleStaticallyKnown(tree: Select, scrutinee: Type, selector: Type, inMatch: Boolean, pos: Position): Tree =
40-
if (!(scrutinee <:< selector) && inMatch) {
46+
def handleStaticallyKnown(tree: Select, scrutinee: Type, selector: Type, inMatch: Boolean, pos: Position): Tree = {
47+
val scrutineeSubSelector = scrutinee <:< selector
48+
if (!scrutineeSubSelector && inMatch) {
4149
ctx.error(
4250
s"this case is unreachable due to `${selector.show}` not being a subclass of `${scrutinee.show}`",
4351
Position(pos.start - 5, pos.end - 5)
4452
)
4553
rewrite(tree, to = false)
46-
} else if (!(scrutinee <:< selector) && !inMatch) {
54+
} else if (!scrutineeSubSelector && !inMatch) {
4755
ctx.warning(
4856
s"this will always yield false since `${scrutinee.show}` is not a subclass of `${selector.show}` (will be optimized away)",
4957
pos
5058
)
5159
rewrite(tree, to = false)
52-
} else if (scrutinee <:< selector && !inMatch) {
60+
} else if (scrutineeSubSelector && !inMatch) {
5361
ctx.warning(
54-
s"this will always yield true since `${scrutinee.show}` is a subclass of `${selector.show}` (will be optimized away)",
62+
s"this will always yield true if the scrutinee is non-null, since `${scrutinee.show}` is a subclass of `${selector.show}` (will be optimized away)",
5563
pos
5664
)
5765
rewrite(tree, to = true)
58-
} else /* if (scrutinee <:< selector && inMatch) */ rewrite(tree, to = true)
66+
} else /* if (scrutineeSubSelector && inMatch) */ rewrite(tree, to = true)
67+
}
5968

6069
/** Rewrites cases with unrelated types */
6170
def handleFalseUnrelated(tree: Select, scrutinee: Type, selector: Type, inMatch: Boolean) =
@@ -74,12 +83,12 @@ class IsInstanceOfEvaluator extends MiniPhaseTransform { thisTransformer =>
7483
}
7584

7685
/** Rewrites the select to a boolean if `to` is false or if the qualifier
77-
* is a primitive.
86+
* is a value class.
7887
*
7988
* If `to` is set to true and the qualifier is not a primitive, the
8089
* instanceOf is replaced by a null check, since:
8190
*
82-
* `srutinee.isInstanceOf[Selector]` if `scrutinee eq null`
91+
* `scrutinee.isInstanceOf[Selector]` if `scrutinee eq null`
8392
*/
8493
def rewrite(tree: Select, to: Boolean): Tree =
8594
if (!to || !tree.qualifier.tpe.widen.derivesFrom(defn.AnyRefAlias))

0 commit comments

Comments
 (0)