FIR: Do not add alias for variables with explicit type
This commit is contained in:
committed by
TeamCityServer
parent
5317cf3af1
commit
a0a57581ec
+6
@@ -27495,6 +27495,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/throwInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("toInvisible.kt")
|
||||
public void testToInvisible() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/toInvisible.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoImplicitReceivers.kt")
|
||||
public void testTwoImplicitReceivers() throws Exception {
|
||||
|
||||
+311
-8
@@ -592,9 +592,9 @@ digraph boundSmartcastsInBranches_kt {
|
||||
219 [label="Access variable R|<local>/x|"];
|
||||
220 [label="Access variable R|kotlin/String.length|"];
|
||||
221 [label="Access variable R|<local>/y|"];
|
||||
222 [label="Access variable R|kotlin/String.length|"];
|
||||
222 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
223 [label="Access variable R|<local>/z|"];
|
||||
224 [label="Access variable R|kotlin/String.length|"];
|
||||
224 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
225 [label="Exit block"];
|
||||
}
|
||||
226 [label="Exit when branch result"];
|
||||
@@ -617,11 +617,11 @@ digraph boundSmartcastsInBranches_kt {
|
||||
color=blue
|
||||
236 [label="Enter block"];
|
||||
237 [label="Access variable R|<local>/x|"];
|
||||
238 [label="Access variable R|kotlin/String.length|"];
|
||||
238 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
239 [label="Access variable R|<local>/y|"];
|
||||
240 [label="Access variable R|kotlin/String.length|"];
|
||||
241 [label="Access variable R|<local>/z|"];
|
||||
242 [label="Access variable R|kotlin/String.length|"];
|
||||
242 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
243 [label="Exit block"];
|
||||
}
|
||||
244 [label="Exit when branch result"];
|
||||
@@ -644,9 +644,9 @@ digraph boundSmartcastsInBranches_kt {
|
||||
color=blue
|
||||
254 [label="Enter block"];
|
||||
255 [label="Access variable R|<local>/x|"];
|
||||
256 [label="Access variable R|kotlin/String.length|"];
|
||||
256 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
257 [label="Access variable R|<local>/y|"];
|
||||
258 [label="Access variable R|kotlin/String.length|"];
|
||||
258 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
259 [label="Access variable R|<local>/z|"];
|
||||
260 [label="Access variable R|kotlin/String.length|"];
|
||||
261 [label="Exit block"];
|
||||
@@ -677,7 +677,7 @@ digraph boundSmartcastsInBranches_kt {
|
||||
277 [label="Access variable R|<local>/y|"];
|
||||
278 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
279 [label="Access variable R|<local>/z|"];
|
||||
280 [label="Access variable R|kotlin/String.length|"];
|
||||
280 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
281 [label="Exit block"];
|
||||
}
|
||||
282 [label="Exit when branch result"];
|
||||
@@ -728,7 +728,7 @@ digraph boundSmartcastsInBranches_kt {
|
||||
color=blue
|
||||
311 [label="Enter block"];
|
||||
312 [label="Access variable R|<local>/x|"];
|
||||
313 [label="Access variable R|kotlin/String.length|"];
|
||||
313 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
314 [label="Access variable R|<local>/y|"];
|
||||
315 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
316 [label="Access variable R|<local>/z|"];
|
||||
@@ -864,4 +864,307 @@ digraph boundSmartcastsInBranches_kt {
|
||||
320 -> {321};
|
||||
321 -> {322};
|
||||
|
||||
subgraph cluster_70 {
|
||||
color=red
|
||||
323 [label="Enter function test_8" style="filled" fillcolor=red];
|
||||
subgraph cluster_71 {
|
||||
color=blue
|
||||
324 [label="Enter block"];
|
||||
325 [label="Const: Null(null)"];
|
||||
326 [label="Variable declaration: lval z: R|kotlin/String?|"];
|
||||
327 [label="Access variable R|<local>/z|"];
|
||||
328 [label="Variable declaration: lvar y: R|kotlin/String?|"];
|
||||
329 [label="Access variable R|<local>/y|"];
|
||||
330 [label="Variable declaration: lval x: R|kotlin/String?|"];
|
||||
subgraph cluster_72 {
|
||||
color=blue
|
||||
331 [label="Enter when"];
|
||||
subgraph cluster_73 {
|
||||
color=blue
|
||||
332 [label="Enter when branch condition "];
|
||||
333 [label="Access variable R|<local>/x|"];
|
||||
334 [label="Const: Null(null)"];
|
||||
335 [label="Equality operator !="];
|
||||
336 [label="Exit when branch condition"];
|
||||
}
|
||||
337 [label="Synthetic else branch"];
|
||||
338 [label="Enter when branch result"];
|
||||
subgraph cluster_74 {
|
||||
color=blue
|
||||
339 [label="Enter block"];
|
||||
340 [label="Access variable R|<local>/x|"];
|
||||
341 [label="Access variable R|kotlin/String.length|"];
|
||||
342 [label="Access variable R|<local>/y|"];
|
||||
343 [label="Access variable R|kotlin/String.length|"];
|
||||
344 [label="Access variable R|<local>/z|"];
|
||||
345 [label="Access variable R|kotlin/String.length|"];
|
||||
346 [label="Exit block"];
|
||||
}
|
||||
347 [label="Exit when branch result"];
|
||||
348 [label="Exit when"];
|
||||
}
|
||||
subgraph cluster_75 {
|
||||
color=blue
|
||||
349 [label="Enter when"];
|
||||
subgraph cluster_76 {
|
||||
color=blue
|
||||
350 [label="Enter when branch condition "];
|
||||
351 [label="Access variable R|<local>/y|"];
|
||||
352 [label="Const: Null(null)"];
|
||||
353 [label="Equality operator !="];
|
||||
354 [label="Exit when branch condition"];
|
||||
}
|
||||
355 [label="Synthetic else branch"];
|
||||
356 [label="Enter when branch result"];
|
||||
subgraph cluster_77 {
|
||||
color=blue
|
||||
357 [label="Enter block"];
|
||||
358 [label="Access variable R|<local>/x|"];
|
||||
359 [label="Access variable R|kotlin/String.length|"];
|
||||
360 [label="Access variable R|<local>/y|"];
|
||||
361 [label="Access variable R|kotlin/String.length|"];
|
||||
362 [label="Access variable R|<local>/z|"];
|
||||
363 [label="Access variable R|kotlin/String.length|"];
|
||||
364 [label="Exit block"];
|
||||
}
|
||||
365 [label="Exit when branch result"];
|
||||
366 [label="Exit when"];
|
||||
}
|
||||
subgraph cluster_78 {
|
||||
color=blue
|
||||
367 [label="Enter when"];
|
||||
subgraph cluster_79 {
|
||||
color=blue
|
||||
368 [label="Enter when branch condition "];
|
||||
369 [label="Access variable R|<local>/z|"];
|
||||
370 [label="Const: Null(null)"];
|
||||
371 [label="Equality operator !="];
|
||||
372 [label="Exit when branch condition"];
|
||||
}
|
||||
373 [label="Synthetic else branch"];
|
||||
374 [label="Enter when branch result"];
|
||||
subgraph cluster_80 {
|
||||
color=blue
|
||||
375 [label="Enter block"];
|
||||
376 [label="Access variable R|<local>/x|"];
|
||||
377 [label="Access variable R|kotlin/String.length|"];
|
||||
378 [label="Access variable R|<local>/y|"];
|
||||
379 [label="Access variable R|kotlin/String.length|"];
|
||||
380 [label="Access variable R|<local>/z|"];
|
||||
381 [label="Access variable R|kotlin/String.length|"];
|
||||
382 [label="Exit block"];
|
||||
}
|
||||
383 [label="Exit when branch result"];
|
||||
384 [label="Exit when"];
|
||||
}
|
||||
385 [label="Const: Null(null)"];
|
||||
386 [label="Assignment: R|<local>/y|"];
|
||||
subgraph cluster_81 {
|
||||
color=blue
|
||||
387 [label="Enter when"];
|
||||
subgraph cluster_82 {
|
||||
color=blue
|
||||
388 [label="Enter when branch condition "];
|
||||
389 [label="Access variable R|<local>/x|"];
|
||||
390 [label="Const: Null(null)"];
|
||||
391 [label="Equality operator !="];
|
||||
392 [label="Exit when branch condition"];
|
||||
}
|
||||
393 [label="Synthetic else branch"];
|
||||
394 [label="Enter when branch result"];
|
||||
subgraph cluster_83 {
|
||||
color=blue
|
||||
395 [label="Enter block"];
|
||||
396 [label="Access variable R|<local>/x|"];
|
||||
397 [label="Access variable R|kotlin/String.length|"];
|
||||
398 [label="Access variable R|<local>/y|"];
|
||||
399 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
400 [label="Access variable R|<local>/z|"];
|
||||
401 [label="Access variable R|kotlin/String.length|"];
|
||||
402 [label="Exit block"];
|
||||
}
|
||||
403 [label="Exit when branch result"];
|
||||
404 [label="Exit when"];
|
||||
}
|
||||
subgraph cluster_84 {
|
||||
color=blue
|
||||
405 [label="Enter when"];
|
||||
subgraph cluster_85 {
|
||||
color=blue
|
||||
406 [label="Enter when branch condition "];
|
||||
407 [label="Access variable R|<local>/y|"];
|
||||
408 [label="Const: Null(null)"];
|
||||
409 [label="Equality operator !="];
|
||||
410 [label="Exit when branch condition"];
|
||||
}
|
||||
411 [label="Synthetic else branch"];
|
||||
412 [label="Enter when branch result"];
|
||||
subgraph cluster_86 {
|
||||
color=blue
|
||||
413 [label="Enter block"];
|
||||
414 [label="Access variable R|<local>/x|"];
|
||||
415 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
416 [label="Access variable R|<local>/y|"];
|
||||
417 [label="Stub" style="filled" fillcolor=gray];
|
||||
418 [label="Access variable R|kotlin/String.length|" style="filled" fillcolor=gray];
|
||||
419 [label="Access variable R|<local>/z|" style="filled" fillcolor=gray];
|
||||
420 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#" style="filled" fillcolor=gray];
|
||||
421 [label="Exit block" style="filled" fillcolor=gray];
|
||||
}
|
||||
422 [label="Exit when branch result" style="filled" fillcolor=gray];
|
||||
423 [label="Exit when"];
|
||||
}
|
||||
subgraph cluster_87 {
|
||||
color=blue
|
||||
424 [label="Enter when"];
|
||||
subgraph cluster_88 {
|
||||
color=blue
|
||||
425 [label="Enter when branch condition "];
|
||||
426 [label="Access variable R|<local>/z|"];
|
||||
427 [label="Const: Null(null)"];
|
||||
428 [label="Equality operator !="];
|
||||
429 [label="Exit when branch condition"];
|
||||
}
|
||||
430 [label="Synthetic else branch"];
|
||||
431 [label="Enter when branch result"];
|
||||
subgraph cluster_89 {
|
||||
color=blue
|
||||
432 [label="Enter block"];
|
||||
433 [label="Access variable R|<local>/x|"];
|
||||
434 [label="Access variable R|kotlin/String.length|"];
|
||||
435 [label="Access variable R|<local>/y|"];
|
||||
436 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
|
||||
437 [label="Access variable R|<local>/z|"];
|
||||
438 [label="Access variable R|kotlin/String.length|"];
|
||||
439 [label="Exit block"];
|
||||
}
|
||||
440 [label="Exit when branch result"];
|
||||
441 [label="Exit when"];
|
||||
}
|
||||
442 [label="Exit block"];
|
||||
}
|
||||
443 [label="Exit function test_8" style="filled" fillcolor=red];
|
||||
}
|
||||
323 -> {324};
|
||||
324 -> {325};
|
||||
325 -> {326};
|
||||
326 -> {327};
|
||||
327 -> {328};
|
||||
328 -> {329};
|
||||
329 -> {330};
|
||||
330 -> {331};
|
||||
331 -> {332};
|
||||
332 -> {333};
|
||||
333 -> {334};
|
||||
334 -> {335};
|
||||
335 -> {336};
|
||||
336 -> {338 337};
|
||||
337 -> {348};
|
||||
338 -> {339};
|
||||
339 -> {340};
|
||||
340 -> {341};
|
||||
341 -> {342};
|
||||
342 -> {343};
|
||||
343 -> {344};
|
||||
344 -> {345};
|
||||
345 -> {346};
|
||||
346 -> {347};
|
||||
347 -> {348};
|
||||
348 -> {349};
|
||||
349 -> {350};
|
||||
350 -> {351};
|
||||
351 -> {352};
|
||||
352 -> {353};
|
||||
353 -> {354};
|
||||
354 -> {356 355};
|
||||
355 -> {366};
|
||||
356 -> {357};
|
||||
357 -> {358};
|
||||
358 -> {359};
|
||||
359 -> {360};
|
||||
360 -> {361};
|
||||
361 -> {362};
|
||||
362 -> {363};
|
||||
363 -> {364};
|
||||
364 -> {365};
|
||||
365 -> {366};
|
||||
366 -> {367};
|
||||
367 -> {368};
|
||||
368 -> {369};
|
||||
369 -> {370};
|
||||
370 -> {371};
|
||||
371 -> {372};
|
||||
372 -> {374 373};
|
||||
373 -> {384};
|
||||
374 -> {375};
|
||||
375 -> {376};
|
||||
376 -> {377};
|
||||
377 -> {378};
|
||||
378 -> {379};
|
||||
379 -> {380};
|
||||
380 -> {381};
|
||||
381 -> {382};
|
||||
382 -> {383};
|
||||
383 -> {384};
|
||||
384 -> {385};
|
||||
385 -> {386};
|
||||
386 -> {387};
|
||||
387 -> {388};
|
||||
388 -> {389};
|
||||
389 -> {390};
|
||||
390 -> {391};
|
||||
391 -> {392};
|
||||
392 -> {394 393};
|
||||
393 -> {404};
|
||||
394 -> {395};
|
||||
395 -> {396};
|
||||
396 -> {397};
|
||||
397 -> {398};
|
||||
398 -> {399};
|
||||
399 -> {400};
|
||||
400 -> {401};
|
||||
401 -> {402};
|
||||
402 -> {403};
|
||||
403 -> {404};
|
||||
404 -> {405};
|
||||
405 -> {406};
|
||||
406 -> {407};
|
||||
407 -> {408};
|
||||
408 -> {409};
|
||||
409 -> {410};
|
||||
410 -> {412 411};
|
||||
411 -> {423};
|
||||
412 -> {413};
|
||||
413 -> {414};
|
||||
414 -> {415};
|
||||
415 -> {416};
|
||||
416 -> {443} [label=onUncaughtException];
|
||||
416 -> {417} [style=dotted];
|
||||
417 -> {418} [style=dotted];
|
||||
418 -> {419} [style=dotted];
|
||||
419 -> {420} [style=dotted];
|
||||
420 -> {421} [style=dotted];
|
||||
421 -> {422} [style=dotted];
|
||||
422 -> {423} [style=dotted];
|
||||
423 -> {424};
|
||||
424 -> {425};
|
||||
425 -> {426};
|
||||
426 -> {427};
|
||||
427 -> {428};
|
||||
428 -> {429};
|
||||
429 -> {431 430};
|
||||
430 -> {441};
|
||||
431 -> {432};
|
||||
432 -> {433};
|
||||
433 -> {434};
|
||||
434 -> {435};
|
||||
435 -> {436};
|
||||
436 -> {437};
|
||||
437 -> {438};
|
||||
438 -> {439};
|
||||
439 -> {440};
|
||||
440 -> {441};
|
||||
441 -> {442};
|
||||
442 -> {443};
|
||||
|
||||
}
|
||||
|
||||
+54
@@ -104,6 +104,60 @@ FILE: boundSmartcastsInBranches.kt
|
||||
R|<local>/x|.R|/A.s|
|
||||
}
|
||||
public final fun test_7(): R|kotlin/Unit| {
|
||||
lval z: R|kotlin/String?| = Null(null)
|
||||
lvar y: R|kotlin/String?| = R|<local>/z|
|
||||
lval x: R|kotlin/String?| = R|<local>/y|
|
||||
when () {
|
||||
!=(R|<local>/x|, Null(null)) -> {
|
||||
R|<local>/x|.R|kotlin/String.length|
|
||||
R|<local>/y|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
R|<local>/z|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
!=(R|<local>/y|, Null(null)) -> {
|
||||
R|<local>/x|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
R|<local>/y|.R|kotlin/String.length|
|
||||
R|<local>/z|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
!=(R|<local>/z|, Null(null)) -> {
|
||||
R|<local>/x|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
R|<local>/y|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
R|<local>/z|.R|kotlin/String.length|
|
||||
}
|
||||
}
|
||||
|
||||
R|<local>/y| = Null(null)
|
||||
when () {
|
||||
!=(R|<local>/x|, Null(null)) -> {
|
||||
R|<local>/x|.R|kotlin/String.length|
|
||||
R|<local>/y|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
R|<local>/z|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
!=(R|<local>/y|, Null(null)) -> {
|
||||
R|<local>/x|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
R|<local>/y|.R|kotlin/String.length|
|
||||
R|<local>/z|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
!=(R|<local>/z|, Null(null)) -> {
|
||||
R|<local>/x|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
R|<local>/y|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
|
||||
R|<local>/z|.R|kotlin/String.length|
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_8(): R|kotlin/Unit| {
|
||||
lval z: R|kotlin/String?| = Null(null)
|
||||
lvar y: R|kotlin/String?| = R|<local>/z|
|
||||
lval x: R|kotlin/String?| = R|<local>/y|
|
||||
|
||||
compiler/fir/analysis-tests/testData/resolve/smartcasts/boundSmartcasts/boundSmartcastsInBranches.kt
Vendored
+42
@@ -83,6 +83,48 @@ fun test_7() {
|
||||
var y : String? = z
|
||||
val x: String? = y
|
||||
|
||||
if (x != null) {
|
||||
x.length // OK
|
||||
y<!UNSAFE_CALL!>.<!>length // Bad
|
||||
z<!UNSAFE_CALL!>.<!>length // Bad
|
||||
}
|
||||
if (y != null) {
|
||||
x<!UNSAFE_CALL!>.<!>length // Bad
|
||||
y.length // OK
|
||||
z<!UNSAFE_CALL!>.<!>length // Bad
|
||||
}
|
||||
|
||||
if (z != null) {
|
||||
x<!UNSAFE_CALL!>.<!>length // Bad
|
||||
y<!UNSAFE_CALL!>.<!>length // Bad
|
||||
z.length // OK
|
||||
}
|
||||
|
||||
y = null
|
||||
|
||||
if (x != null) {
|
||||
x.length // OK
|
||||
y<!UNSAFE_CALL!>.<!>length // Bad
|
||||
z<!UNSAFE_CALL!>.<!>length // Bad
|
||||
}
|
||||
if (<!SENSELESS_COMPARISON!>y != null<!>) {
|
||||
x<!UNSAFE_CALL!>.<!>length // Bad
|
||||
y.length // OK
|
||||
z<!UNSAFE_CALL!>.<!>length // Bad
|
||||
}
|
||||
|
||||
if (z != null) {
|
||||
x<!UNSAFE_CALL!>.<!>length // Bad
|
||||
y<!UNSAFE_CALL!>.<!>length // Bad
|
||||
z.length // OK
|
||||
}
|
||||
}
|
||||
|
||||
fun test_8() {
|
||||
val z: String? = null
|
||||
var y = z
|
||||
val x = y
|
||||
|
||||
if (x != null) {
|
||||
x.length // OK
|
||||
y.length // OK
|
||||
|
||||
@@ -146,7 +146,7 @@ FILE: whenExpressionType.kt
|
||||
}
|
||||
public final fun case9(): R|kotlin/Unit| {
|
||||
lval flag: R|kotlin/Any| = Q|A|.R|/A.A1|
|
||||
lval l1: R|B| = when (R|<local>/flag|) {
|
||||
lval l1: R|kotlin/Unit| = when (R|<local>/flag|) {
|
||||
==($subj$, Q|A|.R|/A.A1|) -> {
|
||||
R|/B.B|()
|
||||
}
|
||||
@@ -155,5 +155,5 @@ FILE: whenExpressionType.kt
|
||||
}
|
||||
}
|
||||
|
||||
lval x1: R|C| = R|/C.C|(R|<local>/l1|)
|
||||
lval x1: R|C| = <Inapplicable(INAPPLICABLE): /C.C>#(R|<local>/l1|)
|
||||
}
|
||||
|
||||
@@ -102,10 +102,10 @@ fun case8() {
|
||||
// TESTCASE NUMBER: 9
|
||||
fun case9() {
|
||||
val flag: Any = A.A1
|
||||
val l1 = when (flag) {
|
||||
val l1 = <!NO_ELSE_IN_WHEN!>when<!> (flag) {
|
||||
A.A1 -> B()
|
||||
A.A2 -> B()
|
||||
}
|
||||
val x1 = C(l1)
|
||||
val x1 = C(<!ARGUMENT_TYPE_MISMATCH!>l1<!>)
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -27495,6 +27495,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/throwInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("toInvisible.kt")
|
||||
public void testToInvisible() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/toInvisible.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoImplicitReceivers.kt")
|
||||
public void testTwoImplicitReceivers() throws Exception {
|
||||
|
||||
+6
@@ -27495,6 +27495,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/throwInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("toInvisible.kt")
|
||||
public void testToInvisible() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/toInvisible.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoImplicitReceivers.kt")
|
||||
public void testTwoImplicitReceivers() throws Exception {
|
||||
|
||||
+6
-5
@@ -1068,10 +1068,10 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
graphBuilder.exitConstExpression(constExpression).mergeIncomingFlow()
|
||||
}
|
||||
|
||||
fun exitLocalVariableDeclaration(variable: FirProperty) {
|
||||
fun exitLocalVariableDeclaration(variable: FirProperty, hadExplicitType: Boolean) {
|
||||
val node = graphBuilder.exitVariableDeclaration(variable).mergeIncomingFlow()
|
||||
val initializer = variable.initializer ?: return
|
||||
exitVariableInitialization(node, initializer, variable, assignment = null)
|
||||
exitVariableInitialization(node, initializer, variable, assignment = null, hadExplicitType)
|
||||
}
|
||||
|
||||
fun exitVariableAssignment(assignment: FirVariableAssignment) {
|
||||
@@ -1079,7 +1079,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
val property = (assignment.lValue as? FirResolvedNamedReference)?.resolvedSymbol?.fir as? FirProperty ?: return
|
||||
// TODO: add unstable smartcast
|
||||
if (property.isLocal || !property.isVar) {
|
||||
exitVariableInitialization(node, assignment.rValue, property, assignment)
|
||||
exitVariableInitialization(node, assignment.rValue, property, assignment, hasExplicitType = false)
|
||||
}
|
||||
processConditionalContract(assignment)
|
||||
}
|
||||
@@ -1088,7 +1088,8 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
node: CFGNode<*>,
|
||||
initializer: FirExpression,
|
||||
property: FirProperty,
|
||||
assignment: FirVariableAssignment?
|
||||
assignment: FirVariableAssignment?,
|
||||
hasExplicitType: Boolean,
|
||||
) {
|
||||
val flow = node.flow
|
||||
val propertyVariable = variableStorage.getOrCreateRealVariableWithoutUnwrappingAlias(
|
||||
@@ -1109,7 +1110,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
val isInitializerStable =
|
||||
initializerVariable.isStable || (initializerVariable.hasLocalStability && initializer.isAccessToStableVariable())
|
||||
|
||||
if (isInitializerStable && (propertyVariable.hasLocalStability || propertyVariable.isStable)) {
|
||||
if (!hasExplicitType && isInitializerStable && (propertyVariable.hasLocalStability || propertyVariable.isStable)) {
|
||||
logicSystem.addLocalVariableAlias(
|
||||
flow, propertyVariable,
|
||||
RealVariableAndType(initializerVariable, initializer.coneType)
|
||||
|
||||
+4
-1
@@ -307,6 +307,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
assert(variable.isLocal)
|
||||
variable.transformDelegate(transformer, ResolutionMode.ContextDependentDelegate)
|
||||
val delegate = variable.delegate
|
||||
|
||||
val hadExplicitType = variable.returnTypeRef !is FirImplicitTypeRef
|
||||
|
||||
if (delegate != null) {
|
||||
transformPropertyAccessorsWithDelegate(variable, delegate)
|
||||
if (variable.delegateFieldSymbol != null) {
|
||||
@@ -326,7 +329,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
}
|
||||
variable.transformOtherChildren(transformer, ResolutionMode.ContextIndependent)
|
||||
context.storeVariable(variable)
|
||||
dataFlowAnalyzer.exitLocalVariableDeclaration(variable)
|
||||
dataFlowAnalyzer.exitLocalVariableDeclaration(variable, hadExplicitType)
|
||||
return variable
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +ProperIeee754Comparisons
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.*
|
||||
@@ -224,4 +223,4 @@ fun box(): String {
|
||||
testFloat(Float.NaN, Float.NaN, Float.NaN)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -11,10 +11,10 @@ fun foo(c: Consumer<Int>, p: Producer<Int>, u: Usual<Int>) {
|
||||
val c2: Consumer<Int> = c1
|
||||
|
||||
val p1: Producer<Any> = p
|
||||
val p2: Producer<Int> = p1
|
||||
val p2: Producer<Int> = <!INITIALIZER_TYPE_MISMATCH!>p1<!>
|
||||
|
||||
val u1: Usual<Any> = <!INITIALIZER_TYPE_MISMATCH!>u<!>
|
||||
val u2: Usual<Int> = u1
|
||||
val u2: Usual<Int> = <!INITIALIZER_TYPE_MISMATCH!>u1<!>
|
||||
}
|
||||
|
||||
//Arrays copy example
|
||||
@@ -37,4 +37,4 @@ fun f(ints: Array<Int>, any: Array<Any>, numbers: Array<Number>) {
|
||||
copy2(ints, <!ARGUMENT_TYPE_MISMATCH!>numbers<!>)
|
||||
copy3<Int>(ints, numbers)
|
||||
copy4(ints, numbers) //ok
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,5 +6,5 @@ fun test(a: Any?) {
|
||||
b.hashCode()
|
||||
|
||||
val c: Any? = a
|
||||
c.hashCode()
|
||||
}
|
||||
c<!UNSAFE_CALL!>.<!>hashCode()
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ enum class En { A, B, С }
|
||||
fun foo() {
|
||||
// nullable variable
|
||||
val en2: Any? = En.A
|
||||
if (<!USELESS_IS_CHECK!>en2 is En<!>) {
|
||||
if (en2 is En) {
|
||||
when (en2) {
|
||||
En.A -> {}
|
||||
En.B -> {}
|
||||
@@ -15,7 +15,7 @@ fun foo() {
|
||||
|
||||
// not nullable variable
|
||||
val en1: Any = En.A
|
||||
if (<!USELESS_IS_CHECK!>en1 is En<!>) {
|
||||
if (en1 is En) {
|
||||
when (en1) {
|
||||
En.A -> {}
|
||||
En.B -> {}
|
||||
|
||||
+1
-1
@@ -10,5 +10,5 @@ fun main() {
|
||||
val c : ListOfLists<*> = b
|
||||
val d : ArrayList<ArrayList<*>> = <!INITIALIZER_TYPE_MISMATCH!>c.x<!>
|
||||
|
||||
c.x checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><ArrayList<out ArrayList<*>>>() }
|
||||
c.x checkType { _<ArrayList<out ArrayList<*>>>() }
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||
|
||||
class A<out T, in E> {
|
||||
fun foo(x: @UnsafeVariance T) {}
|
||||
fun foo(x: @UnsafeVariance T, y: List<@UnsafeVariance T>): @UnsafeVariance E = null!!
|
||||
|
||||
fun bar(): List<@UnsafeVariance E> = null!!
|
||||
}
|
||||
|
||||
fun foo(x: A<String, Any?>, cs: CharSequence, ls: List<CharSequence>) {
|
||||
val y: A<CharSequence, String> = x
|
||||
|
||||
y.foo(<!ARGUMENT_TYPE_MISMATCH!>cs<!>)
|
||||
val s: String = <!INITIALIZER_TYPE_MISMATCH!>y.foo(<!ARGUMENT_TYPE_MISMATCH!>cs<!>, <!ARGUMENT_TYPE_MISMATCH!>ls<!>)<!>
|
||||
|
||||
val ls2: List<String> = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>y.bar()<!>
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||
|
||||
class A<out T, in E> {
|
||||
|
||||
+4
-4
@@ -32,10 +32,10 @@ fun test(s: bar.Sub<String>) {
|
||||
s.<!INVISIBLE_REFERENCE!>doSomething<!>()
|
||||
s.doSomething2()
|
||||
val s2: Super<String> = s
|
||||
s2.<!INVISIBLE_REFERENCE!>name<!>
|
||||
s2.<!INVISIBLE_REFERENCE!>name<!> = ""
|
||||
s2.name
|
||||
s2.name = ""
|
||||
s2.name2
|
||||
<!INVISIBLE_SETTER!>s2.name2<!> = ""
|
||||
s2.<!INVISIBLE_REFERENCE!>doSomething<!>()
|
||||
s2.name2 = ""
|
||||
s2.doSomething()
|
||||
s2.doSomething2()
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ fun foo(arg: Int?) {
|
||||
}
|
||||
val y: Any? = arg
|
||||
if (y != null) {
|
||||
arg.hashCode()
|
||||
arg<!UNSAFE_CALL!>.<!>hashCode()
|
||||
}
|
||||
val yy: Any?
|
||||
yy = arg
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// SKIP_TXT
|
||||
// FILE: a/A.java
|
||||
package a;
|
||||
public interface A {
|
||||
B b();
|
||||
}
|
||||
|
||||
// FILE: a/B.java
|
||||
package a;
|
||||
public interface B {
|
||||
void bar();
|
||||
}
|
||||
|
||||
// FILE: a/AImpl.java
|
||||
package a;
|
||||
|
||||
public class AImpl implements A {
|
||||
@Override
|
||||
public BImpl b() {
|
||||
return new BImpl();
|
||||
}
|
||||
}
|
||||
|
||||
class BImpl implements B {
|
||||
@Override
|
||||
public void bar() {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
import a.A
|
||||
import a.AImpl
|
||||
|
||||
fun test1(a: A) {
|
||||
if (a is AImpl) {
|
||||
(a as A).b().bar() // OK
|
||||
a.b().<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun test2(aImpl: AImpl) {
|
||||
val a: A = aImpl
|
||||
(a <!USELESS_CAST!>as A<!>).b().bar() // OK
|
||||
a.b().bar() // Works at FE1.0, fails at FIR
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// SKIP_TXT
|
||||
// FILE: a/A.java
|
||||
package a;
|
||||
public interface A {
|
||||
B b();
|
||||
}
|
||||
|
||||
// FILE: a/B.java
|
||||
package a;
|
||||
public interface B {
|
||||
void bar();
|
||||
}
|
||||
|
||||
// FILE: a/AImpl.java
|
||||
package a;
|
||||
|
||||
public class AImpl implements A {
|
||||
@Override
|
||||
public BImpl b() {
|
||||
return new BImpl();
|
||||
}
|
||||
}
|
||||
|
||||
class BImpl implements B {
|
||||
@Override
|
||||
public void bar() {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
import a.A
|
||||
import a.AImpl
|
||||
|
||||
fun test1(a: A) {
|
||||
if (a is AImpl) {
|
||||
(a as A).b().bar() // OK
|
||||
<!INACCESSIBLE_TYPE!><!DEBUG_INFO_SMARTCAST!>a<!>.b()<!>.<!INVISIBLE_MEMBER!>bar<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun test2(aImpl: AImpl) {
|
||||
val a: A = aImpl
|
||||
(a <!USELESS_CAST!>as A<!>).b().bar() // OK
|
||||
a.b().bar() // Works at FE1.0, fails at FIR
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ fun String.next(): String {
|
||||
|
||||
fun list(start: String) {
|
||||
var e: Any? = start
|
||||
if (<!SENSELESS_COMPARISON!>e==null<!>) return
|
||||
if (e==null) return
|
||||
while (e is String) {
|
||||
// Smart cast due to the loop condition
|
||||
if (e.length == 0)
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ fun foo(arg: Int?) {
|
||||
}
|
||||
val y: Any? = arg
|
||||
if (y != null) {
|
||||
arg.hashCode()
|
||||
arg<!UNSAFE_CALL!>.<!>hashCode()
|
||||
}
|
||||
val yy: Any?
|
||||
yy = arg
|
||||
|
||||
@@ -67,8 +67,7 @@ FILE fqName:<root> fileName:/whenSmartCastToEnum.kt
|
||||
WHEN type=kotlin.Unit origin=IF
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.En
|
||||
TYPE_OP type=<root>.En origin=IMPLICIT_CAST typeOperand=<root>.En
|
||||
GET_VAR 'val x: kotlin.Any? [val] declared in <root>.test' type=kotlin.Any? origin=null
|
||||
GET_VAR 'val x: kotlin.Any? [val] declared in <root>.test' type=kotlin.Any? origin=null
|
||||
then: BLOCK type=kotlin.Unit origin=WHEN
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.En [val]
|
||||
TYPE_OP type=<root>.En origin=IMPLICIT_CAST typeOperand=<root>.En
|
||||
@@ -99,8 +98,7 @@ FILE fqName:<root> fileName:/whenSmartCastToEnum.kt
|
||||
WHEN type=kotlin.Unit origin=IF
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.En
|
||||
TYPE_OP type=<root>.En origin=IMPLICIT_CAST typeOperand=<root>.En
|
||||
GET_VAR 'val y: kotlin.Any [val] declared in <root>.test' type=kotlin.Any origin=null
|
||||
GET_VAR 'val y: kotlin.Any [val] declared in <root>.test' type=kotlin.Any origin=null
|
||||
then: BLOCK type=kotlin.Unit origin=WHEN
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.En [val]
|
||||
TYPE_OP type=<root>.En origin=IMPLICIT_CAST typeOperand=<root>.En
|
||||
|
||||
@@ -21,7 +21,7 @@ fun test() {
|
||||
var r: String = ""
|
||||
val x: Any? = En.A
|
||||
when {
|
||||
x /*as En */ is En -> { // BLOCK
|
||||
x is En -> { // BLOCK
|
||||
val tmp0_subject: En = x /*as En */
|
||||
when {
|
||||
EQEQ(arg0 = tmp0_subject, arg1 = En.A) -> { // BLOCK
|
||||
@@ -37,7 +37,7 @@ fun test() {
|
||||
}
|
||||
val y: Any = En.A
|
||||
when {
|
||||
y /*as En */ is En -> { // BLOCK
|
||||
y is En -> { // BLOCK
|
||||
val tmp1_subject: En = y /*as En */
|
||||
when {
|
||||
EQEQ(arg0 = tmp1_subject, arg1 = En.A) -> { // BLOCK
|
||||
|
||||
@@ -29,14 +29,12 @@ FILE fqName:<root> fileName:/JCTreeUser.kt
|
||||
WHEN type=kotlin.Unit origin=IF
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.JCTree.JCTypeApply
|
||||
TYPE_OP type=T of <root>.Owner origin=IMPLICIT_CAST typeOperand=T of <root>.Owner
|
||||
GET_VAR 'var tree: <root>.JCTree [var] declared in <root>.Owner.<get-foo>' type=<root>.JCTree origin=null
|
||||
GET_VAR 'var tree: <root>.JCTree [var] declared in <root>.Owner.<get-foo>' type=<root>.JCTree origin=null
|
||||
then: RETURN type=kotlin.Nothing from='public final fun <get-foo> (): kotlin.String declared in <root>.Owner'
|
||||
TYPE_OP type=@[FlexibleNullability] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[FlexibleNullability] kotlin.String
|
||||
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:clazz type:@[FlexibleNullability] kotlin.String? visibility:public' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
|
||||
receiver: TYPE_OP type=<root>.JCTree.JCTypeApply origin=IMPLICIT_CAST typeOperand=<root>.JCTree.JCTypeApply
|
||||
TYPE_OP type=T of <root>.Owner origin=IMPLICIT_CAST typeOperand=T of <root>.Owner
|
||||
GET_VAR 'var tree: <root>.JCTree [var] declared in <root>.Owner.<get-foo>' type=<root>.JCTree origin=null
|
||||
GET_VAR 'var tree: <root>.JCTree [var] declared in <root>.Owner.<get-foo>' type=<root>.JCTree origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-foo> (): kotlin.String declared in <root>.Owner'
|
||||
CONST String type=kotlin.String value=""
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
|
||||
@@ -13,7 +13,7 @@ class Owner<out T : JCTree> {
|
||||
get(): String {
|
||||
var tree: JCTree = <this>.<get-tree>()
|
||||
when {
|
||||
tree /*as T */ is JCTypeApply -> return tree /*as T */ /*as JCTypeApply */.#clazz /*!! @FlexibleNullability String */
|
||||
tree is JCTypeApply -> return tree /*as JCTypeApply */.#clazz /*!! @FlexibleNullability String */
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
Generated
+6
@@ -27585,6 +27585,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/throwInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("toInvisible.kt")
|
||||
public void testToInvisible() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/toInvisible.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoImplicitReceivers.kt")
|
||||
public void testTwoImplicitReceivers() throws Exception {
|
||||
|
||||
@@ -13,7 +13,7 @@ fun case_1() {
|
||||
y = x
|
||||
y.put(0)
|
||||
val z: In<*> = x
|
||||
z.put(0)
|
||||
z.put(<!ARGUMENT_TYPE_MISMATCH!>0<!>)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -27,7 +27,7 @@ fun case_2() {
|
||||
y = x
|
||||
y.put(0)
|
||||
val z: Inv<out Number> = x
|
||||
z.put(0)
|
||||
z.put(<!ARGUMENT_TYPE_MISMATCH!>0<!>)
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
@@ -61,7 +61,7 @@ fun case_5() {
|
||||
y = x
|
||||
y.put(0)
|
||||
val z: Inv<out Number> = x
|
||||
z.put(0)
|
||||
z.put(<!ARGUMENT_TYPE_MISMATCH!>0<!>)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -76,5 +76,5 @@ fun case_6() {
|
||||
y = x
|
||||
y.put(<!ARGUMENT_TYPE_MISMATCH!>0<!>)
|
||||
val z: Inv<out Number> = x
|
||||
z.put(0)
|
||||
z.put(<!ARGUMENT_TYPE_MISMATCH!>0<!>)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user