NI: do substitution type variables during updating trace for lambda (these type variables can appear after the builder inference)

^KT-42450 Fixed
This commit is contained in:
Victor Petukhov
2020-10-12 16:21:07 +03:00
parent e399b4cd12
commit 0685beb765
8 changed files with 56 additions and 9 deletions
@@ -1752,6 +1752,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
} }
@TestMetadata("substituteTypeVariableIntolambdaParameterDescriptor.kt")
public void testSubstituteTypeVariableIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteTypeVariableIntolambdaParameterDescriptor.kt");
}
} }
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods") @TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.types.typeUtil.shouldBeSubstituted
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ResolvedAtomCompleter( class ResolvedAtomCompleter(
@@ -212,15 +213,14 @@ class ResolvedAtomCompleter(
resultSubstitutor.safeSubstitute(lambda.returnType) resultSubstitutor.safeSubstitute(lambda.returnType)
} }
val approximatedValueParameterTypes = lambda.parameters.map { val approximatedValueParameterTypes = lambda.parameters.map { parameterType ->
// Do substitution and approximation only for stub types, which can appear from builder inference (as postponed variables) if (parameterType.shouldBeSubstituted()) {
if (it is StubType) {
typeApproximator.approximateDeclarationType( typeApproximator.approximateDeclarationType(
resultSubstitutor.safeSubstitute(it), resultSubstitutor.safeSubstitute(parameterType),
local = true, local = true,
languageVersionSettings = topLevelCallContext.languageVersionSettings languageVersionSettings = topLevelCallContext.languageVersionSettings
) )
} else it } else parameterType
} }
val approximatedReturnType = val approximatedReturnType =
@@ -277,8 +277,7 @@ class ResolvedAtomCompleter(
functionDescriptor.setReturnType(returnType) functionDescriptor.setReturnType(returnType)
for ((i, valueParameter) in functionDescriptor.valueParameters.withIndex()) { for ((i, valueParameter) in functionDescriptor.valueParameters.withIndex()) {
if (valueParameter !is ValueParameterDescriptorImpl || valueParameter.type !is StubType) if (valueParameter !is ValueParameterDescriptorImpl || !valueParameter.type.shouldBeSubstituted()) continue
continue
valueParameter.setOutType(valueParameters[i]) valueParameter.setOutType(valueParameters[i])
} }
@@ -0,0 +1,25 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
class Foo<A>
fun <K> bar(x: Foo<K>): Unit {}
fun <E> foo(block: (Foo<E>) -> Unit): E = null as E
interface FlowCollector<T> {
fun emit(value: T)
}
@Suppress("EXPERIMENTAL_API_USAGE_ERROR")
fun <I> flow(@BuilderInference block: FlowCollector<I>.() -> Unit): I = null as I
fun adapt(): Unit = flow {
emit(foo { coroutine -> bar(coroutine) })
}
fun box(): String {
adapt()
return "OK"
}
@@ -1772,6 +1772,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
} }
@TestMetadata("substituteTypeVariableIntolambdaParameterDescriptor.kt")
public void testSubstituteTypeVariableIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteTypeVariableIntolambdaParameterDescriptor.kt");
}
} }
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods") @TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -1772,6 +1772,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
} }
@TestMetadata("substituteTypeVariableIntolambdaParameterDescriptor.kt")
public void testSubstituteTypeVariableIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteTypeVariableIntolambdaParameterDescriptor.kt");
}
} }
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods") @TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -1752,6 +1752,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
} }
@TestMetadata("substituteTypeVariableIntolambdaParameterDescriptor.kt")
public void testSubstituteTypeVariableIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteTypeVariableIntolambdaParameterDescriptor.kt");
}
} }
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods") @TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.StubType; import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -50,7 +50,7 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorNonRoo
} }
public void setOutType(KotlinType outType) { public void setOutType(KotlinType outType) {
assert this.outType == null || this.outType instanceof StubType; assert this.outType == null || TypeUtilsKt.shouldBeSubstituted(this.outType);
this.outType = outType; this.outType = outType;
} }
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.isCaptured
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.* import org.jetbrains.kotlin.types.checker.*
import org.jetbrains.kotlin.types.model.TypeVariableTypeConstructorMarker
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.* import java.util.*
@@ -304,3 +305,5 @@ private fun NewCapturedType.unCaptureTopLevelType(): UnwrappedType {
return constructor.projection.type.unwrap() return constructor.projection.type.unwrap()
} }
fun KotlinType.shouldBeSubstituted() = contains { it is StubType || it.constructor is TypeVariableTypeConstructorMarker }