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 f5dd8b5e26e..11889a4d50c 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java @@ -9823,6 +9823,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/inference/invokeLambdaAsFunction.kt"); } + @TestMetadata("knownTypeParameters.kt") + public void testKnownTypeParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/knownTypeParameters.kt"); + } + @TestMetadata("kt11963.kt") public void testKt11963() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/kt11963.kt"); @@ -9858,6 +9863,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/inference/kt3184.kt"); } + @TestMetadata("kt32415.kt") + public void testKt32415() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/kt32415.kt"); + } + @TestMetadata("kt32434.kt") public void testKt32434() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/kt32434.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 d3a40a891f6..f0d8e717847 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 @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.calls.context.CallPosition import org.jetbrains.kotlin.resolve.calls.inference.buildResultingSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor +import org.jetbrains.kotlin.resolve.calls.inference.components.composeWith import org.jetbrains.kotlin.resolve.calls.inference.model.* import org.jetbrains.kotlin.resolve.calls.inference.substitute import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateTypes @@ -728,10 +729,13 @@ class NewResolvedCallImpl( } private fun CallableDescriptor.substituteInferredVariablesAndApproximate(substitutor: NewTypeSubstitutor?): CallableDescriptor { - return substitute(resolvedCallAtom.freshVariablesSubstitutor) - .substituteAndApproximateTypes( - substitutor ?: FreshVariableNewTypeSubstitutor.Empty, typeApproximator - ) + val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty + + val compositeSubstitutor = resolvedCallAtom.freshVariablesSubstitutor + .composeWith(resolvedCallAtom.knownParametersSubstitutor) + .composeWith(inferredTypeVariablesSubstitutor) + + return substituteAndApproximateTypes(compositeSubstitutor, typeApproximator) } fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? = diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index 9aa870e2b46..1686264a451 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorMo import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.typeUtil.contains import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -124,6 +125,8 @@ internal object NoArguments : ResolutionPart() { internal object CreateFreshVariablesSubstitutor : ResolutionPart() { override fun KotlinResolutionCandidate.process(workIndex: Int) { + resolvedCall.knownParametersSubstitutor = knownTypeParametersResultingSubstitutor ?: TypeSubstitutor.EMPTY + if (candidateDescriptor.typeParameters.isEmpty()) { resolvedCall.freshVariablesSubstitutor = FreshVariableNewTypeSubstitutor.Empty return @@ -415,6 +418,7 @@ internal object ErrorDescriptorResolutionPart : ResolutionPart() { resolvedCall.typeArgumentMappingByOriginal = TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments resolvedCall.argumentMappingByOriginal = emptyMap() resolvedCall.freshVariablesSubstitutor = FreshVariableNewTypeSubstitutor.Empty + resolvedCall.knownParametersSubstitutor = TypeSubstitutor.EMPTY resolvedCall.argumentToCandidateParameter = emptyMap() kotlinCall.explicitReceiver?.safeAs()?.let { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt index 2f53bd7538e..a58f2db1441 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt @@ -7,8 +7,8 @@ package org.jetbrains.kotlin.resolve.calls.inference.components import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations -import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor +import org.jetbrains.kotlin.resolve.calls.inference.substitute import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor @@ -190,7 +190,22 @@ class FreshVariableNewTypeSubstitutor(val freshVariables: List abstract val freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor - + abstract val knownParametersSubstitutor: TypeSubstitutor abstract val argumentsWithConversion: Map } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt index 3277453ff96..c558ae66c1d 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt @@ -179,6 +179,7 @@ class MutableResolvedCallAtom( override lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping override lateinit var argumentMappingByOriginal: Map override lateinit var freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor + override lateinit var knownParametersSubstitutor: TypeSubstitutor lateinit var argumentToCandidateParameter: Map private var samAdapterMap: HashMap? = null diff --git a/compiler/testData/diagnostics/tests/inference/knownTypeParameters.kt b/compiler/testData/diagnostics/tests/inference/knownTypeParameters.kt new file mode 100644 index 00000000000..d719187d3fa --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/knownTypeParameters.kt @@ -0,0 +1,30 @@ +// !LANGUAGE: +NewInference + +open class A { + open inner class A1(val a1: T1) + open inner class A2(val a2: T2) + + open fun f1(arg: T1) = arg + open fun f2(arg: T2) = arg +} + +open class B : A() { + open inner class B1(b1: T) : A1(b1) + open inner class B2(b2: Int) : A2(b2) + + fun variableToKnownParameter(p: T): Int = + p as? Int ?: 0 + + inner class B3(b3: T) : A2(variableToKnownParameter(b3)) + + override fun f1(arg: T) = arg + override fun f2(arg: Int) = arg +} + +class C : B() { + inner class C1(c1: String): B1(c1) + inner class C2 : B2(15) + + override fun f1(arg: String) = arg + override fun f2(arg: Int) = arg +} diff --git a/compiler/testData/diagnostics/tests/inference/knownTypeParameters.txt b/compiler/testData/diagnostics/tests/inference/knownTypeParameters.txt new file mode 100644 index 00000000000..bbd7d1b2d6c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/knownTypeParameters.txt @@ -0,0 +1,86 @@ +package + +public open class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun f1(/*0*/ arg: T1): T1 + public open fun f2(/*0*/ arg: T2): T2 + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public open inner class A1 /*captured type parameters: /*0*/ T1, /*1*/ T2*/ { + public constructor A1(/*0*/ a1: T1) + public final val a1: T1 + 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 + } + + public open inner class A2 /*captured type parameters: /*0*/ T1, /*1*/ T2*/ { + public constructor A2(/*0*/ a2: T2) + public final val a2: T2 + 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 + } +} + +public open class B : A { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ fun f1(/*0*/ arg: T): T + public open override /*1*/ fun f2(/*0*/ arg: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final fun variableToKnownParameter(/*0*/ p: T): kotlin.Int + + public open inner class B1 /*captured type parameters: /*0*/ T*/ : A.A1 { + public constructor B1(/*0*/ b1: T) + public final override /*1*/ /*fake_override*/ val a1: T + 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 + } + + public open inner class B2 /*captured type parameters: /*0*/ T*/ : A.A2 { + public constructor B2(/*0*/ b2: kotlin.Int) + public final override /*1*/ /*fake_override*/ val a2: kotlin.Int + 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 + } + + public final inner class B3 /*captured type parameters: /*0*/ T*/ : A.A2 { + public constructor B3(/*0*/ b3: T) + public final override /*1*/ /*fake_override*/ val a2: kotlin.Int + 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 + } +} + +public final class C : B { + public constructor C() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ fun f1(/*0*/ arg: kotlin.String): kotlin.String + public open override /*1*/ fun f2(/*0*/ arg: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final override /*1*/ /*fake_override*/ fun variableToKnownParameter(/*0*/ p: kotlin.String): kotlin.Int + + public final inner class C1 : B.B1 { + public constructor C1(/*0*/ c1: kotlin.String) + public final override /*1*/ /*fake_override*/ val a1: kotlin.String + 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 + } + + public final inner class C2 : B.B2 { + public constructor C2() + public final override /*1*/ /*fake_override*/ val a2: kotlin.Int + 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/testData/diagnostics/tests/inference/kt32415.kt b/compiler/testData/diagnostics/tests/inference/kt32415.kt new file mode 100644 index 00000000000..3b56457ee7d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/kt32415.kt @@ -0,0 +1,9 @@ +// !LANGUAGE: +NewInference + +abstract class TestType { + open inner class Inner(val item: V) +} + +class Derived: TestType() { + inner class DerivedInner(item: Long): Inner(item) +} diff --git a/compiler/testData/diagnostics/tests/inference/kt32415.txt b/compiler/testData/diagnostics/tests/inference/kt32415.txt new file mode 100644 index 00000000000..12b2efea43b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/kt32415.txt @@ -0,0 +1,31 @@ +package + +public final class Derived : TestType { + public constructor Derived() + 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 + + public final inner class DerivedInner : TestType.Inner { + public constructor DerivedInner(/*0*/ item: kotlin.Long) + public final override /*1*/ /*fake_override*/ val item: kotlin.Long + 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 + } +} + +public abstract class TestType { + public constructor TestType() + 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 + + public open inner class Inner /*captured type parameters: /*0*/ V : kotlin.Any*/ { + public constructor Inner(/*0*/ item: V) + public final val item: V + 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 85c0e3b05f9..c304a506817 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -9830,6 +9830,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/inference/invokeLambdaAsFunction.kt"); } + @TestMetadata("knownTypeParameters.kt") + public void testKnownTypeParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/knownTypeParameters.kt"); + } + @TestMetadata("kt11963.kt") public void testKt11963() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/kt11963.kt"); @@ -9865,6 +9870,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/inference/kt3184.kt"); } + @TestMetadata("kt32415.kt") + public void testKt32415() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/kt32415.kt"); + } + @TestMetadata("kt32434.kt") public void testKt32434() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/kt32434.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 27faa31d7ec..c75feb1210f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -9825,6 +9825,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/invokeLambdaAsFunction.kt"); } + @TestMetadata("knownTypeParameters.kt") + public void testKnownTypeParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/knownTypeParameters.kt"); + } + @TestMetadata("kt11963.kt") public void testKt11963() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/kt11963.kt"); @@ -9860,6 +9865,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/kt3184.kt"); } + @TestMetadata("kt32415.kt") + public void testKt32415() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/kt32415.kt"); + } + @TestMetadata("kt32434.kt") public void testKt32434() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/kt32434.kt");