From 92dae5d8a9e5d0fb8c703681467489c7e930631a Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Tue, 12 Nov 2019 12:02:50 +0300 Subject: [PATCH] [NI] Split substitution of inferred type parametes into two steps Substituting inferred type parameters with single substitutor leads to incorrect behaviour in cases, when class' type parameters are used in constructor. As a side effect of two-step substitution, intermediate descriptor is created, which prevents incorrect substitution. To preserve this side effect, single resulting substitutor was split into two substitutors: one for substituting fresh variables and another for substituting inferred variables and known parameters. ^KT-32415 Fixed --- .../kotlin/fir/FirDiagnosticsSmokeTestGenerated.java | 5 +++++ .../calls/tower/KotlinToResolvedCallTransformer.kt | 8 +++----- .../tests/inference/typeParameterInConstructor.kt | 5 +++++ .../tests/inference/typeParameterInConstructor.txt | 10 ++++++++++ .../kotlin/checkers/DiagnosticsTestGenerated.java | 5 +++++ .../javac/DiagnosticsUsingJavacTestGenerated.java | 5 +++++ 6 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.kt create mode 100644 compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.txt diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java index 11889a4d50c..e7761ca35d1 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java @@ -9963,6 +9963,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt"); } + @TestMetadata("typeParameterInConstructor.kt") + public void testTypeParameterInConstructor() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.kt"); + } + @TestMetadata("useFunctionLiteralsToInferType.kt") public void testUseFunctionLiteralsToInferType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/useFunctionLiteralsToInferType.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index f0d8e717847..f483415e3f5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -730,12 +730,10 @@ class NewResolvedCallImpl( private fun CallableDescriptor.substituteInferredVariablesAndApproximate(substitutor: NewTypeSubstitutor?): CallableDescriptor { val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty + val compositeSubstitutor = inferredTypeVariablesSubstitutor.composeWith(resolvedCallAtom.knownParametersSubstitutor) - val compositeSubstitutor = resolvedCallAtom.freshVariablesSubstitutor - .composeWith(resolvedCallAtom.knownParametersSubstitutor) - .composeWith(inferredTypeVariablesSubstitutor) - - return substituteAndApproximateTypes(compositeSubstitutor, typeApproximator) + return substitute(resolvedCallAtom.freshVariablesSubstitutor) + .substituteAndApproximateTypes(compositeSubstitutor, typeApproximator) } fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? = diff --git a/compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.kt b/compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.kt new file mode 100644 index 00000000000..d6aa122b339 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.kt @@ -0,0 +1,5 @@ +// !LANGUAGE: +NewInference + +class B(val obj: O) { + val v = B(obj) +} diff --git a/compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.txt b/compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.txt new file mode 100644 index 00000000000..b93bf369e0c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.txt @@ -0,0 +1,10 @@ +package + +public final class B { + public constructor B(/*0*/ obj: O) + public final val obj: O + public final val v: B + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index c304a506817..3c47e9d08d1 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -9970,6 +9970,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt"); } + @TestMetadata("typeParameterInConstructor.kt") + public void testTypeParameterInConstructor() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.kt"); + } + @TestMetadata("useFunctionLiteralsToInferType.kt") public void testUseFunctionLiteralsToInferType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/useFunctionLiteralsToInferType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index c75feb1210f..45f052c0fa4 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -9965,6 +9965,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt"); } + @TestMetadata("typeParameterInConstructor.kt") + public void testTypeParameterInConstructor() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/typeParameterInConstructor.kt"); + } + @TestMetadata("useFunctionLiteralsToInferType.kt") public void testUseFunctionLiteralsToInferType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/useFunctionLiteralsToInferType.kt");