[NI] Fix substitution in completion of callable references in coroutine inference
This commit is contained in:
+2
@@ -237,4 +237,6 @@ class ComposedSubstitutor(val left: NewTypeSubstitutor, val right: NewTypeSubsti
|
|||||||
right.substituteNotNullTypeWithConstructor(constructor)?.constructor ?: constructor
|
right.substituteNotNullTypeWithConstructor(constructor)?.constructor ?: constructor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val isEmpty: Boolean get() = left.isEmpty && right.isEmpty
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-5
@@ -264,15 +264,25 @@ class ResolvedAtomCompleter(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val resultTypeParameters =
|
val resultTypeParameters =
|
||||||
callableCandidate.freshSubstitutor!!.freshVariables.map { resultSubstitutor.safeSubstitute(it.defaultType) }
|
callableCandidate.freshSubstitutor!!.freshVariables.map { resultSubstitutor.safeSubstitute(it.defaultType).asTypeProjection() }
|
||||||
|
|
||||||
|
val firstSubstitutor = IndexedParametersSubstitution(callableCandidate.candidate.typeParameters, resultTypeParameters)
|
||||||
|
val secondSubstitution = object : TypeSubstitution() {
|
||||||
|
override fun get(key: KotlinType): TypeProjection? {
|
||||||
|
return resultSubstitutor.safeSubstitute(key.unwrap()).takeIf { it !== key }?.asTypeProjection()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isEmpty(): Boolean {
|
||||||
|
return resultSubstitutor.isEmpty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val resultSubstitutor = TypeSubstitutor.createChainedSubstitutor(
|
||||||
|
firstSubstitutor,
|
||||||
|
secondSubstitution
|
||||||
|
)
|
||||||
|
|
||||||
val psiCallArgument = resolvedAtom.atom.psiCallArgument as CallableReferenceKotlinCallArgumentImpl
|
val psiCallArgument = resolvedAtom.atom.psiCallArgument as CallableReferenceKotlinCallArgumentImpl
|
||||||
val callableReferenceExpression = psiCallArgument.ktCallableReferenceExpression
|
val callableReferenceExpression = psiCallArgument.ktCallableReferenceExpression
|
||||||
val resultSubstitutor = IndexedParametersSubstitution(
|
|
||||||
callableCandidate.candidate.typeParameters,
|
|
||||||
resultTypeParameters.map { it.asTypeProjection() }).buildSubstitutor()
|
|
||||||
|
|
||||||
|
|
||||||
// write down type for callable reference expression
|
// write down type for callable reference expression
|
||||||
val resultType = resultSubstitutor.safeSubstitute(callableCandidate.reflectionCandidateType, Variance.INVARIANT)
|
val resultType = resultSubstitutor.safeSubstitute(callableCandidate.reflectionCandidateType, Variance.INVARIANT)
|
||||||
|
|||||||
+10
@@ -21,6 +21,8 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
|||||||
fun safeSubstitute(type: UnwrappedType): UnwrappedType =
|
fun safeSubstitute(type: UnwrappedType): UnwrappedType =
|
||||||
substitute(type, runCapturedChecks = true, keepAnnotation = true) ?: type
|
substitute(type, runCapturedChecks = true, keepAnnotation = true) ?: type
|
||||||
|
|
||||||
|
val isEmpty: Boolean
|
||||||
|
|
||||||
private fun substitute(type: UnwrappedType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? =
|
private fun substitute(type: UnwrappedType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? =
|
||||||
when (type) {
|
when (type) {
|
||||||
is SimpleType -> substitute(type, keepAnnotation, runCapturedChecks)
|
is SimpleType -> substitute(type, keepAnnotation, runCapturedChecks)
|
||||||
@@ -170,10 +172,14 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
|||||||
|
|
||||||
object EmptySubstitutor : NewTypeSubstitutor {
|
object EmptySubstitutor : NewTypeSubstitutor {
|
||||||
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = null
|
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = null
|
||||||
|
|
||||||
|
override val isEmpty: Boolean get() = true
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewTypeSubstitutorByConstructorMap(val map: Map<TypeConstructor, UnwrappedType>) : NewTypeSubstitutor {
|
class NewTypeSubstitutorByConstructorMap(val map: Map<TypeConstructor, UnwrappedType>) : NewTypeSubstitutor {
|
||||||
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = map[constructor]
|
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = map[constructor]
|
||||||
|
|
||||||
|
override val isEmpty: Boolean get() = map.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
class FreshVariableNewTypeSubstitutor(val freshVariables: List<TypeVariableFromCallableDescriptor>) : NewTypeSubstitutor {
|
class FreshVariableNewTypeSubstitutor(val freshVariables: List<TypeVariableFromCallableDescriptor>) : NewTypeSubstitutor {
|
||||||
@@ -185,6 +191,8 @@ class FreshVariableNewTypeSubstitutor(val freshVariables: List<TypeVariableFromC
|
|||||||
return typeVariable.defaultType
|
return typeVariable.defaultType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val isEmpty: Boolean get() = freshVariables.isEmpty()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val Empty = FreshVariableNewTypeSubstitutor(emptyList())
|
val Empty = FreshVariableNewTypeSubstitutor(emptyList())
|
||||||
}
|
}
|
||||||
@@ -205,6 +213,8 @@ fun createCompositeSubstitutor(appliedFirst: NewTypeSubstitutor, appliedLast: Ty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val isEmpty: Boolean get() = appliedFirst.isEmpty && appliedLast.isEmpty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// !LANGUAGE: +NewInference
|
||||||
|
// ISSUE: KT-33545
|
||||||
|
|
||||||
|
import kotlin.experimental.ExperimentalTypeInference
|
||||||
|
|
||||||
|
interface Flow<out T> {
|
||||||
|
suspend fun collect(collector: FlowCollector<T>)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FlowCollector<in T> {
|
||||||
|
suspend fun emit(value: T)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> Flow<T>.collect(crossinline action: suspend (value: T) -> Unit): Unit {}
|
||||||
|
|
||||||
|
abstract class LiveData<T>
|
||||||
|
|
||||||
|
interface LiveDataScope<T> {
|
||||||
|
suspend fun emit(value: T)
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseExperimental(ExperimentalTypeInference::class)
|
||||||
|
fun <T> liveData(@BuilderInference block: suspend LiveDataScope<T>.() -> Unit): LiveData<T> = null!!
|
||||||
|
|
||||||
|
fun <Value> Flow<Value>.asLiveData() = liveData {
|
||||||
|
collect(this::emit)
|
||||||
|
// collect { emit(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String = "OK"
|
||||||
+5
@@ -12518,6 +12518,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("builderInference.kt")
|
||||||
|
public void testBuilderInference() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inference/builderInference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("capturedStarProjection.kt")
|
@TestMetadata("capturedStarProjection.kt")
|
||||||
public void testCapturedStarProjection() throws Exception {
|
public void testCapturedStarProjection() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
||||||
|
|||||||
+5
@@ -12518,6 +12518,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("builderInference.kt")
|
||||||
|
public void testBuilderInference() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inference/builderInference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("capturedStarProjection.kt")
|
@TestMetadata("capturedStarProjection.kt")
|
||||||
public void testCapturedStarProjection() throws Exception {
|
public void testCapturedStarProjection() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
||||||
|
|||||||
+5
@@ -11368,6 +11368,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("builderInference.kt")
|
||||||
|
public void testBuilderInference() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inference/builderInference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("capturedStarProjection.kt")
|
@TestMetadata("capturedStarProjection.kt")
|
||||||
public void testCapturedStarProjection() throws Exception {
|
public void testCapturedStarProjection() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
||||||
|
|||||||
+5
@@ -11368,6 +11368,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("builderInference.kt")
|
||||||
|
public void testBuilderInference() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inference/builderInference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("capturedStarProjection.kt")
|
@TestMetadata("capturedStarProjection.kt")
|
||||||
public void testCapturedStarProjection() throws Exception {
|
public void testCapturedStarProjection() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user