diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 4719e886f58..dcec8916226 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -4594,6 +4594,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/checkArguments/kt49276Error.kt"); } + @Test + @TestMetadata("kt51062.kt") + public void testKt51062() throws Exception { + runTest("compiler/testData/diagnostics/tests/checkArguments/kt51062.kt"); + } + @Test @TestMetadata("overloadedFunction.kt") public void testOverloadedFunction() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 41928d17502..7fd261a1a29 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -4594,6 +4594,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/checkArguments/kt49276Error.kt"); } + @Test + @TestMetadata("kt51062.kt") + public void testKt51062() throws Exception { + runTest("compiler/testData/diagnostics/tests/checkArguments/kt51062.kt"); + } + @Test @TestMetadata("overloadedFunction.kt") public void testOverloadedFunction() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index a36b97b7ec8..e0b118c1d37 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -4594,6 +4594,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/checkArguments/kt49276Error.kt"); } + @Test + @TestMetadata("kt51062.kt") + public void testKt51062() throws Exception { + runTest("compiler/testData/diagnostics/tests/checkArguments/kt51062.kt"); + } + @Test @TestMetadata("overloadedFunction.kt") public void testOverloadedFunction() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/CallResolverUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/CallResolverUtil.kt index a1cf93fd3a5..49b3b835da4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/CallResolverUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/CallResolverUtil.kt @@ -372,7 +372,7 @@ internal fun List.replaceTypes( internal fun PSIKotlinCall.replaceArguments( newArguments: List, - newReceiverArgument: ReceiverExpressionKotlinCallArgument? = null, + newReceiverArgument: ReceiverKotlinCallArgument? = null, ): PSIKotlinCall = PSIKotlinCallImpl( callKind, psiCall, tracingStrategy, newReceiverArgument, dispatchReceiverForInvokeExtension, name, typeArguments, newArguments, externalArgument, startingDataFlowInfo, resultDataFlowInfo, dataFlowInfoForArguments, isForImplicitInvoke diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PassingProgressionAsCollectionCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PassingProgressionAsCollectionCallChecker.kt index ec3c86c95e1..4769d4ef349 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PassingProgressionAsCollectionCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PassingProgressionAsCollectionCallChecker.kt @@ -78,7 +78,7 @@ class PassingProgressionAsCollectionCallChecker(private val kotlinCallResolver: ) ) } - val newCall = kotlinCall.replaceArguments(newArguments) + val newCall = kotlinCall.replaceArguments(newArguments, kotlinCall.explicitReceiver) val candidateForCollectionReplacedArgument = kotlinCallResolver.resolveCall( scopeTower, resolutionCallbacks, newCall, expectedType, context.collectAllCandidates @@ -107,12 +107,12 @@ class PassingProgressionAsCollectionCallChecker(private val kotlinCallResolver: } else type } ?: continue - val cons = alternativeParameterType.constructor + val alternativeParameterTypeConstructor = alternativeParameterType.upperIfFlexible().constructor - if (cons.declarationDescriptor != builtIns.collection && (cons !is IntersectionTypeConstructor || cons.supertypes.none { it.constructor.declarationDescriptor == builtIns.collection })) continue + if (alternativeParameterTypeConstructor.declarationDescriptor != builtIns.collection && (alternativeParameterTypeConstructor !is IntersectionTypeConstructor || alternativeParameterTypeConstructor.supertypes.none { it.constructor.declarationDescriptor == builtIns.collection })) continue val argumentExpression = argument.psiExpression ?: continue - val initialArgumentType = resolvedCall.candidateDescriptor.valueParameters.getOrNull(i)?.type ?: continue + val initialArgumentType = resolvedCall.candidateDescriptor.valueParameters.getOrNull(i)?.type?.upperIfFlexible() ?: continue // Iterable initial type is an exception, considered as similar to Collection passing candidate if (initialArgumentType.constructor.declarationDescriptor == builtIns.iterable) continue diff --git a/compiler/testData/diagnostics/tests/checkArguments/kt51062.fir.kt b/compiler/testData/diagnostics/tests/checkArguments/kt51062.fir.kt new file mode 100644 index 00000000000..d63df4215b0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/checkArguments/kt51062.fir.kt @@ -0,0 +1,53 @@ +// WITH_STDLIB +// FULL_JDK + +// FILE: JavaSmartList.java +import kotlin.ranges.ClosedRange; + +import java.util.Collection; + +public class JavaSmartList { + JavaSmartList(E x) {} + JavaSmartList(Collection x) {} + + static void append(Object x) {} + static void append(Collection x) {} + + static void append2(Iterable x) {} + static void append2(Collection x) {} + + public static class In { + In(T x) {} + } + + static void append3(In x) {} + static void append3(In> x) {} + + static void append4(E x) {} + static > void append4(E x) {} + + static void takes(T x) {} + static & ClosedRange> void takes(T x) {} +} + +// FILE: main.kt +fun main() { + JavaSmartList(1..2) // warning + JavaSmartList(1..10) // no warning + + JavaSmartList.append(1..10) // warning + JavaSmartList.append((1..10) as Any) // no warning + JavaSmartList.append((1..10) as Iterable) // no warning + JavaSmartList.append("a".."z") // no warning, the range is not iterable + JavaSmartList.append(1.0..2.0) + + JavaSmartList.append2(1..10) // no warning + + JavaSmartList.append3(JavaSmartList.In(1..10)) // no warning + + JavaSmartList.append4(1..10) // warning + + JavaSmartList.append4(1..10) // warning + + JavaSmartList.takes(1..10) // warning +} diff --git a/compiler/testData/diagnostics/tests/checkArguments/kt51062.kt b/compiler/testData/diagnostics/tests/checkArguments/kt51062.kt new file mode 100644 index 00000000000..aa51cc3dad8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/checkArguments/kt51062.kt @@ -0,0 +1,53 @@ +// WITH_STDLIB +// FULL_JDK + +// FILE: JavaSmartList.java +import kotlin.ranges.ClosedRange; + +import java.util.Collection; + +public class JavaSmartList { + JavaSmartList(E x) {} + JavaSmartList(Collection x) {} + + static void append(Object x) {} + static void append(Collection x) {} + + static void append2(Iterable x) {} + static void append2(Collection x) {} + + public static class In { + In(T x) {} + } + + static void append3(In x) {} + static void append3(In> x) {} + + static void append4(E x) {} + static > void append4(E x) {} + + static void takes(T x) {} + static & ClosedRange> void takes(T x) {} +} + +// FILE: main.kt +fun main() { + JavaSmartList((x: (Mutable)Collection!)")!>1..2) // warning + JavaSmartList(1..10) // no warning + + JavaSmartList.append(!): Unit")!>1..10) // warning + JavaSmartList.append((1..10) as Any) // no warning + JavaSmartList.append((1..10) as Iterable) // no warning + JavaSmartList.append("a".."z") // no warning, the range is not iterable + JavaSmartList.append(1.0..2.0) + + JavaSmartList.append2(1..10) // no warning + + JavaSmartList.append3(JavaSmartList.In(1..10)) // no warning + + JavaSmartList.append4(!> append4(x: E!): Unit")!>1..10) // warning + + JavaSmartList.append4(1..10) // warning + + JavaSmartList.takes(!> takes(x: T!): Unit where T : ClosedRange<*>!")!>1..10) // warning +} diff --git a/compiler/testData/diagnostics/tests/checkArguments/kt51062.txt b/compiler/testData/diagnostics/tests/checkArguments/kt51062.txt new file mode 100644 index 00000000000..274335c1529 --- /dev/null +++ b/compiler/testData/diagnostics/tests/checkArguments/kt51062.txt @@ -0,0 +1,30 @@ +package + +public fun main(): kotlin.Unit + +public open class JavaSmartList { + public/*package*/ constructor JavaSmartList(/*0*/ x: E!) + public/*package*/ constructor JavaSmartList(/*0*/ x: kotlin.collections.(Mutable)Collection!) + 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 open class In { + public/*package*/ constructor In(/*0*/ x: 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 + } + + // Static members + public/*package*/ open fun append(/*0*/ x: kotlin.Any!): kotlin.Unit + public/*package*/ open fun append(/*0*/ x: kotlin.collections.(Mutable)Collection<*>!): kotlin.Unit + public/*package*/ open fun append2(/*0*/ x: kotlin.collections.(Mutable)Collection<*>!): kotlin.Unit + public/*package*/ open fun append2(/*0*/ x: kotlin.collections.(Mutable)Iterable<*>!): kotlin.Unit + public/*package*/ open fun append3(/*0*/ x: JavaSmartList.In<*>!): kotlin.Unit + public/*package*/ open fun append3(/*0*/ x: JavaSmartList.In!>!): kotlin.Unit + public/*package*/ open fun append4(/*0*/ x: E!): kotlin.Unit + public/*package*/ open fun !> append4(/*0*/ x: E!): kotlin.Unit + public/*package*/ open fun takes(/*0*/ x: T!): kotlin.Unit + public/*package*/ open fun !> takes(/*0*/ x: T!): kotlin.Unit where T : kotlin.ranges.ClosedRange<*>! +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index ef7f3b17c42..3d422d6bf85 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -4600,6 +4600,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/checkArguments/kt49276Error.kt"); } + @Test + @TestMetadata("kt51062.kt") + public void testKt51062() throws Exception { + runTest("compiler/testData/diagnostics/tests/checkArguments/kt51062.kt"); + } + @Test @TestMetadata("overloadedFunction.kt") public void testOverloadedFunction() throws Exception {