diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index 6c654b9d268..3b2ceb718f1 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -18377,6 +18377,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/resolve/newLineLambda.kt"); } + @TestMetadata("noStopOnReceiverUnstableSmartCast.kt") + public void testNoStopOnReceiverUnstableSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.kt"); + } + @TestMetadata("objectLiteralAsArgument.kt") public void testObjectLiteralAsArgument() throws Exception { runTest("compiler/testData/diagnostics/tests/resolve/objectLiteralAsArgument.kt"); diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt index ea25a4a236d..855a7ba7005 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt @@ -571,8 +571,9 @@ class StateMachineBuilder( override fun visitReturn(expression: IrReturn) { expression.acceptChildrenVoid(this) - if (expression.returnTargetSymbol is IrReturnableBlockSymbol) { - val (exitState, varSymbol) = returnableBlockMap[expression.returnTargetSymbol]!! + val returnTarget = expression.returnTargetSymbol + if (returnTarget is IrReturnableBlockSymbol) { + val (exitState, varSymbol) = returnableBlockMap[returnTarget]!! if (varSymbol != null) { transformLastExpression { JsIrBuilder.buildSetVariable(varSymbol, it, it.type) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt index b5a48b48ba3..6807301c81c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt @@ -64,7 +64,7 @@ private fun checkExpressionArgument( ): KotlinCallDiagnostic? { if (unstableType != null) { if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, actualExpectedType, position)) { - return UnstableSmartCast(expressionArgument, unstableType) + return UnstableSmartCast(expressionArgument, unstableType, isReceiver) } } @@ -112,7 +112,7 @@ private fun checkExpressionArgument( val expectedNullableType = expectedType.makeNullableAsSpecified(true) if (unstableType != null && csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) { - diagnosticsHolder.addDiagnostic(UnstableSmartCast(expressionArgument, unstableType)) + diagnosticsHolder.addDiagnostic(UnstableSmartCast(expressionArgument, unstableType, isReceiver)) } else if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) { diagnosticsHolder.addDiagnostic(UnsafeCallError(expressionArgument)) } else { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt index 7d912582c87..b23c9daec64 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceCandidate import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable +import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.* import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.UnwrappedType @@ -138,11 +139,23 @@ class SmartCastDiagnostic( override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this) } -class UnstableSmartCast( +class UnstableSmartCast private constructor( val argument: ExpressionKotlinCallArgument, - val targetType: UnwrappedType -) : KotlinCallDiagnostic(RESOLVED_WITH_ERROR) { + val targetType: UnwrappedType, + applicability: ResolutionCandidateApplicability, +) : KotlinCallDiagnostic(applicability) { override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this) + + companion object { + operator fun invoke( + argument: ExpressionKotlinCallArgument, + targetType: UnwrappedType, + isReceiver: Boolean = false, + ): UnstableSmartCast { + val applicability = if (isReceiver) MAY_THROW_RUNTIME_ERROR else RESOLVED_WITH_ERROR + return UnstableSmartCast(argument, targetType, applicability) + } + } } class UnsafeCallError(val receiver: SimpleKotlinCallArgument) : KotlinCallDiagnostic(MAY_THROW_RUNTIME_ERROR) { diff --git a/compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.fir.kt b/compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.fir.kt new file mode 100644 index 00000000000..6fa99a95691 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.fir.kt @@ -0,0 +1,27 @@ +interface Base { + val parent: Base +} + +class Derived : Base { + override val parent: Base + get() = TODO() +} + +fun test(d: Derived) { + when { + d.parent is Derived -> d.parent.parent + } +} + +fun Any?.take() {} +class Something { + var prop: String? = null + + fun String.take() {} + + fun test() { + if (prop is String) { + prop.take() + } + } +} diff --git a/compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.kt b/compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.kt new file mode 100644 index 00000000000..6fa99a95691 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.kt @@ -0,0 +1,27 @@ +interface Base { + val parent: Base +} + +class Derived : Base { + override val parent: Base + get() = TODO() +} + +fun test(d: Derived) { + when { + d.parent is Derived -> d.parent.parent + } +} + +fun Any?.take() {} +class Something { + var prop: String? = null + + fun String.take() {} + + fun test() { + if (prop is String) { + prop.take() + } + } +} diff --git a/compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.txt b/compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.txt new file mode 100644 index 00000000000..8737f9dc6b6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.txt @@ -0,0 +1,29 @@ +package + +public fun test(/*0*/ d: Derived): kotlin.Unit +public fun kotlin.Any?.take(): kotlin.Unit + +public interface Base { + public abstract val parent: Base + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Derived : Base { + public constructor Derived() + public open override /*1*/ val parent: Base + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Something { + public constructor Something() + public final var prop: kotlin.String? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final fun kotlin.String.take(): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/elvis/impossible.kt b/compiler/testData/diagnostics/tests/smartCasts/elvis/impossible.kt index 8174bd0da67..dec520aab65 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/elvis/impossible.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/elvis/impossible.kt @@ -18,7 +18,7 @@ fun foo(list: StringList, arg: Unstable) { list.remove(arg.first) if (arg.first?.isEmpty() ?: false) { // Should be still resolved to extension, without smart cast or smart cast impossible - list.remove(arg.first) + list.remove(arg.first) } } @@ -36,6 +36,6 @@ fun bar(list: BooleanList, arg: UnstableBoolean) { list.remove(arg.first) if (arg.first ?: false) { // Should be still resolved to extension, without smart cast or smart cast impossible - list.remove(arg.first) + list.remove(arg.first) } } diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/unnecessaryWithMap.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/unnecessaryWithMap.fir.kt index 2e77dcc451a..72785f3b31e 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/unnecessaryWithMap.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/unnecessaryWithMap.fir.kt @@ -1,3 +1,5 @@ +// !WITH_NEW_INFERENCE + fun create(): Map = null!! operator fun Map.iterator(): Iterator> = null!! diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/unnecessaryWithMap.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/unnecessaryWithMap.kt index e58eeca864d..11051429b06 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/unnecessaryWithMap.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/unnecessaryWithMap.kt @@ -1,3 +1,5 @@ +// !WITH_NEW_INFERENCE + fun create(): Map = null!! operator fun Map.iterator(): Iterator> = null!! @@ -13,7 +15,7 @@ class MyClass { m = create() // See KT-7428 for ((k, v) in m) - res += (k.length + v.length) + res += (k.length + v.length) return res } } \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index eac8c930a51..3c199c9b547 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -18389,6 +18389,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/resolve/newLineLambda.kt"); } + @TestMetadata("noStopOnReceiverUnstableSmartCast.kt") + public void testNoStopOnReceiverUnstableSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.kt"); + } + @TestMetadata("objectLiteralAsArgument.kt") public void testObjectLiteralAsArgument() throws Exception { runTest("compiler/testData/diagnostics/tests/resolve/objectLiteralAsArgument.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 49cf27c5a86..ebddbb0e1a4 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -18379,6 +18379,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/resolve/newLineLambda.kt"); } + @TestMetadata("noStopOnReceiverUnstableSmartCast.kt") + public void testNoStopOnReceiverUnstableSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/noStopOnReceiverUnstableSmartCast.kt"); + } + @TestMetadata("objectLiteralAsArgument.kt") public void testObjectLiteralAsArgument() throws Exception { runTest("compiler/testData/diagnostics/tests/resolve/objectLiteralAsArgument.kt");