[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
This commit is contained in:
Pavel Kirpichenkov
2019-11-12 12:02:50 +03:00
parent b6af13f18d
commit 92dae5d8a9
6 changed files with 33 additions and 5 deletions
@@ -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");
@@ -730,12 +730,10 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
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? =
@@ -0,0 +1,5 @@
// !LANGUAGE: +NewInference
class B<O>(val obj: O) {
val v = B(obj)
}
@@ -0,0 +1,10 @@
package
public final class B</*0*/ O> {
public constructor B</*0*/ O>(/*0*/ obj: O)
public final val obj: O
public final val v: B<O>
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
}
@@ -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");
@@ -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");