[FIR] Preserve enhanced mutability when nullability was enhanced for warning
#KT-56989
This commit is contained in:
committed by
Space Team
parent
a63ec9efdc
commit
2005446296
+6
@@ -1189,6 +1189,12 @@ public class FirPsiOldFrontendForeignAnnotationsCompiledJavaTestGenerated extend
|
|||||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mutabilityAndNullabilityForWarning.kt")
|
||||||
|
public void testMutabilityAndNullabilityForWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/mutabilityAndNullabilityForWarning.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notNullVarargsOverrides.kt")
|
@TestMetadata("notNullVarargsOverrides.kt")
|
||||||
public void testNotNullVarargsOverrides() throws Exception {
|
public void testNotNullVarargsOverrides() throws Exception {
|
||||||
|
|||||||
+6
@@ -1247,6 +1247,12 @@ public class FirPsiOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingT
|
|||||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mutabilityAndNullabilityForWarning.kt")
|
||||||
|
public void testMutabilityAndNullabilityForWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/mutabilityAndNullabilityForWarning.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notNullVarargsOverrides.kt")
|
@TestMetadata("notNullVarargsOverrides.kt")
|
||||||
public void testNotNullVarargsOverrides() throws Exception {
|
public void testNotNullVarargsOverrides() throws Exception {
|
||||||
|
|||||||
+6
@@ -1247,6 +1247,12 @@ public class FirPsiOldFrontendForeignAnnotationsSourceJavaTestGenerated extends
|
|||||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mutabilityAndNullabilityForWarning.kt")
|
||||||
|
public void testMutabilityAndNullabilityForWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/mutabilityAndNullabilityForWarning.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notNullVarargsOverrides.kt")
|
@TestMetadata("notNullVarargsOverrides.kt")
|
||||||
public void testNotNullVarargsOverrides() throws Exception {
|
public void testNotNullVarargsOverrides() throws Exception {
|
||||||
|
|||||||
+20
-11
@@ -151,7 +151,10 @@ internal fun FirExpression.checkExpressionForEnhancedTypeMismatch(
|
|||||||
val (actualTypeForComparison, expectedTypeForComparison) = getEnhancedTypesForComparison(actualType, expectedType, context)
|
val (actualTypeForComparison, expectedTypeForComparison) = getEnhancedTypesForComparison(actualType, expectedType, context)
|
||||||
?: return
|
?: return
|
||||||
|
|
||||||
if (!actualTypeForComparison.isSubtypeOf(context.session.typeContext, expectedTypeForComparison)) {
|
if (!actualTypeForComparison.isSubtypeOf(context.session.typeContext, expectedTypeForComparison) &&
|
||||||
|
// Don't report anything if the original types didn't match.
|
||||||
|
actualType.isSubtypeOf(context.session.typeContext, expectedType.asExpectedFunctionTypeIfSam(actualType, context))
|
||||||
|
) {
|
||||||
reporter.reportOn(source, factory, actualTypeForComparison, expectedTypeForComparison, context)
|
reporter.reportOn(source, factory, actualTypeForComparison, expectedTypeForComparison, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,16 +178,22 @@ private fun getEnhancedTypesForComparison(
|
|||||||
val actualTypeForComparison = enhancedActualType ?: actualType
|
val actualTypeForComparison = enhancedActualType ?: actualType
|
||||||
val expectedTypeForComparison = enhancedExpectedType ?: expectedType
|
val expectedTypeForComparison = enhancedExpectedType ?: expectedType
|
||||||
|
|
||||||
val expectedTypeAsFunctionTypeIfSam = if (
|
val expectedTypeAsFunctionTypeIfSam = expectedTypeForComparison.asExpectedFunctionTypeIfSam(actualTypeForComparison, context)
|
||||||
actualTypeForComparison.isSomeFunctionType(context.session) &&
|
|
||||||
!expectedTypeForComparison.isSomeFunctionType(context.session)
|
|
||||||
) {
|
|
||||||
// TODO remove after KT-62847
|
|
||||||
val samResolver = FirSamResolver(context.session, context.scopeSession)
|
|
||||||
samResolver.getFunctionTypeForPossibleSamType(expectedTypeForComparison) ?: expectedTypeForComparison
|
|
||||||
} else {
|
|
||||||
expectedTypeForComparison
|
|
||||||
}
|
|
||||||
|
|
||||||
return actualTypeForComparison to expectedTypeAsFunctionTypeIfSam
|
return actualTypeForComparison to expectedTypeAsFunctionTypeIfSam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the receiver is a SAM type and the [actualType] is a function type, converts the receiver to the corresponding function type.
|
||||||
|
* Otherwise, returns receiver.
|
||||||
|
*
|
||||||
|
* TODO remove after KT-62847
|
||||||
|
* */
|
||||||
|
private fun ConeKotlinType.asExpectedFunctionTypeIfSam(actualType: ConeKotlinType, context: CheckerContext): ConeKotlinType {
|
||||||
|
if (!actualType.isSomeFunctionType(context.session) || isSomeFunctionType(context.session)) {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
val samResolver = FirSamResolver(context.session, context.scopeSession)
|
||||||
|
return samResolver.getFunctionTypeForPossibleSamType(this) ?: this
|
||||||
|
}
|
||||||
|
|||||||
@@ -106,7 +106,14 @@ private fun ConeSimpleKotlinType.enhanceInflexibleType(
|
|||||||
)
|
)
|
||||||
|
|
||||||
return if (effectiveQualifiers.isNullabilityQualifierForWarning && enhanced != null) {
|
return if (effectiveQualifiers.isNullabilityQualifierForWarning && enhanced != null) {
|
||||||
this.withAttributes(attributes.plus(EnhancedTypeForWarningAttribute(enhanced)))
|
val newAttributes = attributes.plus(EnhancedTypeForWarningAttribute(enhanced))
|
||||||
|
|
||||||
|
if (enhancedTag != lookupTag) {
|
||||||
|
// Handle case when mutability was enhanced and nullability was enhanced for warning.
|
||||||
|
enhancedTag.constructType(typeArguments, isNullable, newAttributes)
|
||||||
|
} else {
|
||||||
|
this.withAttributes(newAttributes)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
enhanced
|
enhanced
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// NULLABILITY_ANNOTATIONS: @org.jetbrains.annotations:warn
|
||||||
|
// DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// FILE: ReadOnly.java
|
||||||
|
package org.jetbrains.annotations;
|
||||||
|
|
||||||
|
public @interface ReadOnly {}
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
import java.util.List;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.ReadOnly;
|
||||||
|
|
||||||
|
public class J {
|
||||||
|
@ReadOnly
|
||||||
|
@Nullable
|
||||||
|
public static List<String> foo() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
fun main() {
|
||||||
|
takeMutable(<!ARGUMENT_TYPE_MISMATCH!>J.foo()<!>)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun takeMutable(l: MutableList<String>) {}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// NULLABILITY_ANNOTATIONS: @org.jetbrains.annotations:warn
|
||||||
|
// DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// FILE: ReadOnly.java
|
||||||
|
package org.jetbrains.annotations;
|
||||||
|
|
||||||
|
public @interface ReadOnly {}
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
import java.util.List;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.ReadOnly;
|
||||||
|
|
||||||
|
public class J {
|
||||||
|
@ReadOnly
|
||||||
|
@Nullable
|
||||||
|
public static List<String> foo() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
fun main() {
|
||||||
|
takeMutable(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>J.foo()<!>)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun takeMutable(l: MutableList<String>) {}
|
||||||
+6
@@ -1189,6 +1189,12 @@ public class ForeignAnnotationsCompiledJavaTestGenerated extends AbstractForeign
|
|||||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mutabilityAndNullabilityForWarning.kt")
|
||||||
|
public void testMutabilityAndNullabilityForWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/mutabilityAndNullabilityForWarning.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notNullVarargsOverrides.kt")
|
@TestMetadata("notNullVarargsOverrides.kt")
|
||||||
public void testNotNullVarargsOverrides() throws Exception {
|
public void testNotNullVarargsOverrides() throws Exception {
|
||||||
|
|||||||
+6
@@ -1247,6 +1247,12 @@ public class ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated exte
|
|||||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mutabilityAndNullabilityForWarning.kt")
|
||||||
|
public void testMutabilityAndNullabilityForWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/mutabilityAndNullabilityForWarning.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notNullVarargsOverrides.kt")
|
@TestMetadata("notNullVarargsOverrides.kt")
|
||||||
public void testNotNullVarargsOverrides() throws Exception {
|
public void testNotNullVarargsOverrides() throws Exception {
|
||||||
|
|||||||
+6
@@ -1247,6 +1247,12 @@ public class ForeignAnnotationsSourceJavaTestGenerated extends AbstractForeignAn
|
|||||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/methodWithTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mutabilityAndNullabilityForWarning.kt")
|
||||||
|
public void testMutabilityAndNullabilityForWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/mutabilityAndNullabilityForWarning.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notNullVarargsOverrides.kt")
|
@TestMetadata("notNullVarargsOverrides.kt")
|
||||||
public void testNotNullVarargsOverrides() throws Exception {
|
public void testNotNullVarargsOverrides() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user