FIR: Report UNSAFE_CALL instead of SMARTCAST_IMPOSSIBLE when smartcast

to null.

Currently the error message shows the expression is impossible to
smartcast to the nullable type, which is nonsensical since it's already
that type.
This commit is contained in:
Mark Punzalan
2021-07-29 18:52:36 +00:00
committed by teamcityserver
parent 0627dbcb78
commit 504449f03e
4 changed files with 71 additions and 0 deletions
@@ -1413,4 +1413,59 @@ digraph nullability_kt {
534 -> {535};
535 -> {536};
subgraph cluster_107 {
color=red
537 [label="Enter function test_14" style="filled" fillcolor=red];
subgraph cluster_108 {
color=blue
538 [label="Enter block"];
subgraph cluster_109 {
color=blue
539 [label="Enter when"];
subgraph cluster_110 {
color=blue
540 [label="Enter when branch condition "];
541 [label="Access variable R|<local>/q|"];
542 [label="Access variable R|/Q.data|"];
543 [label="Const: Null(null)"];
544 [label="Equality operator =="];
545 [label="Exit when branch condition"];
}
546 [label="Synthetic else branch"];
547 [label="Enter when branch result"];
subgraph cluster_111 {
color=blue
548 [label="Enter block"];
549 [label="Access variable R|<local>/q|"];
550 [label="Access variable R|/Q.data|"];
551 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
552 [label="Exit block"];
}
553 [label="Exit when branch result"];
554 [label="Exit when"];
}
555 [label="Exit block"];
}
556 [label="Exit function test_14" style="filled" fillcolor=red];
}
537 -> {538};
538 -> {539};
539 -> {540};
540 -> {541};
541 -> {542};
542 -> {543};
543 -> {544};
544 -> {545};
545 -> {547 546};
546 -> {554};
547 -> {548};
548 -> {549};
549 -> {550};
550 -> {551};
551 -> {552};
552 -> {553};
553 -> {554};
554 -> {555};
555 -> {556};
}
@@ -232,3 +232,11 @@ FILE: nullability.kt
}
}
public final fun test_14(q: R|Q|): R|kotlin/Unit| {
when () {
==(R|<local>/q|.R|/Q.data|, Null(null)) -> {
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#
}
}
}
@@ -175,3 +175,10 @@ fun test_13(q: QImplMutable?) {
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s.inc() // should be bad
}
}
fun test_14(q: Q) {
// `q.data` is a property that has an open getter
if (q.data == null) {
q.data<!UNSAFE_CALL!>.<!>s // should be UNSAFE_CALL and NOT SMARTCAST_IMPOSSIBLE
}
}
@@ -116,6 +116,7 @@ object CheckDispatchReceiver : ResolutionStage() {
(candidate.originScope as? FirUnstableSmartcastTypeScope)?.isSymbolFromUnstableSmartcast(candidate.symbol) == true
if (explicitReceiverExpression is FirExpressionWithSmartcast &&
explicitReceiverExpression !is FirExpressionWithSmartcastToNull &&
explicitReceiverExpression.smartcastStability != SmartcastStability.STABLE_VALUE &&
(isCandidateFromUnstableSmartcast || isReceiverNullable)
) {