[NI] Use new type substitutor for known type parameters
Use known type parameters substitutor after substitutor for fresh variables. The old logic of substituions had the following order: - replace known type parameters - replace type parameters with type variables - complete inference - replace type variables with inferred types According to the updated logic, replacement goes as follows: - replace type parameters with type variables - replace known type parameters; if they were variables, this will effectively remove them from inference - complete inference - replace remaining type variables with inferred types Support projection substitution in new type substitutor. It is needed for correct interaction with old type substitutor. Old type substitutors can contain mappings constructor -> projection which couldn't be expressed correctly with existing substitutor API in some cases. ^KT-41386 Fixed
This commit is contained in:
+5
@@ -11937,6 +11937,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt41386.kt")
|
||||||
|
public void testKt41386() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41386.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt4420.kt")
|
@TestMetadata("kt4420.kt")
|
||||||
public void testKt4420() throws Exception {
|
public void testKt4420() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
|
||||||
|
|||||||
+3
-4
@@ -30,7 +30,6 @@ 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.FreshVariableNewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.composeWith
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateTypes
|
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateTypes
|
||||||
@@ -809,10 +808,10 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
shouldApproximate: Boolean = true
|
shouldApproximate: Boolean = true
|
||||||
): CallableDescriptor {
|
): CallableDescriptor {
|
||||||
val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
||||||
val compositeSubstitutor = inferredTypeVariablesSubstitutor.composeWith(resolvedCallAtom.knownParametersSubstitutor)
|
|
||||||
|
|
||||||
return substitute(resolvedCallAtom.freshVariablesSubstitutor)
|
// TODO: merge last two substitutors to avoid redundant descriptor substitutions
|
||||||
.substituteAndApproximateTypes(compositeSubstitutor, if (shouldApproximate) typeApproximator else null)
|
return substitute(resolvedCallAtom.freshVariablesSubstitutor).substitute(resolvedCallAtom.knownParametersSubstitutor)
|
||||||
|
.substituteAndApproximateTypes(inferredTypeVariablesSubstitutor, if (shouldApproximate) typeApproximator else null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? {
|
fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? {
|
||||||
|
|||||||
+37
-8
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
|||||||
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
@@ -115,14 +115,22 @@ internal object NoArguments : ResolutionPart() {
|
|||||||
|
|
||||||
internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
||||||
override fun KotlinResolutionCandidate.process(workIndex: Int) {
|
override fun KotlinResolutionCandidate.process(workIndex: Int) {
|
||||||
resolvedCall.knownParametersSubstitutor = knownTypeParametersResultingSubstitutor ?: TypeSubstitutor.EMPTY
|
val toFreshVariables =
|
||||||
|
if (candidateDescriptor.typeParameters.isEmpty())
|
||||||
|
FreshVariableNewTypeSubstitutor.Empty
|
||||||
|
else
|
||||||
|
createToFreshVariableSubstitutorAndAddInitialConstraints(candidateDescriptor, csBuilder)
|
||||||
|
|
||||||
|
val knownTypeParametersSubstitutor = knownTypeParametersResultingSubstitutor?.let {
|
||||||
|
createKnownParametersFromFreshVariablesSubstitutor(toFreshVariables, knownTypeParametersResultingSubstitutor)
|
||||||
|
} ?: EmptySubstitutor
|
||||||
|
|
||||||
|
resolvedCall.freshVariablesSubstitutor = toFreshVariables
|
||||||
|
resolvedCall.knownParametersSubstitutor = knownTypeParametersSubstitutor
|
||||||
|
|
||||||
if (candidateDescriptor.typeParameters.isEmpty()) {
|
if (candidateDescriptor.typeParameters.isEmpty()) {
|
||||||
resolvedCall.freshVariablesSubstitutor = FreshVariableNewTypeSubstitutor.Empty
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val toFreshVariables = createToFreshVariableSubstitutorAndAddInitialConstraints(candidateDescriptor, csBuilder)
|
|
||||||
resolvedCall.freshVariablesSubstitutor = toFreshVariables
|
|
||||||
|
|
||||||
// bad function -- error on declaration side
|
// bad function -- error on declaration side
|
||||||
if (csBuilder.hasContradiction) return
|
if (csBuilder.hasContradiction) return
|
||||||
@@ -176,6 +184,27 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
|||||||
KotlinTypeFactory.flexibleType(type.makeNotNullable().lowerIfFlexible(), type.makeNullable().upperIfFlexible())
|
KotlinTypeFactory.flexibleType(type.makeNotNullable().lowerIfFlexible(), type.makeNullable().upperIfFlexible())
|
||||||
} else type
|
} else type
|
||||||
|
|
||||||
|
private fun createKnownParametersFromFreshVariablesSubstitutor(
|
||||||
|
freshVariableSubstitutor: FreshVariableNewTypeSubstitutor,
|
||||||
|
knownTypeParametersSubstitutor: TypeSubstitutor,
|
||||||
|
): NewTypeSubstitutor {
|
||||||
|
if (knownTypeParametersSubstitutor.isEmpty)
|
||||||
|
return EmptySubstitutor
|
||||||
|
|
||||||
|
val knownTypeParameterByTypeVariable = mutableMapOf<TypeConstructor, UnwrappedType>().let { map ->
|
||||||
|
for (typeVariable in freshVariableSubstitutor.freshVariables) {
|
||||||
|
val typeParameterType = typeVariable.originalTypeParameter.defaultType
|
||||||
|
val substitutedKnownTypeParameter = knownTypeParametersSubstitutor.substitute(typeParameterType)
|
||||||
|
|
||||||
|
if (substitutedKnownTypeParameter !== typeParameterType)
|
||||||
|
map[typeVariable.defaultType.constructor] = substitutedKnownTypeParameter
|
||||||
|
}
|
||||||
|
map
|
||||||
|
}
|
||||||
|
|
||||||
|
return knownTypeParametersSubstitutor.composeWith(NewTypeSubstitutorByConstructorMap(knownTypeParameterByTypeVariable))
|
||||||
|
}
|
||||||
|
|
||||||
fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
||||||
candidateDescriptor: CallableDescriptor,
|
candidateDescriptor: CallableDescriptor,
|
||||||
csBuilder: ConstraintSystemOperation
|
csBuilder: ConstraintSystemOperation
|
||||||
@@ -595,8 +624,8 @@ private fun KotlinResolutionCandidate.checkUnsafeImplicitInvokeAfterSafeCall(arg
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinResolutionCandidate.prepareExpectedType(expectedType: UnwrappedType): UnwrappedType {
|
private fun KotlinResolutionCandidate.prepareExpectedType(expectedType: UnwrappedType): UnwrappedType {
|
||||||
val resultType = knownTypeParametersResultingSubstitutor?.substitute(expectedType) ?: expectedType
|
val resultType = resolvedCall.freshVariablesSubstitutor.safeSubstitute(expectedType)
|
||||||
return resolvedCall.freshVariablesSubstitutor.safeSubstitute(resultType)
|
return resolvedCall.knownParametersSubstitutor.safeSubstitute(resultType)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object CheckReceivers : ResolutionPart() {
|
internal object CheckReceivers : ResolutionPart() {
|
||||||
@@ -714,7 +743,7 @@ internal object ErrorDescriptorResolutionPart : ResolutionPart() {
|
|||||||
resolvedCall.typeArgumentMappingByOriginal = TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
resolvedCall.typeArgumentMappingByOriginal = TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
||||||
resolvedCall.argumentMappingByOriginal = emptyMap()
|
resolvedCall.argumentMappingByOriginal = emptyMap()
|
||||||
resolvedCall.freshVariablesSubstitutor = FreshVariableNewTypeSubstitutor.Empty
|
resolvedCall.freshVariablesSubstitutor = FreshVariableNewTypeSubstitutor.Empty
|
||||||
resolvedCall.knownParametersSubstitutor = TypeSubstitutor.EMPTY
|
resolvedCall.knownParametersSubstitutor = EmptySubstitutor
|
||||||
resolvedCall.argumentToCandidateParameter = emptyMap()
|
resolvedCall.argumentToCandidateParameter = emptyMap()
|
||||||
|
|
||||||
kotlinCall.explicitReceiver?.safeAs<SimpleKotlinCallArgument>()?.let {
|
kotlinCall.explicitReceiver?.safeAs<SimpleKotlinCallArgument>()?.let {
|
||||||
|
|||||||
+43
-12
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
|
|||||||
import org.jetbrains.kotlin.types.checker.intersectTypes
|
import org.jetbrains.kotlin.types.checker.intersectTypes
|
||||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||||
|
|
||||||
interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
interface NewTypeSubstitutor : TypeSubstitutorMarker {
|
||||||
fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType?
|
fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType?
|
||||||
|
|
||||||
fun safeSubstitute(type: UnwrappedType): UnwrappedType =
|
fun safeSubstitute(type: UnwrappedType): UnwrappedType =
|
||||||
@@ -23,6 +23,15 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
|||||||
|
|
||||||
val isEmpty: Boolean
|
val isEmpty: Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns not null when substitutor manages specific type projection substitution by itself.
|
||||||
|
* Intended for corner cases involving interactions with legacy type substitutor,
|
||||||
|
* please consider using substituteNotNullTypeWithConstructor instead of making manual projection substitutions.
|
||||||
|
*/
|
||||||
|
fun substituteArgumentProjection(argument: TypeProjection): TypeProjection? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
private fun substitute(type: UnwrappedType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? =
|
private fun substitute(type: UnwrappedType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? =
|
||||||
when (type) {
|
when (type) {
|
||||||
is SimpleType -> substitute(type, keepAnnotation, runCapturedChecks)
|
is SimpleType -> substitute(type, keepAnnotation, runCapturedChecks)
|
||||||
@@ -165,6 +174,13 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
|||||||
val argument = arguments[index]
|
val argument = arguments[index]
|
||||||
|
|
||||||
if (argument.isStarProjection) continue
|
if (argument.isStarProjection) continue
|
||||||
|
|
||||||
|
val specialProjectionSubstitution = substituteArgumentProjection(argument)
|
||||||
|
if (specialProjectionSubstitution != null) {
|
||||||
|
newArguments[index] = specialProjectionSubstitution
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
val substitutedArgumentType = substitute(argument.type.unwrap(), keepAnnotation, runCapturedChecks) ?: continue
|
val substitutedArgumentType = substitute(argument.type.unwrap(), keepAnnotation, runCapturedChecks) ?: continue
|
||||||
|
|
||||||
newArguments[index] = TypeProjectionImpl(argument.projectionKind, substitutedArgumentType)
|
newArguments[index] = TypeProjectionImpl(argument.projectionKind, substitutedArgumentType)
|
||||||
@@ -205,24 +221,39 @@ class FreshVariableNewTypeSubstitutor(val freshVariables: List<TypeVariableFromC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createCompositeSubstitutor(appliedFirst: NewTypeSubstitutor, appliedLast: TypeSubstitutor): NewTypeSubstitutor {
|
fun createCompositeSubstitutor(appliedFirst: TypeSubstitutor, appliedLast: NewTypeSubstitutor): NewTypeSubstitutor {
|
||||||
if (appliedLast.isEmpty) return appliedFirst
|
if (appliedFirst.isEmpty) return appliedLast
|
||||||
|
|
||||||
return object : NewTypeSubstitutor {
|
return object : NewTypeSubstitutor {
|
||||||
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? {
|
override fun substituteArgumentProjection(argument: TypeProjection): TypeProjection? {
|
||||||
val substitutedOnce = appliedFirst.substituteNotNullTypeWithConstructor(constructor)
|
val substitutedProjection = appliedFirst.substitute(argument)
|
||||||
|
|
||||||
return if (substitutedOnce != null) {
|
if (substitutedProjection == null || substitutedProjection === argument) {
|
||||||
appliedLast.substitute(substitutedOnce.unwrap())
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (substitutedProjection.isStarProjection)
|
||||||
|
return substitutedProjection
|
||||||
|
|
||||||
|
val resultingType = appliedLast.safeSubstitute(substitutedProjection.type.unwrap())
|
||||||
|
return TypeProjectionImpl(substitutedProjection.projectionKind, resultingType)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? {
|
||||||
|
val substitutedOnce = constructor.declarationDescriptor?.defaultType?.let {
|
||||||
|
appliedFirst.substitute(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (substitutedOnce == null) {
|
||||||
|
appliedLast.substituteNotNullTypeWithConstructor(constructor)
|
||||||
} else {
|
} else {
|
||||||
constructor.declarationDescriptor?.defaultType?.let {
|
appliedLast.safeSubstitute(substitutedOnce)
|
||||||
appliedLast.substitute(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isEmpty: Boolean get() = appliedFirst.isEmpty && appliedLast.isEmpty
|
override val isEmpty: Boolean
|
||||||
|
get() = appliedFirst.isEmpty && appliedLast.isEmpty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NewTypeSubstitutor.composeWith(appliedAfter: TypeSubstitutor) = createCompositeSubstitutor(this, appliedAfter)
|
fun TypeSubstitutor.composeWith(appliedAfter: NewTypeSubstitutor) = createCompositeSubstitutor(this, appliedAfter)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ abstract class ResolvedCallAtom : ResolvedAtom() {
|
|||||||
abstract val typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
|
abstract val typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
|
||||||
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||||
abstract val freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
|
abstract val freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
|
||||||
abstract val knownParametersSubstitutor: TypeSubstitutor
|
abstract val knownParametersSubstitutor: NewTypeSubstitutor
|
||||||
abstract val argumentsWithConversion: Map<KotlinCallArgument, SamConversionDescription>
|
abstract val argumentsWithConversion: Map<KotlinCallArgument, SamConversionDescription>
|
||||||
abstract val argumentsWithSuspendConversion: Map<KotlinCallArgument, UnwrappedType>
|
abstract val argumentsWithSuspendConversion: Map<KotlinCallArgument, UnwrappedType>
|
||||||
abstract val argumentsWithUnitConversion: Map<KotlinCallArgument, UnwrappedType>
|
abstract val argumentsWithUnitConversion: Map<KotlinCallArgument, UnwrappedType>
|
||||||
|
|||||||
+2
-1
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
|||||||
import org.jetbrains.kotlin.resolve.calls.components.*
|
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
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.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.LowerPriorityToPreserveCompatibility
|
import org.jetbrains.kotlin.resolve.calls.inference.model.LowerPriorityToPreserveCompatibility
|
||||||
@@ -194,7 +195,7 @@ class MutableResolvedCallAtom(
|
|||||||
override lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
|
override lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
|
||||||
override lateinit var argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
override lateinit var argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||||
override lateinit var freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
|
override lateinit var freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
|
||||||
override lateinit var knownParametersSubstitutor: TypeSubstitutor
|
override lateinit var knownParametersSubstitutor: NewTypeSubstitutor
|
||||||
lateinit var argumentToCandidateParameter: Map<KotlinCallArgument, ValueParameterDescriptor>
|
lateinit var argumentToCandidateParameter: Map<KotlinCallArgument, ValueParameterDescriptor>
|
||||||
private var samAdapterMap: HashMap<KotlinCallArgument, SamConversionDescription>? = null
|
private var samAdapterMap: HashMap<KotlinCallArgument, SamConversionDescription>? = null
|
||||||
private var suspendAdapterMap: HashMap<KotlinCallArgument, UnwrappedType>? = null
|
private var suspendAdapterMap: HashMap<KotlinCallArgument, UnwrappedType>? = null
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
|
||||||
// KT-5508 Stackoverflow in type substitution
|
// KT-5508 Stackoverflow in type substitution
|
||||||
|
|
||||||
abstract class A<T> {
|
abstract class A<T> {
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
|
||||||
// KT-5508 Stackoverflow in type substitution
|
// KT-5508 Stackoverflow in type substitution
|
||||||
|
|
||||||
abstract class A<T> {
|
abstract class A<T> {
|
||||||
@@ -6,7 +5,7 @@ abstract class A<T> {
|
|||||||
public abstract fun bar(x: T)
|
public abstract fun bar(x: T)
|
||||||
|
|
||||||
public inner abstract class B<S> : A<B<S>>() {
|
public inner abstract class B<S> : A<B<S>>() {
|
||||||
public inner <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class C<!><U> : <!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>B<!><C<U>>()
|
public inner <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class C<!><U> : B<C<U>>()
|
||||||
{
|
{
|
||||||
// Here B<C<U>> means A<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>>.B<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>.C<U>>
|
// Here B<C<U>> means A<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>>.B<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>.C<U>>
|
||||||
// while for being a correct override it should be A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>
|
// while for being a correct override it should be A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// !LANGUAGE: +NewInference
|
||||||
|
|
||||||
|
open class Test<T1, T2>(val map1 : Map<T1, T2>, val map2 : Map<T2, T1>) {
|
||||||
|
open val inverse: Test<T2, T1> = object : <!INAPPLICABLE_CANDIDATE!>Test<T2, T1><!>(map2, map1) {
|
||||||
|
override val inverse: Test<T1, T2>
|
||||||
|
get() = this@Test
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// !LANGUAGE: +NewInference
|
||||||
|
|
||||||
|
open class Test<T1, T2>(val map1 : Map<T1, T2>, val map2 : Map<T2, T1>) {
|
||||||
|
open val inverse: Test<T2, T1> = object : Test<T2, T1>(map2, map1) {
|
||||||
|
override val inverse: Test<T1, T2>
|
||||||
|
get() = this@Test
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public open class Test</*0*/ T1, /*1*/ T2> {
|
||||||
|
public constructor Test</*0*/ T1, /*1*/ T2>(/*0*/ map1: kotlin.collections.Map<T1, T2>, /*1*/ map2: kotlin.collections.Map<T2, T1>)
|
||||||
|
public open val inverse: Test<T2, T1>
|
||||||
|
public final val map1: kotlin.collections.Map<T1, T2>
|
||||||
|
public final val map2: kotlin.collections.Map<T2, 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
|
||||||
|
}
|
||||||
@@ -11944,6 +11944,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt41386.kt")
|
||||||
|
public void testKt41386() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41386.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt4420.kt")
|
@TestMetadata("kt4420.kt")
|
||||||
public void testKt4420() throws Exception {
|
public void testKt4420() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
|
||||||
|
|||||||
Generated
+5
@@ -11939,6 +11939,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt41386.kt")
|
||||||
|
public void testKt41386() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41386.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt4420.kt")
|
@TestMetadata("kt4420.kt")
|
||||||
public void testKt4420() throws Exception {
|
public void testKt4420() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user