FIR: Implement captured type substitution
This commit is contained in:
committed by
teamcity
parent
476a7727da
commit
61ea65906c
+19
-1
@@ -61,7 +61,7 @@ abstract class AbstractConeSubstitutor(private val typeContext: ConeTypeContext)
|
|||||||
if (it.lowerBound == it.upperBound) it.lowerBound
|
if (it.lowerBound == it.upperBound) it.lowerBound
|
||||||
else it
|
else it
|
||||||
}
|
}
|
||||||
is ConeCapturedType -> return null
|
is ConeCapturedType -> return substituteCapturedType()
|
||||||
is ConeDefinitelyNotNullType -> this.substituteOriginal()
|
is ConeDefinitelyNotNullType -> this.substituteOriginal()
|
||||||
is ConeIntersectionType -> this.substituteIntersectedTypes()
|
is ConeIntersectionType -> this.substituteIntersectedTypes()
|
||||||
is ConeStubType -> return null
|
is ConeStubType -> return null
|
||||||
@@ -69,6 +69,24 @@ abstract class AbstractConeSubstitutor(private val typeContext: ConeTypeContext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ConeCapturedType.substituteCapturedType(): ConeCapturedType? {
|
||||||
|
val innerType = this.lowerType ?: this.constructor.projection.type
|
||||||
|
val substitutedInnerType = substituteOrNull(innerType) ?: return null
|
||||||
|
if (substitutedInnerType is ConeCapturedType) return substitutedInnerType
|
||||||
|
val substitutedSuperTypes =
|
||||||
|
this.constructor.supertypes?.map { substituteOrSelf(it) }
|
||||||
|
|
||||||
|
return ConeCapturedType(
|
||||||
|
captureStatus,
|
||||||
|
constructor = ConeCapturedTypeConstructor(
|
||||||
|
wrapProjection(constructor.projection, substitutedInnerType),
|
||||||
|
substitutedSuperTypes,
|
||||||
|
typeParameterMarker = constructor.typeParameterMarker
|
||||||
|
),
|
||||||
|
lowerType = if (lowerType != null) substitutedInnerType else null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun ConeIntersectionType.substituteIntersectedTypes(): ConeIntersectionType? {
|
private fun ConeIntersectionType.substituteIntersectedTypes(): ConeIntersectionType? {
|
||||||
val substitutedTypes = ArrayList<ConeKotlinType>(intersectedTypes.size)
|
val substitutedTypes = ArrayList<ConeKotlinType>(intersectedTypes.size)
|
||||||
var somethingIsSubstituted = false
|
var somethingIsSubstituted = false
|
||||||
|
|||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER
|
|
||||||
|
|
||||||
class Foo<K>
|
|
||||||
|
|
||||||
fun <T> getFoo(value: T) = null as Foo<out Foo<T>>
|
|
||||||
fun <R> takeLambda(block: () -> R) {}
|
|
||||||
|
|
||||||
fun main(x: Int) {
|
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>takeLambda<!> {
|
|
||||||
getFoo(x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER
|
||||||
|
|
||||||
class Foo<K>
|
class Foo<K>
|
||||||
|
|||||||
+1
-1
@@ -82,7 +82,7 @@ fun testCapturedVariable() {
|
|||||||
|
|
||||||
c2
|
c2
|
||||||
|
|
||||||
val c3 = select(SubInv<Number>(), createInvIn())
|
val c3 = <!NEW_INFERENCE_ERROR!>select(SubInv<Number>(), createInvIn())<!>
|
||||||
|
|
||||||
c3
|
c3
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ fun test7(cls: Cls) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test8(cls: Cls) {
|
fun test8(cls: Cls) {
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id<!>(
|
id(
|
||||||
wrapIn(cls)
|
wrapIn(cls)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -12,4 +12,4 @@ fun <T> listOf(): List<T> = null!!
|
|||||||
// since it has 'out' type projection in 'in' position.
|
// since it has 'out' type projection in 'in' position.
|
||||||
val test1 = BOutIn(<!ARGUMENT_TYPE_MISMATCH!>listOf()<!>, null!!)
|
val test1 = BOutIn(<!ARGUMENT_TYPE_MISMATCH!>listOf()<!>, null!!)
|
||||||
|
|
||||||
val test2 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>BInIn<!>(listOf(), null!!)
|
val test2 = BInIn(listOf(), null!!)
|
||||||
|
|||||||
Reference in New Issue
Block a user