[NI] Use new type substitutor instead of old in completion of callable references
It's necessary because of new type substitutor is eager than odl, so if there is a substitution of type parameter deep inside type arguments then second substitutor wins against first #KT-35896 Fixed
This commit is contained in:
Generated
+5
@@ -2382,6 +2382,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt12286.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt12286.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt35896.kt")
|
||||||
|
public void testKt35896() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt35896.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt7470.kt")
|
@TestMetadata("kt7470.kt")
|
||||||
public void testKt7470() throws Exception {
|
public void testKt7470() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt7470.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt7470.kt");
|
||||||
|
|||||||
+16
-11
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
|||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
@@ -255,6 +256,16 @@ class ResolvedAtomCompleter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun NewTypeSubstitutor.toOldSubstitution(): TypeSubstitution = object : TypeSubstitution() {
|
||||||
|
override fun get(key: KotlinType): TypeProjection? {
|
||||||
|
return safeSubstitute(key.unwrap()).takeIf { it !== key }?.asTypeProjection()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isEmpty(): Boolean {
|
||||||
|
return isEmpty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun completeCallableReference(
|
private fun completeCallableReference(
|
||||||
resolvedAtom: ResolvedCallableReferenceAtom
|
resolvedAtom: ResolvedCallableReferenceAtom
|
||||||
) {
|
) {
|
||||||
@@ -264,20 +275,14 @@ class ResolvedAtomCompleter(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val resultTypeParameters =
|
val resultTypeParameters =
|
||||||
callableCandidate.freshSubstitutor!!.freshVariables.map { resultSubstitutor.safeSubstitute(it.defaultType).asTypeProjection() }
|
callableCandidate.freshSubstitutor!!.freshVariables.map { resultSubstitutor.safeSubstitute(it.defaultType) }
|
||||||
|
|
||||||
val firstSubstitutor = IndexedParametersSubstitution(callableCandidate.candidate.typeParameters, resultTypeParameters)
|
val typeParametersSubstitutor = NewTypeSubstitutorByConstructorMap((callableCandidate.candidate.typeParameters.map { it.typeConstructor } zip resultTypeParameters).toMap())
|
||||||
val secondSubstitution = object : TypeSubstitution() {
|
|
||||||
override fun get(key: KotlinType): TypeProjection? {
|
|
||||||
return resultSubstitutor.safeSubstitute(key.unwrap()).takeIf { it !== key }?.asTypeProjection()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isEmpty(): Boolean {
|
val firstSubstitution = typeParametersSubstitutor.toOldSubstitution()
|
||||||
return resultSubstitutor.isEmpty
|
val secondSubstitution = resultSubstitutor.toOldSubstitution()
|
||||||
}
|
|
||||||
}
|
|
||||||
val resultSubstitutor = TypeSubstitutor.createChainedSubstitutor(
|
val resultSubstitutor = TypeSubstitutor.createChainedSubstitutor(
|
||||||
firstSubstitutor,
|
firstSubstitution,
|
||||||
secondSubstitution
|
secondSubstitution
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// !LANGUAGE: +NewInference
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// ISSUE: KT-35896
|
||||||
|
|
||||||
|
interface B<E, SC>
|
||||||
|
|
||||||
|
class Inv<T>
|
||||||
|
|
||||||
|
class Foo<T>(x: Int): B<T, Inv<T>>
|
||||||
|
|
||||||
|
fun <T1, T2, S> bar(list: T2, fn: (S) -> B<T1, T2>) {}
|
||||||
|
|
||||||
|
fun <K> foo(list: Inv<K>) {
|
||||||
|
bar(list, ::Foo)
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// !LANGUAGE: +NewInference
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// ISSUE: KT-35896
|
||||||
|
|
||||||
|
interface B<E, SC>
|
||||||
|
|
||||||
|
class Inv<T>
|
||||||
|
|
||||||
|
class Foo<T>(x: Int): B<T, Inv<T>>
|
||||||
|
|
||||||
|
fun <T1, T2, S> bar(list: T2, fn: (S) -> B<T1, T2>) {}
|
||||||
|
|
||||||
|
fun <K> foo(list: Inv<K>) {
|
||||||
|
bar(list, ::Foo)
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T1, /*1*/ T2, /*2*/ S> bar(/*0*/ list: T2, /*1*/ fn: (S) -> B<T1, T2>): kotlin.Unit
|
||||||
|
public fun </*0*/ K> foo(/*0*/ list: Inv<K>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface B</*0*/ E, /*1*/ SC> {
|
||||||
|
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 Foo</*0*/ T> : B<T, Inv<T>> {
|
||||||
|
public constructor Foo</*0*/ T>(/*0*/ x: kotlin.Int)
|
||||||
|
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 Inv</*0*/ T> {
|
||||||
|
public constructor Inv</*0*/ 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
|
||||||
|
}
|
||||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public fun bar1(/*0*/ a: Array2D<kotlin.Int> /* = kotlin.Array<kotlin.Array<kotlin.Int>> */): Array2D<out kotlin.Number> /* = kotlin.Array<kotlin.Array<out kotlin.Number>> */
|
public fun bar1(/*0*/ a: Array2D<kotlin.Int> /* = kotlin.Array<kotlin.Array<kotlin.Int>> */): Array2D<out kotlin.Number> /* = kotlin.Array<kotlin.Array<out kotlin.Number>> */
|
||||||
public fun bar2(/*0*/ m: TMap<*> /* = kotlin.collections.Map<*, *> */): kotlin.collections.Map<out kotlin.Any?, kotlin.Any?>
|
public fun bar2(/*0*/ m: TMap<*> /* = kotlin.collections.Map<*, *> */): kotlin.collections.Map<*, *>
|
||||||
public fun foo1(/*0*/ a: Array2D<out kotlin.Number> /* = kotlin.Array<kotlin.Array<out kotlin.Number>> */): Array2D<out kotlin.Number> /* = kotlin.Array<kotlin.Array<out kotlin.Number>> */
|
public fun foo1(/*0*/ a: Array2D<out kotlin.Number> /* = kotlin.Array<kotlin.Array<out kotlin.Number>> */): Array2D<out kotlin.Number> /* = kotlin.Array<kotlin.Array<out kotlin.Number>> */
|
||||||
public fun </*0*/ T> foo2(/*0*/ m: TMap<T> /* = kotlin.collections.Map<T, T> */): TMap<T> /* = kotlin.collections.Map<T, T> */
|
public fun </*0*/ T> foo2(/*0*/ m: TMap<T> /* = kotlin.collections.Map<T, T> */): TMap<T> /* = kotlin.collections.Map<T, T> */
|
||||||
public typealias Array2D</*0*/ T> = kotlin.Array<kotlin.Array<T>>
|
public typealias Array2D</*0*/ T> = kotlin.Array<kotlin.Array<T>>
|
||||||
|
|||||||
@@ -2389,6 +2389,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt12286.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt12286.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt35896.kt")
|
||||||
|
public void testKt35896() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt35896.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt7470.kt")
|
@TestMetadata("kt7470.kt")
|
||||||
public void testKt7470() throws Exception {
|
public void testKt7470() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt7470.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt7470.kt");
|
||||||
|
|||||||
Generated
+5
@@ -2384,6 +2384,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt12286.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt12286.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt35896.kt")
|
||||||
|
public void testKt35896() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt35896.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt7470.kt")
|
@TestMetadata("kt7470.kt")
|
||||||
public void testKt7470() throws Exception {
|
public void testKt7470() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt7470.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/generic/kt7470.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user