[NI] Continue resolution after unstable smart cast on receiver
The old inference cosideres candidates with unstable smartcast on receiver unsuccessful, therefore another one may be selected. KT-36264
This commit is contained in:
Generated
+5
@@ -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");
|
||||
|
||||
+3
-2
@@ -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) }
|
||||
}
|
||||
|
||||
+2
-2
@@ -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 {
|
||||
|
||||
+16
-3
@@ -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) {
|
||||
|
||||
+27
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -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
|
||||
}
|
||||
@@ -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(<!OI;SMARTCAST_IMPOSSIBLE!>arg.first<!>)
|
||||
list.remove(<!NI;SMARTCAST_IMPOSSIBLE, SMARTCAST_IMPOSSIBLE!>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(<!OI;SMARTCAST_IMPOSSIBLE!>arg.first<!>)
|
||||
list.remove(<!NI;SMARTCAST_IMPOSSIBLE, SMARTCAST_IMPOSSIBLE!>arg.first<!>)
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
|
||||
fun create(): Map<String, String> = null!!
|
||||
|
||||
operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = null!!
|
||||
|
||||
+3
-1
@@ -1,3 +1,5 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
|
||||
fun create(): Map<String, String> = null!!
|
||||
|
||||
operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = null!!
|
||||
@@ -13,7 +15,7 @@ class MyClass {
|
||||
m = create()
|
||||
// See KT-7428
|
||||
for ((k, v) in <!SMARTCAST_IMPOSSIBLE!>m<!>)
|
||||
res += (k.length + v.length)
|
||||
res <!NI;OVERLOAD_RESOLUTION_AMBIGUITY!>+=<!> (<!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>k<!>.<!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>length<!> <!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> <!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>v<!>.<!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>length<!>)
|
||||
return res
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user