From b2ff4d7f9a1317ae9f1776af4be490d0c2c4e3c2 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 6 Mar 2020 15:06:13 +0300 Subject: [PATCH] FIR: Support expansion of flexible type-alias-based types in inference --- .../kotlin/fir/types/ConeTypeContext.kt | 9 +++++ .../j+k/flexibleTypeAliases.kt | 35 +++++++++++++++++++ .../j+k/flexibleTypeAliases.txt | 8 +++++ ...FirDiagnosticsWithStdlibTestGenerated.java | 5 +++ 4 files changed, 57 insertions(+) create mode 100644 compiler/fir/resolve/testData/resolveWithStdlib/j+k/flexibleTypeAliases.kt create mode 100644 compiler/fir/resolve/testData/resolveWithStdlib/j+k/flexibleTypeAliases.txt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index 6d289b0911c..098ac25be5b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -398,6 +398,15 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty override fun prepareType(type: KotlinTypeMarker): KotlinTypeMarker { return when (type) { is ConeClassLikeType -> type.fullyExpandedType(session) + is ConeFlexibleType -> { + val lowerBound = prepareType(type.lowerBound) + if (lowerBound === type.lowerBound) return type + + ConeFlexibleType( + lowerBound as ConeKotlinType, + prepareType(type.upperBound) as ConeKotlinType + ) + } else -> type } } diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/j+k/flexibleTypeAliases.kt b/compiler/fir/resolve/testData/resolveWithStdlib/j+k/flexibleTypeAliases.kt new file mode 100644 index 00000000000..39aa6734f45 --- /dev/null +++ b/compiler/fir/resolve/testData/resolveWithStdlib/j+k/flexibleTypeAliases.kt @@ -0,0 +1,35 @@ +// FULL_JDK +// FILE: imm/Map.java +package imm; +public interface Map { + Option get(k K); +} + +// FILE: imm/Set.java +package imm; +public interface Set { +} + +// FILE: imm/Option.java +package imm; +public interface Option { + T getOrElse(T other); +} + +// FILE: imm/LinkedHashSet.java +package imm; +public class LinkedHashSet extends Set { + public static LinkedHashSet empty() { return null; } +} + +// FILE: main.kt + +typealias ImmutableMap = imm.Map +typealias ImmutableSet = imm.Set +typealias ImmutableLinkedHashSet = imm.LinkedHashSet + +private typealias ImmutableMultimap = ImmutableMap> + +private fun ImmutableMultimap.put(key: K, value: V) { + this[key].getOrElse(ImmutableLinkedHashSet.empty()) +} diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/j+k/flexibleTypeAliases.txt b/compiler/fir/resolve/testData/resolveWithStdlib/j+k/flexibleTypeAliases.txt new file mode 100644 index 00000000000..7fed31c5335 --- /dev/null +++ b/compiler/fir/resolve/testData/resolveWithStdlib/j+k/flexibleTypeAliases.txt @@ -0,0 +1,8 @@ +FILE: main.kt + public final typealias ImmutableMap = R|imm/Map| + public final typealias ImmutableSet = R|imm/Set| + public final typealias ImmutableLinkedHashSet = R|imm/LinkedHashSet| + private final typealias ImmutableMultimap = R|ImmutableMap>| + private final fun R|ImmutableMultimap|.put(key: R|K|, value: R|V|): R|kotlin/Unit| { + this@R|/put|.R|FakeOverride, ImmutableSet?>!>, imm/Option, ImmutableSet?>!>?>!|>|(R|/key|).R|FakeOverride, ImmutableSet?>!|>|(Q|ImmutableLinkedHashSet|.R|imm/LinkedHashSet.empty|()) + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index 6acac89b1c8..441c6bb4d39 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -585,6 +585,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/resolve/testData/resolveWithStdlib/j+k/FieldSubstitution.kt"); } + @TestMetadata("flexibleTypeAliases.kt") + public void testFlexibleTypeAliases() throws Exception { + runTest("compiler/fir/resolve/testData/resolveWithStdlib/j+k/flexibleTypeAliases.kt"); + } + @TestMetadata("FunctionTypeInJava.kt") public void testFunctionTypeInJava() throws Exception { runTest("compiler/fir/resolve/testData/resolveWithStdlib/j+k/FunctionTypeInJava.kt");