From 24948a8b3f6718a457ea42b07bacac49fd26e9d5 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 11 Jun 2020 13:25:39 +0300 Subject: [PATCH] FIR: Fix incorrect handling bare types when subject is type alias ^KT-39043 Fixed --- .../resolve/types/bareWithSubjectTypeAlias.kt | 14 +++++++ .../types/bareWithSubjectTypeAlias.txt | 39 +++++++++++++++++++ .../fir/FirDiagnosticsTestGenerated.java | 18 +++++++++ ...DiagnosticsWithLightTreeTestGenerated.java | 18 +++++++++ .../kotlin/fir/resolve/ResolveUtils.kt | 14 ++++++- .../FirExpressionsResolveTransformer.kt | 5 ++- 6 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.kt b/compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.kt new file mode 100644 index 00000000000..536f93fee4b --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.kt @@ -0,0 +1,14 @@ +sealed class A { + class B(val x: T1) : A() + class C(val y: T2) : A() +} + +typealias TA = A + +fun bar(): TA = TODO() + +fun foo() { + when (val a = bar()) { + is A.B -> a.x.length + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.txt b/compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.txt new file mode 100644 index 00000000000..4d524ea9d11 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.txt @@ -0,0 +1,39 @@ +FILE: bareWithSubjectTypeAlias.kt + public sealed class A : R|kotlin/Any| { + private constructor(): R|A| { + super() + } + + public final class B : R|A| { + public constructor(x: R|T1|): R|A.B| { + super|>() + } + + public final val x: R|T1| = R|/x| + public get(): R|T1| + + } + + public final class C : R|A| { + public constructor(y: R|T2|): R|A.C| { + super|>() + } + + public final val y: R|T2| = R|/y| + public get(): R|T2| + + } + + } + public final typealias TA = R|A| + public final fun bar(): R|TA| { + ^bar R|kotlin/TODO|() + } + public final fun foo(): R|kotlin/Unit| { + when (lval a: R|TA| = R|/bar|()) { + ($subj$ is R|A.B|) -> { + R|/a|.R|FakeOverride|.R|kotlin/CharSequence.length| + } + } + + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index 61082eb2a7d..59ae935d5c4 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -2241,6 +2241,24 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { } } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/types") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Types extends AbstractFirDiagnosticsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInTypes() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/types"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("bareWithSubjectTypeAlias.kt") + public void testBareWithSubjectTypeAlias() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.kt"); + } + } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/visibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 255dda8aefa..b69d322b458 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -2241,6 +2241,24 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos } } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/types") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Types extends AbstractFirDiagnosticsWithLightTreeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInTypes() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/types"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("bareWithSubjectTypeAlias.kt") + public void testBareWithSubjectTypeAlias() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/types/bareWithSubjectTypeAlias.kt"); + } + } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/visibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 4f06b30b820..058bd798be7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -8,13 +8,15 @@ package org.jetbrains.kotlin.fir.resolve import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.FirResolvedReifiedParameterReferenceBuilder import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionWithSmartcast import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier +import org.jetbrains.kotlin.fir.inferenceContext import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirSuperReference @@ -28,6 +30,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.bindSymbolToLookupTag import org.jetbrains.kotlin.fir.resolve.providers.getSymbolByTypeRef import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType +import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.symbols.* @@ -87,6 +90,15 @@ fun ConeClassLikeType.fullyExpandedType( return fullyExpandedTypeNoCache(useSiteSession, expandedConeType) } +fun ConeKotlinType.fullyExpandedType( + useSiteSession: FirSession +): ConeKotlinType = when (this) { + is ConeFlexibleType -> + ConeFlexibleType(lowerBound.fullyExpandedType(useSiteSession), upperBound.fullyExpandedType(useSiteSession)) + is ConeClassLikeType -> fullyExpandedType(useSiteSession) + else -> this +} + private fun ConeClassLikeType.fullyExpandedTypeNoCache( useSiteSession: FirSession, expandedConeType: (FirTypeAlias) -> ConeClassLikeType?, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index a8e132bed0a..33633612f39 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -34,7 +34,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.* -import org.jetbrains.kotlin.fir.types.impl.FirQualifierPartImpl import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -379,7 +378,9 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform } private fun FirTypeRef.withTypeArgumentsForBareType(argument: FirExpression): FirTypeRef { - val baseTypeArguments = argument.typeRef.coneTypeSafe()?.typeArguments + // TODO: Everything should also work for case of checked-type itself is a type alias + val baseTypeArguments = + argument.typeRef.coneTypeSafe()?.fullyExpandedType(session)?.typeArguments val type = coneTypeSafe() return if (type?.typeArguments?.isEmpty() != true || type is ConeTypeParameterType ||