FIR: Do not add alias for variables with explicit type

This commit is contained in:
Denis.Zharkov
2021-10-20 10:06:46 +03:00
committed by TeamCityServer
parent 5317cf3af1
commit a0a57581ec
29 changed files with 562 additions and 67 deletions
@@ -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 {
@@ -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};
}
@@ -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|
@@ -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<!>)
}
@@ -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 {
@@ -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 {
@@ -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)
@@ -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
View File
@@ -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
}
}
@@ -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 -> {}
@@ -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> {
@@ -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
}
@@ -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)
@@ -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
+2 -4
View File
@@ -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]
+1 -1
View File
@@ -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 ""
}
@@ -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<!>)
}