diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsCompiledJavaTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsCompiledJavaTestGenerated.java index dc67c95aa68..b3b2186013e 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsCompiledJavaTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsCompiledJavaTestGenerated.java @@ -714,6 +714,12 @@ public class FirOldFrontendForeignAnnotationsCompiledJavaTestGenerated extends A runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { @@ -796,6 +802,12 @@ public class FirOldFrontendForeignAnnotationsCompiledJavaTestGenerated extends A runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java index b1fa7d7362e..af3e98aa3f7 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java @@ -714,6 +714,12 @@ public class FirOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTest runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { @@ -796,6 +802,12 @@ public class FirOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTest runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsSourceJavaTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsSourceJavaTestGenerated.java index 23e48f31063..8a134e345b4 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsSourceJavaTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendForeignAnnotationsSourceJavaTestGenerated.java @@ -714,6 +714,12 @@ public class FirOldFrontendForeignAnnotationsSourceJavaTestGenerated extends Abs runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { @@ -796,6 +802,12 @@ public class FirOldFrontendForeignAnnotationsSourceJavaTestGenerated extends Abs runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.fir.kt new file mode 100644 index 00000000000..88b59d781f4 --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.fir.kt @@ -0,0 +1,18 @@ +// JSPECIFY_STATE: strict +// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode + +// FILE: J1.java +import org.jspecify.nullness.*; + +@NullMarked +public interface J1 { + T foo(); +} + +// FILE: J2.java +public interface J2 { + J1 bar(); +} + +// FILE: main.kt +fun baz(j2: J2): Any = j2.bar().foo() // Any..Any? diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.kt new file mode 100644 index 00000000000..53881e2a111 --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.kt @@ -0,0 +1,18 @@ +// JSPECIFY_STATE: strict +// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode + +// FILE: J1.java +import org.jspecify.nullness.*; + +@NullMarked +public interface J1 { + T foo(); +} + +// FILE: J2.java +public interface J2 { + J1 bar(); +} + +// FILE: main.kt +fun baz(j2: J2): Any = j2.bar().foo() // Any..Any? diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.txt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.txt new file mode 100644 index 00000000000..3b0f82a6d99 --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.txt @@ -0,0 +1,17 @@ +package + +public fun baz(/*0*/ j2: J2): kotlin.Any + +@org.jspecify.nullness.NullMarked public interface J1 { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): T + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface J2 { + public abstract fun bar(): J1! + 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 +} diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.kt new file mode 100644 index 00000000000..6344ec52ed3 --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.kt @@ -0,0 +1,17 @@ +// FIR_IDENTICAL +// JSPECIFY_STATE: warn +// FILE: J1.java +import org.jspecify.nullness.*; + +@NullMarked +public interface J1 { + T foo(); +} + +// FILE: J2.java +public interface J2 { + J1 bar(); +} + +// FILE: main.kt +fun baz(j2: J2): Any = j2.bar().foo() // Any..Any? diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.txt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.txt new file mode 100644 index 00000000000..c29daea928d --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.txt @@ -0,0 +1,17 @@ +package + +public fun baz(/*0*/ j2: J2): kotlin.Any + +@org.jspecify.nullness.NullMarked public interface J1 { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): T! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface J2 { + public abstract fun bar(): J1! + 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 +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaTestGenerated.java index 180c59643e5..d8db3a432e6 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaTestGenerated.java @@ -714,6 +714,12 @@ public class ForeignAnnotationsCompiledJavaTestGenerated extends AbstractForeign runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { @@ -796,6 +802,12 @@ public class ForeignAnnotationsCompiledJavaTestGenerated extends AbstractForeign runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java index a38af1a3c0c..96361164d9f 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java @@ -714,6 +714,12 @@ public class ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated exte runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { @@ -796,6 +802,12 @@ public class ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated exte runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsSourceJavaTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsSourceJavaTestGenerated.java index 1d54a1859d0..7d68bae0702 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsSourceJavaTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsSourceJavaTestGenerated.java @@ -714,6 +714,12 @@ public class ForeignAnnotationsSourceJavaTestGenerated extends AbstractForeignAn runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { @@ -796,6 +802,12 @@ public class ForeignAnnotationsSourceJavaTestGenerated extends AbstractForeignAn runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.kt"); } + @Test + @TestMetadata("UnannotatedWildcard.kt") + public void testUnannotatedWildcard() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/UnannotatedWildcard.kt"); + } + @Test @TestMetadata("WildcardsWithDefault.kt") public void testWildcardsWithDefault() throws Exception { diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt index b16b5048867..b964eee52ea 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt @@ -119,6 +119,16 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings val enhanced = when { !shouldEnhanceArguments -> Result(null, 0) !arg.isStarProjection -> arg.type.unwrap().enhancePossiblyFlexible(qualifiers, globalArgIndex, isSuperTypesEnhancement) + qualifiers(globalArgIndex).nullability == FORCE_FLEXIBILITY -> + arg.type.unwrap().let { + // Given `C`, unannotated `C` is `C`. + Result( + KotlinTypeFactory.flexibleType( + it.lowerIfFlexible().makeNullableAsSpecified(false), + it.upperIfFlexible().makeNullableAsSpecified(true) + ), 1 + ) + } else -> Result(null, 1) } globalArgIndex += enhanced.subtreeSize