Fix overload ambiguity after smartcast to nullable Nothing
#KT-39544 Fixed
This commit is contained in:
+5
@@ -21422,6 +21422,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
|||||||
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt");
|
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("smartcastToNothingAfterCheckingForNull.kt")
|
||||||
|
public void testSmartcastToNothingAfterCheckingForNull() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastToNothingAfterCheckingForNull.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("thisWithLabel.kt")
|
@TestMetadata("thisWithLabel.kt")
|
||||||
public void testThisWithLabel() throws Exception {
|
public void testThisWithLabel() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt");
|
runTest("compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt");
|
||||||
|
|||||||
+9
@@ -32,6 +32,8 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastI
|
|||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
import org.jetbrains.kotlin.types.checker.intersectWrappedTypes
|
import org.jetbrains.kotlin.types.checker.intersectWrappedTypes
|
||||||
import org.jetbrains.kotlin.types.checker.prepareArgumentTypeRegardingCaptureTypes
|
import org.jetbrains.kotlin.types.checker.prepareArgumentTypeRegardingCaptureTypes
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.isNullableNothing
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import org.jetbrains.kotlin.utils.DFS
|
import org.jetbrains.kotlin.utils.DFS
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -71,6 +73,13 @@ val ReceiverValueWithSmartCastInfo.stableType: UnwrappedType
|
|||||||
*/
|
*/
|
||||||
val intersectionType = intersectWrappedTypes(allOriginalTypes)
|
val intersectionType = intersectWrappedTypes(allOriginalTypes)
|
||||||
|
|
||||||
|
// Intersection type of Nothing with any flexible types will be Nothing!.
|
||||||
|
// This is a bit incorrect as cast to Nothing? or Nothing can result only in Nothing? or Nothing,
|
||||||
|
// otherwise it'll be possible to pass null to some non-nullable type
|
||||||
|
if (intersectionType.isNullableNothing() && !intersectionType.isMarkedNullable) {
|
||||||
|
return intersectionType.makeNullable().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
return prepareArgumentTypeRegardingCaptureTypes(intersectionType) ?: intersectionType
|
return prepareArgumentTypeRegardingCaptureTypes(intersectionType) ?: intersectionType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class My {
|
|||||||
fun test() {
|
fun test() {
|
||||||
val my = My.create()
|
val my = My.create()
|
||||||
if (my == null) {
|
if (my == null) {
|
||||||
<!OI;DEBUG_INFO_CONSTANT!>my<!><!OI;UNSAFE_CALL!>.<!>foo()
|
<!OI;DEBUG_INFO_CONSTANT!>my<!><!UNSAFE_CALL!>.<!>foo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// FILE: B.java
|
||||||
|
|
||||||
|
public abstract class B<T> implements A<T> {}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
interface A<T> {
|
||||||
|
val content: T
|
||||||
|
}
|
||||||
|
fun f(x: Any?) {}
|
||||||
|
fun f(x: Byte) {}
|
||||||
|
fun f(x: Char) {}
|
||||||
|
|
||||||
|
fun g(i: Int) {}
|
||||||
|
|
||||||
|
fun g(x: B<Int>) {
|
||||||
|
val y = x.content
|
||||||
|
if (y == null) {
|
||||||
|
f(y)
|
||||||
|
g(y)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y is Nothing?) {
|
||||||
|
<!AMBIGUITY!>f<!>(y)
|
||||||
|
<!AMBIGUITY!>g<!>(y)
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// FILE: B.java
|
||||||
|
|
||||||
|
public abstract class B<T> implements A<T> {}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
interface A<T> {
|
||||||
|
val content: T
|
||||||
|
}
|
||||||
|
fun f(x: Any?) {}
|
||||||
|
fun f(x: Byte) {}
|
||||||
|
fun f(x: Char) {}
|
||||||
|
|
||||||
|
fun g(i: Int) {}
|
||||||
|
|
||||||
|
fun g(x: B<Int>) {
|
||||||
|
val y = x.content
|
||||||
|
if (y == null) {
|
||||||
|
f(<!DEBUG_INFO_CONSTANT!>y<!>)
|
||||||
|
<!NONE_APPLICABLE!>g<!>(<!DEBUG_INFO_CONSTANT!>y<!>)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y is Nothing?) {
|
||||||
|
f(y)
|
||||||
|
<!NONE_APPLICABLE!>g<!>(y)
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun f(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun f(/*0*/ x: kotlin.Byte): kotlin.Unit
|
||||||
|
public fun f(/*0*/ x: kotlin.Char): kotlin.Unit
|
||||||
|
public fun g(/*0*/ x: B<kotlin.Int>): kotlin.Unit
|
||||||
|
public fun g(/*0*/ i: kotlin.Int): kotlin.Unit
|
||||||
|
|
||||||
|
public interface A</*0*/ T> {
|
||||||
|
public abstract val content: T
|
||||||
|
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 abstract class B</*0*/ T : kotlin.Any!> : A<T!> {
|
||||||
|
public constructor B</*0*/ T : kotlin.Any!>()
|
||||||
|
public abstract override /*1*/ /*fake_override*/ val content: T!
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -21499,6 +21499,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
|
|||||||
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt");
|
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("smartcastToNothingAfterCheckingForNull.kt")
|
||||||
|
public void testSmartcastToNothingAfterCheckingForNull() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastToNothingAfterCheckingForNull.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("thisWithLabel.kt")
|
@TestMetadata("thisWithLabel.kt")
|
||||||
public void testThisWithLabel() throws Exception {
|
public void testThisWithLabel() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt");
|
runTest("compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt");
|
||||||
|
|||||||
Generated
+5
@@ -21424,6 +21424,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt");
|
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("smartcastToNothingAfterCheckingForNull.kt")
|
||||||
|
public void testSmartcastToNothingAfterCheckingForNull() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastToNothingAfterCheckingForNull.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("thisWithLabel.kt")
|
@TestMetadata("thisWithLabel.kt")
|
||||||
public void testThisWithLabel() throws Exception {
|
public void testThisWithLabel() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt");
|
runTest("compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user