[FE 1.0] Don't capture projections during compatibility check of supertypes to determine intersection type emptiness

This commit is contained in:
Victor Petukhov
2022-04-27 20:16:29 +03:00
committed by teamcity
parent 73be9d0a20
commit 6c54b78574
7 changed files with 103 additions and 7 deletions
@@ -30,19 +30,20 @@ import org.jetbrains.kotlin.utils.sure
import java.util.*
class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor: TypeSubstitutor) : MemberScope {
val substitutor = givenSubstitutor.substitution.wrapWithCapturingSubstitution().buildSubstitutor()
val substitutor by lazy { givenSubstitutor.substitution.buildSubstitutor() }
private val capturingSubstitutor = givenSubstitutor.substitution.wrapWithCapturingSubstitution().buildSubstitutor()
private var substitutedDescriptors: MutableMap<DeclarationDescriptor, DeclarationDescriptor>? = null
private val _allDescriptors by lazy { substitute(workerScope.getContributedDescriptors()) }
fun substitute(type: KotlinType): KotlinType {
if (substitutor.isEmpty) return type
return substitutor.safeSubstitute(type) as KotlinType
if (capturingSubstitutor.isEmpty) return type
return capturingSubstitutor.safeSubstitute(type) as KotlinType
}
private fun <D : DeclarationDescriptor> substitute(descriptor: D): D {
if (substitutor.isEmpty) return descriptor
if (capturingSubstitutor.isEmpty) return descriptor
if (substitutedDescriptors == null) {
substitutedDescriptors = HashMap<DeclarationDescriptor, DeclarationDescriptor>()
@@ -50,7 +51,7 @@ class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor:
val substituted = substitutedDescriptors!!.getOrPut(descriptor) {
when (descriptor) {
is Substitutable<*> -> descriptor.substitute(substitutor).sure {
is Substitutable<*> -> descriptor.substitute(capturingSubstitutor).sure {
"We expect that no conflict should happen while substitution is guaranteed to generate invariant projection, " +
"but $descriptor substitution fails"
}
@@ -63,7 +64,7 @@ class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor:
}
private fun <D : DeclarationDescriptor> substitute(descriptors: Collection<D>): Collection<D> {
if (substitutor.isEmpty) return descriptors
if (capturingSubstitutor.isEmpty) return descriptors
if (descriptors.isEmpty()) return descriptors
val result = newLinkedHashSetWithExpectedSize<D>(descriptors.size)
@@ -97,7 +98,7 @@ class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor:
p.println("substitutor = ")
p.pushIndent()
p.println(substitutor)
p.println(capturingSubstitutor)
p.popIndent()
p.print("workerScope = ")