FIR substitution: use intersection of bounds for * projection
This commit is contained in:
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.inferenceContext
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
@@ -113,8 +114,19 @@ fun ConeClassLikeType.wrapSubstitutionScopeIfNeed(
|
|||||||
val typeParameters = (declaration as? FirTypeParametersOwner)?.typeParameters.orEmpty()
|
val typeParameters = (declaration as? FirTypeParametersOwner)?.typeParameters.orEmpty()
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val substitution = typeParameters.zip(this.typeArguments) { typeParameter, typeArgument ->
|
val substitution = typeParameters.zip(this.typeArguments) { typeParameter, typeArgument ->
|
||||||
typeParameter.symbol to (typeArgument as? ConeTypedProjection)?.type
|
val typeParameterSymbol = typeParameter.symbol
|
||||||
}.filter { (_, type) -> type != null }.toMap() as Map<FirTypeParameterSymbol, ConeKotlinType>
|
typeParameterSymbol to when (typeArgument) {
|
||||||
|
is ConeTypedProjection -> {
|
||||||
|
typeArgument.type
|
||||||
|
}
|
||||||
|
else /* StarProjection */ -> {
|
||||||
|
ConeTypeIntersector.intersectTypes(
|
||||||
|
session.inferenceContext(),
|
||||||
|
typeParameterSymbol.fir.bounds.map { it.coneTypeUnsafe() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
FirClassSubstitutionScope(session, useSiteMemberScope, builder, substitution)
|
FirClassSubstitutionScope(session, useSiteMemberScope, builder, substitution)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -93,7 +93,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeDefinitelyNotNullType? {
|
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeDefinitelyNotNullType? {
|
||||||
return ConeDefinitelyNotNullType.create(substituteType(original) ?: original)
|
return ConeDefinitelyNotNullType.create(substituteType(original)?.withNullability(ConeNullability.NOT_NULL) ?: original)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeFlexibleType.substituteBounds(): ConeFlexibleType? {
|
private fun ConeFlexibleType.substituteBounds(): ConeFlexibleType? {
|
||||||
@@ -145,7 +145,6 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun substitutorByMap(substitution: Map<FirTypeParameterSymbol, ConeKotlinType>): ConeSubstitutor {
|
fun substitutorByMap(substitution: Map<FirTypeParameterSymbol, ConeKotlinType>): ConeSubstitutor {
|
||||||
if (substitution.isEmpty()) return ConeSubstitutor.Empty
|
if (substitution.isEmpty()) return ConeSubstitutor.Empty
|
||||||
return ConeSubstitutorByMap(substitution)
|
return ConeSubstitutorByMap(substitution)
|
||||||
|
|||||||
+17
-3
@@ -37,8 +37,12 @@ internal inline var FirExpression.resultType: FirTypeRef
|
|||||||
replaceTypeRef(type)
|
replaceTypeRef(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun inferenceComponents(session: FirSession, returnTypeCalculator: ReturnTypeCalculator, scopeSession: ScopeSession) =
|
internal interface UniversalConeInferenceContext :
|
||||||
InferenceComponents(object : ConeInferenceContext, TypeSystemInferenceExtensionContextDelegate, DataFlowInferenceContext {
|
ConeInferenceContext, TypeSystemInferenceExtensionContextDelegate, DataFlowInferenceContext
|
||||||
|
|
||||||
|
internal fun FirSession.inferenceContext(): UniversalConeInferenceContext {
|
||||||
|
val session = this
|
||||||
|
return object : UniversalConeInferenceContext {
|
||||||
override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List<SimpleTypeMarker>): SimpleTypeMarker? {
|
override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List<SimpleTypeMarker>): SimpleTypeMarker? {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
return null
|
return null
|
||||||
@@ -59,4 +63,14 @@ internal fun inferenceComponents(session: FirSession, returnTypeCalculator: Retu
|
|||||||
require(this is ErrorTypeConstructor)
|
require(this is ErrorTypeConstructor)
|
||||||
return ConeClassErrorType(reason)
|
return ConeClassErrorType(reason)
|
||||||
}
|
}
|
||||||
}, session, returnTypeCalculator, scopeSession)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun inferenceComponents(
|
||||||
|
session: FirSession,
|
||||||
|
returnTypeCalculator: ReturnTypeCalculator,
|
||||||
|
scopeSession: ScopeSession
|
||||||
|
): InferenceComponents {
|
||||||
|
val inferenceContext = session.inferenceContext()
|
||||||
|
return InferenceComponents(inferenceContext, session, returnTypeCalculator, scopeSession)
|
||||||
|
}
|
||||||
+4
-4
@@ -325,8 +325,8 @@ digraph complex_kt {
|
|||||||
110 [label="Access variable this@R|/firstIsInstanceOrNull|"];
|
110 [label="Access variable this@R|/firstIsInstanceOrNull|"];
|
||||||
111 [label="Variable declaration: lval <range>: R|kotlin/sequences/Sequence<*>|"];
|
111 [label="Variable declaration: lval <range>: R|kotlin/sequences/Sequence<*>|"];
|
||||||
112 [label="Access variable R|<local>/<range>|"];
|
112 [label="Access variable R|<local>/<range>|"];
|
||||||
113 [label="Function call: R|<local>/<range>|.R|kotlin/sequences/Sequence.iterator|()"];
|
113 [label="Function call: R|<local>/<range>|.R|FakeOverride<kotlin/sequences/Sequence.iterator: R|kotlin/collections/Iterator<kotlin/Any?>|>|()"];
|
||||||
114 [label="Variable declaration: lval <iterator>: R|kotlin/collections/Iterator<T>|"];
|
114 [label="Variable declaration: lval <iterator>: R|kotlin/collections/Iterator<kotlin/Any?>|"];
|
||||||
subgraph cluster_25 {
|
subgraph cluster_25 {
|
||||||
color=blue
|
color=blue
|
||||||
115 [label="Enter while loop"];
|
115 [label="Enter while loop"];
|
||||||
@@ -344,8 +344,8 @@ digraph complex_kt {
|
|||||||
color=blue
|
color=blue
|
||||||
121 [label="Enter block"];
|
121 [label="Enter block"];
|
||||||
122 [label="Access variable R|<local>/<iterator>|"];
|
122 [label="Access variable R|<local>/<iterator>|"];
|
||||||
123 [label="Function call: R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|T|>|()"];
|
123 [label="Function call: R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/Any?|>|()"];
|
||||||
124 [label="Variable declaration: lval element: R|T|"];
|
124 [label="Variable declaration: lval element: R|kotlin/Any?|"];
|
||||||
subgraph cluster_29 {
|
subgraph cluster_29 {
|
||||||
color=blue
|
color=blue
|
||||||
125 [label="Enter when"];
|
125 [label="Enter when"];
|
||||||
|
|||||||
+2
-2
@@ -40,9 +40,9 @@ FILE: complex.kt
|
|||||||
}
|
}
|
||||||
public final inline fun <reified T : R|kotlin/Any|> R|kotlin/sequences/Sequence<*>|.firstIsInstanceOrNull(): R|T?| {
|
public final inline fun <reified T : R|kotlin/Any|> R|kotlin/sequences/Sequence<*>|.firstIsInstanceOrNull(): R|T?| {
|
||||||
lval <range>: R|kotlin/sequences/Sequence<*>| = this@R|/firstIsInstanceOrNull|
|
lval <range>: R|kotlin/sequences/Sequence<*>| = this@R|/firstIsInstanceOrNull|
|
||||||
lval <iterator>: R|kotlin/collections/Iterator<T>| = R|<local>/<range>|.R|kotlin/sequences/Sequence.iterator|()
|
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Any?>| = R|<local>/<range>|.R|FakeOverride<kotlin/sequences/Sequence.iterator: R|kotlin/collections/Iterator<kotlin/Any?>|>|()
|
||||||
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
|
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
|
||||||
lval element: R|T| = R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|T|>|()
|
lval element: R|kotlin/Any?| = R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/Any?|>|()
|
||||||
when () {
|
when () {
|
||||||
(R|<local>/element| is R|T|) -> {
|
(R|<local>/element| is R|T|) -> {
|
||||||
^firstIsInstanceOrNull R|<local>/element|
|
^firstIsInstanceOrNull R|<local>/element|
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ FILE: test.kt
|
|||||||
R|<local>/resolvedCall|.R|/ResolvedCall.resultingDescriptor|.R|/name|
|
R|<local>/resolvedCall|.R|/ResolvedCall.resultingDescriptor|.R|/name|
|
||||||
}
|
}
|
||||||
public final fun otherTest(call: R|Call<*>|, resolvedCall: R|ResolvedCall<*>|): R|kotlin/Unit| {
|
public final fun otherTest(call: R|Call<*>|, resolvedCall: R|ResolvedCall<*>|): R|kotlin/Unit| {
|
||||||
R|<local>/call|.R|/Call.resultingDescriptor|.R|/name|
|
R|<local>/call|.R|FakeOverride</Call.resultingDescriptor: R|Descriptor|>|.R|/name|
|
||||||
R|<local>/resolvedCall|.R|/ResolvedCall.resultingDescriptor|.R|/name|
|
R|<local>/resolvedCall|.R|/ResolvedCall.resultingDescriptor|.R|/name|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ FILE: test.kt
|
|||||||
private get(): R|DiagnosticFactory0<DerivedElement>|
|
private get(): R|DiagnosticFactory0<DerivedElement>|
|
||||||
public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| {
|
public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| {
|
||||||
lval casted: R|Diagnostic<*>!| = R|/DERIVED_FACTORY|.R|FakeOverride</DiagnosticFactory.cast: R|Diagnostic<*>!|>|(R|<local>/d|)
|
lval casted: R|Diagnostic<*>!| = R|/DERIVED_FACTORY|.R|FakeOverride</DiagnosticFactory.cast: R|Diagnostic<*>!|>|(R|<local>/d|)
|
||||||
lval element: R|E!| = R|<local>/casted|.R|/Diagnostic.element|
|
lval element: R|Element!| = R|<local>/casted|.R|/Diagnostic.element|
|
||||||
<Inapplicable(INAPPLICABLE): [/Fix.Fix]>#(R|<local>/element|)
|
<Inapplicable(INAPPLICABLE): [/Fix.Fix]>#(R|<local>/element|)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
public open class Some : R|kotlin/Any|, R|Strange<*>| {
|
public open class Some : R|kotlin/Any|, R|Strange<*>| {
|
||||||
public open operator fun foo(): R|kotlin/Any|
|
public open operator fun foo(): R|kotlin/Any?|
|
||||||
|
|
||||||
public constructor(): R|Some|
|
public constructor(): R|Some|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user