[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");
|
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")
|
@TestMetadata("objectLiteralAsArgument.kt")
|
||||||
public void testObjectLiteralAsArgument() throws Exception {
|
public void testObjectLiteralAsArgument() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/resolve/objectLiteralAsArgument.kt");
|
runTest("compiler/testData/diagnostics/tests/resolve/objectLiteralAsArgument.kt");
|
||||||
|
|||||||
+3
-2
@@ -571,8 +571,9 @@ class StateMachineBuilder(
|
|||||||
|
|
||||||
override fun visitReturn(expression: IrReturn) {
|
override fun visitReturn(expression: IrReturn) {
|
||||||
expression.acceptChildrenVoid(this)
|
expression.acceptChildrenVoid(this)
|
||||||
if (expression.returnTargetSymbol is IrReturnableBlockSymbol) {
|
val returnTarget = expression.returnTargetSymbol
|
||||||
val (exitState, varSymbol) = returnableBlockMap[expression.returnTargetSymbol]!!
|
if (returnTarget is IrReturnableBlockSymbol) {
|
||||||
|
val (exitState, varSymbol) = returnableBlockMap[returnTarget]!!
|
||||||
if (varSymbol != null) {
|
if (varSymbol != null) {
|
||||||
transformLastExpression { JsIrBuilder.buildSetVariable(varSymbol, it, it.type) }
|
transformLastExpression { JsIrBuilder.buildSetVariable(varSymbol, it, it.type) }
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -64,7 +64,7 @@ private fun checkExpressionArgument(
|
|||||||
): KotlinCallDiagnostic? {
|
): KotlinCallDiagnostic? {
|
||||||
if (unstableType != null) {
|
if (unstableType != null) {
|
||||||
if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, actualExpectedType, position)) {
|
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)
|
val expectedNullableType = expectedType.makeNullableAsSpecified(true)
|
||||||
|
|
||||||
if (unstableType != null && csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
|
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)) {
|
} else if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
|
||||||
diagnosticsHolder.addDiagnostic(UnsafeCallError(expressionArgument))
|
diagnosticsHolder.addDiagnostic(UnsafeCallError(expressionArgument))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+16
-3
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceCandidate
|
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
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.resolve.calls.tower.ResolutionCandidateApplicability.*
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
@@ -138,11 +139,23 @@ class SmartCastDiagnostic(
|
|||||||
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this)
|
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnstableSmartCast(
|
class UnstableSmartCast private constructor(
|
||||||
val argument: ExpressionKotlinCallArgument,
|
val argument: ExpressionKotlinCallArgument,
|
||||||
val targetType: UnwrappedType
|
val targetType: UnwrappedType,
|
||||||
) : KotlinCallDiagnostic(RESOLVED_WITH_ERROR) {
|
applicability: ResolutionCandidateApplicability,
|
||||||
|
) : KotlinCallDiagnostic(applicability) {
|
||||||
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this)
|
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) {
|
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)
|
list.remove(arg.first)
|
||||||
if (arg.first?.isEmpty() ?: false) {
|
if (arg.first?.isEmpty() ?: false) {
|
||||||
// Should be still resolved to extension, without smart cast or smart cast impossible
|
// 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)
|
list.remove(arg.first)
|
||||||
if (arg.first ?: false) {
|
if (arg.first ?: false) {
|
||||||
// Should be still resolved to extension, without smart cast or smart cast impossible
|
// 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!!
|
fun create(): Map<String, String> = null!!
|
||||||
|
|
||||||
operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = 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!!
|
fun create(): Map<String, String> = null!!
|
||||||
|
|
||||||
operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = null!!
|
operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = null!!
|
||||||
@@ -13,7 +15,7 @@ class MyClass {
|
|||||||
m = create()
|
m = create()
|
||||||
// See KT-7428
|
// See KT-7428
|
||||||
for ((k, v) in <!SMARTCAST_IMPOSSIBLE!>m<!>)
|
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
|
return res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18389,6 +18389,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/resolve/newLineLambda.kt");
|
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")
|
@TestMetadata("objectLiteralAsArgument.kt")
|
||||||
public void testObjectLiteralAsArgument() throws Exception {
|
public void testObjectLiteralAsArgument() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/resolve/objectLiteralAsArgument.kt");
|
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");
|
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")
|
@TestMetadata("objectLiteralAsArgument.kt")
|
||||||
public void testObjectLiteralAsArgument() throws Exception {
|
public void testObjectLiteralAsArgument() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/resolve/objectLiteralAsArgument.kt");
|
runTest("compiler/testData/diagnostics/tests/resolve/objectLiteralAsArgument.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user