From 1e548e3f21f4a13ad81e17e6b9aa0930d8cc18b6 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 14 Nov 2019 15:50:36 +0300 Subject: [PATCH] FIR substitution: use intersection of bounds for * projection --- .../kotlin/fir/resolve/SupertypeUtils.kt | 16 +++++++++++++-- .../resolve/substitution/ConeSubstitutor.kt | 3 +-- .../body/resolve/BodyResolveUtils.kt | 20 ++++++++++++++++--- .../resolve/testData/resolve/cfg/complex.dot | 8 ++++---- .../resolve/testData/resolve/cfg/complex.txt | 4 ++-- .../expresssions/genericDescriptor.txt | 2 +- .../expresssions/genericDiagnostic.txt | 2 +- .../javaInheritsRawKotlin/extraDump.java.txt | 2 +- 8 files changed, 41 insertions(+), 16 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt index 93ec02d5c42..b92b4f3b4e3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirSession 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.impl.* import org.jetbrains.kotlin.fir.symbols.impl.* @@ -113,8 +114,19 @@ fun ConeClassLikeType.wrapSubstitutionScopeIfNeed( val typeParameters = (declaration as? FirTypeParametersOwner)?.typeParameters.orEmpty() @Suppress("UNCHECKED_CAST") val substitution = typeParameters.zip(this.typeArguments) { typeParameter, typeArgument -> - typeParameter.symbol to (typeArgument as? ConeTypedProjection)?.type - }.filter { (_, type) -> type != null }.toMap() as Map + val typeParameterSymbol = typeParameter.symbol + 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) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/substitution/ConeSubstitutor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/substitution/ConeSubstitutor.kt index efa5ac77ba1..b20e43e179e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/substitution/ConeSubstitutor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/substitution/ConeSubstitutor.kt @@ -93,7 +93,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() { } 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? { @@ -145,7 +145,6 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() { } - fun substitutorByMap(substitution: Map): ConeSubstitutor { if (substitution.isEmpty()) return ConeSubstitutor.Empty return ConeSubstitutorByMap(substitution) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt index 4b1a08e7e87..5838608a100 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt @@ -37,8 +37,12 @@ internal inline var FirExpression.resultType: FirTypeRef replaceTypeRef(type) } -internal fun inferenceComponents(session: FirSession, returnTypeCalculator: ReturnTypeCalculator, scopeSession: ScopeSession) = - InferenceComponents(object : ConeInferenceContext, TypeSystemInferenceExtensionContextDelegate, DataFlowInferenceContext { +internal interface UniversalConeInferenceContext : + ConeInferenceContext, TypeSystemInferenceExtensionContextDelegate, DataFlowInferenceContext + +internal fun FirSession.inferenceContext(): UniversalConeInferenceContext { + val session = this + return object : UniversalConeInferenceContext { override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List): SimpleTypeMarker? { // TODO: implement return null @@ -59,4 +63,14 @@ internal fun inferenceComponents(session: FirSession, returnTypeCalculator: Retu require(this is ErrorTypeConstructor) return ConeClassErrorType(reason) } - }, session, returnTypeCalculator, scopeSession) \ No newline at end of file + } +} + +internal fun inferenceComponents( + session: FirSession, + returnTypeCalculator: ReturnTypeCalculator, + scopeSession: ScopeSession +): InferenceComponents { + val inferenceContext = session.inferenceContext() + return InferenceComponents(inferenceContext, session, returnTypeCalculator, scopeSession) +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/cfg/complex.dot b/compiler/fir/resolve/testData/resolve/cfg/complex.dot index ae18582bd96..c9aa69b9756 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/complex.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/complex.dot @@ -325,8 +325,8 @@ digraph complex_kt { 110 [label="Access variable this@R|/firstIsInstanceOrNull|"]; 111 [label="Variable declaration: lval : R|kotlin/sequences/Sequence<*>|"]; 112 [label="Access variable R|/|"]; - 113 [label="Function call: R|/|.R|kotlin/sequences/Sequence.iterator|()"]; - 114 [label="Variable declaration: lval : R|kotlin/collections/Iterator|"]; + 113 [label="Function call: R|/|.R|FakeOverride|>|()"]; + 114 [label="Variable declaration: lval : R|kotlin/collections/Iterator|"]; subgraph cluster_25 { color=blue 115 [label="Enter while loop"]; @@ -344,8 +344,8 @@ digraph complex_kt { color=blue 121 [label="Enter block"]; 122 [label="Access variable R|/|"]; - 123 [label="Function call: R|/|.R|FakeOverride|()"]; - 124 [label="Variable declaration: lval element: R|T|"]; + 123 [label="Function call: R|/|.R|FakeOverride|()"]; + 124 [label="Variable declaration: lval element: R|kotlin/Any?|"]; subgraph cluster_29 { color=blue 125 [label="Enter when"]; diff --git a/compiler/fir/resolve/testData/resolve/cfg/complex.txt b/compiler/fir/resolve/testData/resolve/cfg/complex.txt index 3d2de763451..a000a45367b 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/complex.txt +++ b/compiler/fir/resolve/testData/resolve/cfg/complex.txt @@ -40,9 +40,9 @@ FILE: complex.kt } public final inline fun R|kotlin/sequences/Sequence<*>|.firstIsInstanceOrNull(): R|T?| { lval : R|kotlin/sequences/Sequence<*>| = this@R|/firstIsInstanceOrNull| - lval : R|kotlin/collections/Iterator| = R|/|.R|kotlin/sequences/Sequence.iterator|() + lval : R|kotlin/collections/Iterator| = R|/|.R|FakeOverride|>|() while(R|/|.R|kotlin/collections/Iterator.hasNext|()) { - lval element: R|T| = R|/|.R|FakeOverride|() + lval element: R|kotlin/Any?| = R|/|.R|FakeOverride|() when () { (R|/element| is R|T|) -> { ^firstIsInstanceOrNull R|/element| diff --git a/compiler/fir/resolve/testData/resolve/expresssions/genericDescriptor.txt b/compiler/fir/resolve/testData/resolve/expresssions/genericDescriptor.txt index a442538c847..8906e852aa8 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/genericDescriptor.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/genericDescriptor.txt @@ -11,6 +11,6 @@ FILE: test.kt R|/resolvedCall|.R|/ResolvedCall.resultingDescriptor|.R|/name| } public final fun otherTest(call: R|Call<*>|, resolvedCall: R|ResolvedCall<*>|): R|kotlin/Unit| { - R|/call|.R|/Call.resultingDescriptor|.R|/name| + R|/call|.R|FakeOverride|.R|/name| R|/resolvedCall|.R|/ResolvedCall.resultingDescriptor|.R|/name| } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/genericDiagnostic.txt b/compiler/fir/resolve/testData/resolve/expresssions/genericDiagnostic.txt index 730c3026601..2691596ff7e 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/genericDiagnostic.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/genericDiagnostic.txt @@ -17,6 +17,6 @@ FILE: test.kt private get(): R|DiagnosticFactory0| public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| { lval casted: R|Diagnostic<*>!| = R|/DERIVED_FACTORY|.R|FakeOverride!|>|(R|/d|) - lval element: R|E!| = R|/casted|.R|/Diagnostic.element| + lval element: R|Element!| = R|/casted|.R|/Diagnostic.element| #(R|/element|) } diff --git a/idea/testData/fir/multiModule/javaInheritsRawKotlin/extraDump.java.txt b/idea/testData/fir/multiModule/javaInheritsRawKotlin/extraDump.java.txt index 0be649d3908..96ecab90d18 100644 --- a/idea/testData/fir/multiModule/javaInheritsRawKotlin/extraDump.java.txt +++ b/idea/testData/fir/multiModule/javaInheritsRawKotlin/extraDump.java.txt @@ -1,5 +1,5 @@ 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|