NI: do substitution stub types during updating trace for lambda (these stub types can appear from the builder inference as postponed variables)

^KT-40060 Fixed
This commit is contained in:
Victor Petukhov
2020-07-06 16:23:52 +03:00
parent eec3a4720c
commit c588bc604d
10 changed files with 87 additions and 18 deletions
@@ -1707,6 +1707,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
public void testLackOfNullCheckOnNullableInsideBuild() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
}
@TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt")
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.builtins.createFunctionType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
@@ -209,13 +210,24 @@ class ResolvedAtomCompleter(
resultSubstitutor.safeSubstitute(lambda.returnType)
}
val approximatedValueParameterTypes = lambda.parameters.map {
// Do substitution and approximation only for stub types, which can appear from builder inference (as postponed variables)
if (it is StubType) {
typeApproximator.approximateDeclarationType(
resultSubstitutor.safeSubstitute(it),
local = true,
languageVersionSettings = topLevelCallContext.languageVersionSettings
)
} else it
}
val approximatedReturnType =
typeApproximator.approximateDeclarationType(
returnType,
local = true,
languageVersionSettings = topLevelCallContext.languageVersionSettings
)
updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType)
updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType, approximatedValueParameterTypes)
for (lambdaResult in resultArgumentsInfo.nonErrorArguments) {
val resultValueArgument = lambdaResult as? PSIKotlinCallArgument ?: continue
@@ -235,7 +247,12 @@ class ResolvedAtomCompleter(
}
}
private fun updateTraceForLambda(lambda: ResolvedLambdaAtom, trace: BindingTrace, returnType: UnwrappedType) {
private fun updateTraceForLambda(
lambda: ResolvedLambdaAtom,
trace: BindingTrace,
returnType: UnwrappedType,
valueParameters: List<UnwrappedType>
) {
val psiCallArgument = lambda.atom.psiCallArgument
val ktArgumentExpression: KtExpression
@@ -254,8 +271,15 @@ class ResolvedAtomCompleter(
val functionDescriptor = trace.bindingContext.get(BindingContext.FUNCTION, ktFunction) as? FunctionDescriptorImpl
?: throw AssertionError("No function descriptor for resolved lambda argument")
functionDescriptor.setReturnType(returnType)
for ((i, valueParameter) in functionDescriptor.valueParameters.withIndex()) {
if (valueParameter !is ValueParameterDescriptorImpl || valueParameter.type !is StubType)
continue
valueParameter.setOutType(valueParameters[i])
}
val existingLambdaType = trace.getType(ktArgumentExpression)
if (existingLambdaType == null) {
if (ktFunction is KtNamedFunction && ktFunction.nameIdentifier != null) return // it's a statement
@@ -0,0 +1,24 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
import kotlin.experimental.ExperimentalTypeInference
class TypeDefinition<K : Any> {
fun parse(parser: (serializedValue: String) -> K?): Unit {}
fun serialize(parser: (value: K) -> Any?): Unit {}
}
@OptIn(ExperimentalTypeInference::class)
fun <T : Any> defineType(@BuilderInference definition: TypeDefinition<T>.() -> Unit): Unit {}
fun test() {
defineType {
parse { it as Int }
serialize { it.toString() }
}
}
fun box(): String {
test()
return "OK"
}
@@ -1727,6 +1727,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testLackOfNullCheckOnNullableInsideBuild() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
}
@TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt")
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -1727,6 +1727,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
public void testLackOfNullCheckOnNullableInsideBuild() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
}
@TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt")
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -1707,6 +1707,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
public void testLackOfNullCheckOnNullableInsideBuild() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
}
@TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt")
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.StubType;
import java.util.Collection;
import java.util.Collections;
@@ -49,7 +50,7 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorNonRoo
}
public void setOutType(KotlinType outType) {
assert this.outType == null;
assert this.outType == null || this.outType instanceof StubType;
this.outType = outType;
}
@@ -41,11 +41,6 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@TestMetadata("constValInAnnotation.kt")
public void testConstValInAnnotation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/constValInAnnotation.kt");
}
@TestMetadata("nestedAnnotation.kt")
public void testNestedAnnotation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/nestedAnnotation.kt");
@@ -1327,6 +1322,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
public void testLackOfNullCheckOnNullableInsideBuild() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
}
@TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt")
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -41,11 +41,6 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@TestMetadata("constValInAnnotation.kt")
public void testConstValInAnnotation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/constValInAnnotation.kt");
}
@TestMetadata("nestedAnnotation.kt")
public void testNestedAnnotation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/nestedAnnotation.kt");
@@ -1337,6 +1332,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
public void testLackOfNullCheckOnNullableInsideBuild() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
}
@TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt")
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
@@ -41,11 +41,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@TestMetadata("constValInAnnotation.kt")
public void testConstValInAnnotation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/constValInAnnotation.kt");
}
@TestMetadata("nestedAnnotation.kt")
public void testNestedAnnotation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/nestedAnnotation.kt");
@@ -1337,6 +1332,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
public void testLackOfNullCheckOnNullableInsideBuild() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
}
@TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt")
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods")