[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
|
||||
)
|
||||
}
|
||||
|
||||
override val isEmpty: Boolean get() = left.isEmpty && right.isEmpty
|
||||
}
|
||||
|
||||
+15
-5
@@ -264,15 +264,25 @@ class ResolvedAtomCompleter(
|
||||
return
|
||||
}
|
||||
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 callableReferenceExpression = psiCallArgument.ktCallableReferenceExpression
|
||||
val resultSubstitutor = IndexedParametersSubstitution(
|
||||
callableCandidate.candidate.typeParameters,
|
||||
resultTypeParameters.map { it.asTypeProjection() }).buildSubstitutor()
|
||||
|
||||
|
||||
// write down type for callable reference expression
|
||||
val resultType = resultSubstitutor.safeSubstitute(callableCandidate.reflectionCandidateType, Variance.INVARIANT)
|
||||
|
||||
+10
@@ -21,6 +21,8 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
||||
fun safeSubstitute(type: UnwrappedType): UnwrappedType =
|
||||
substitute(type, runCapturedChecks = true, keepAnnotation = true) ?: type
|
||||
|
||||
val isEmpty: Boolean
|
||||
|
||||
private fun substitute(type: UnwrappedType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? =
|
||||
when (type) {
|
||||
is SimpleType -> substitute(type, keepAnnotation, runCapturedChecks)
|
||||
@@ -170,10 +172,14 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
||||
|
||||
object EmptySubstitutor : NewTypeSubstitutor {
|
||||
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = null
|
||||
|
||||
override val isEmpty: Boolean get() = true
|
||||
}
|
||||
|
||||
class NewTypeSubstitutorByConstructorMap(val map: Map<TypeConstructor, UnwrappedType>) : NewTypeSubstitutor {
|
||||
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = map[constructor]
|
||||
|
||||
override val isEmpty: Boolean get() = map.isEmpty()
|
||||
}
|
||||
|
||||
class FreshVariableNewTypeSubstitutor(val freshVariables: List<TypeVariableFromCallableDescriptor>) : NewTypeSubstitutor {
|
||||
@@ -185,6 +191,8 @@ class FreshVariableNewTypeSubstitutor(val freshVariables: List<TypeVariableFromC
|
||||
return typeVariable.defaultType
|
||||
}
|
||||
|
||||
override val isEmpty: Boolean get() = freshVariables.isEmpty()
|
||||
|
||||
companion object {
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("builderInference.kt")
|
||||
public void testBuilderInference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedStarProjection.kt")
|
||||
public void testCapturedStarProjection() throws Exception {
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("builderInference.kt")
|
||||
public void testBuilderInference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedStarProjection.kt")
|
||||
public void testCapturedStarProjection() throws Exception {
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("builderInference.kt")
|
||||
public void testBuilderInference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedStarProjection.kt")
|
||||
public void testCapturedStarProjection() throws Exception {
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("builderInference.kt")
|
||||
public void testBuilderInference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedStarProjection.kt")
|
||||
public void testCapturedStarProjection() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
||||
|
||||
Reference in New Issue
Block a user