FIR: Refine inference constraints when type variable in flexible position

That issue might be fixed via changing
TypeVariableMarker.shouldBeFlexible at ConeConstraintSystemUtilContext
but this and some other tricks have been added because of incorrect
handling of constraints where type variable has a flexible bound

^KT-51168 Fixed
This commit is contained in:
Denis.Zharkov
2022-04-12 16:30:55 +03:00
committed by teamcity
parent 853b7ec078
commit f70ae2df3a
54 changed files with 411 additions and 154 deletions
@@ -7,7 +7,7 @@ FILE: main.kt
public abstract interface PsiClass : R|kotlin/Any| {
}
public final fun test(): R|kotlin/Unit| {
lval processor: R|AdapterProcessor<ft<PsiMethod, PsiMethod?>, ft<PsiClass, PsiClass?>>| = R|/AdapterProcessor.AdapterProcessor|<R|ft<PsiMethod, PsiMethod?>|, R|ft<PsiClass, PsiClass?>|>(R|/Function|<R|ft<PsiMethod, PsiMethod?>|, R|ft<PsiClass, PsiClass?>|>(<L> = Function@fun <anonymous>(method: R|PsiMethod?|): R|ft<PsiClass, PsiClass?>| <inline=NoInline> {
lval processor: R|AdapterProcessor<PsiMethod, PsiClass>| = R|/AdapterProcessor.AdapterProcessor|<R|PsiMethod|, R|PsiClass|>(R|/Function|<R|ft<PsiMethod, PsiMethod?>|, R|ft<PsiClass, PsiClass?>|>(<L> = Function@fun <anonymous>(method: R|PsiMethod?|): R|ft<PsiClass, PsiClass?>| <inline=NoInline> {
^ R|<local>/method|?.{ $subj$.R|/PsiMethod.containingClass| }
}
))
@@ -1,4 +1,4 @@
FILE: main.kt
public final fun <T> test(executor: R|BuildActionExecuter<T>|, modelType: R|java/lang/Class<T>|, env: R|kotlin/collections/Map<kotlin/String, kotlin/String>|): R|kotlin/Unit| {
lval model: R|ft<BuildActionExecuter<ft<T, T?>>, BuildActionExecuter<ft<T, T?>>?>| = R|<local>/executor|.R|SubstitutionOverride</BuildActionExecuter.setEnvironmentVariables: R|ft<BuildActionExecuter<ft<T, T?>>, BuildActionExecuter<ft<T, T?>>?>|>|(R|<local>/env|)
lval model: R|ft<BuildActionExecuter<ft<T & Any, T?>>, BuildActionExecuter<ft<T & Any, T?>>?>| = R|<local>/executor|.R|SubstitutionOverride</BuildActionExecuter.setEnvironmentVariables: R|ft<BuildActionExecuter<ft<T & Any, T?>>, BuildActionExecuter<ft<T & Any, T?>>?>|>|(R|<local>/env|)
}
@@ -26,13 +26,13 @@ FILE: main.kt
}
public final fun test_1(): R|kotlin/Unit| {
lval map: R|util/HashMap<ft<kotlin/Int, kotlin/Int?>, ft<kotlin/Int, kotlin/Int?>>| = R|util/HashMap.HashMap|<R|ft<kotlin/Int, kotlin/Int?>|, R|ft<kotlin/Int, kotlin/Int?>|>()
lval map: R|util/HashMap<kotlin/Int, kotlin/Int>| = R|util/HashMap.HashMap|<R|kotlin/Int|, R|kotlin/Int|>()
}
public final fun test_2(): R|kotlin/Unit| {
lval set: R|util/HashSet<kotlin/Int>| = R|util/HashSet.HashSet|<R|kotlin/Int|>()
}
public final fun test_3(): R|kotlin/Unit| {
lval list: R|foo/ArrayList<ft<kotlin/Int, kotlin/Int?>>| = R|foo/ArrayList.ArrayList|<R|ft<kotlin/Int, kotlin/Int?>|>()
lval list: R|foo/ArrayList<kotlin/Int>| = R|foo/ArrayList.ArrayList|<R|kotlin/Int|>()
}
public final fun test_4(): R|kotlin/Unit| {
lval list: R|foo/LinkedList<kotlin/Int>| = R|foo/LinkedList.LinkedList|<R|kotlin/Int|>()
@@ -13,8 +13,8 @@ FILE: test.kt
lval element: R|DE| = R|<local>/d|.R|/Diagnostic.element|
R|/Fix.Fix|(R|<local>/element|)
}
private final val DERIVED_FACTORY: R|DiagnosticFactory0<ft<DerivedElement, DerivedElement?>>| = R|/DiagnosticFactory0.DiagnosticFactory0|<R|ft<DerivedElement, DerivedElement?>|>()
private get(): R|DiagnosticFactory0<ft<DerivedElement, DerivedElement?>>|
private final val DERIVED_FACTORY: R|DiagnosticFactory0<DerivedElement>| = R|/DiagnosticFactory0.DiagnosticFactory0|<R|DerivedElement|>()
private get(): R|DiagnosticFactory0<DerivedElement>|
public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| {
lval casted: R|Diagnostic<ft<DerivedElement, DerivedElement?>>| = R|/DERIVED_FACTORY|.R|SubstitutionOverride</DiagnosticFactory0.cast: R|@EnhancedNullability Diagnostic<ft<DerivedElement, DerivedElement?>>|>|(R|<local>/d|)
lval element: R|DerivedElement| = R|<local>/casted|.R|/Diagnostic.element|
@@ -1,6 +1,6 @@
FILE: flexibleTypeBug.kt
public final fun foo(): R|kotlin/Unit| {
lvar list1: R|ft<kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>, kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>| = Q|java/util/Collections|.R|java/util/Collections.emptyList|<R|ft<kotlin/String, kotlin/String?>|>()
lvar list1: R|ft<kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>, kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>| = Q|java/util/Collections|.R|java/util/Collections.emptyList|<R|kotlin/String|>()
lval list2: R|kotlin/collections/List<kotlin/String>| = R|kotlin/collections/listOf|<R|kotlin/String|>(String(b))
R|<local>/list1| = R|<local>/list1|.R|kotlin/collections/plus|<R|ft<kotlin/String, kotlin/String?>|>(R|<local>/list2|)
}
@@ -1,4 +1,4 @@
FILE: main.kt
public final fun main(): R|kotlin/Unit| {
R|/JavaClass.JavaClass|<R|ft<kotlin/String, kotlin/String?>|>(Null(null)).R|SubstitutionOverride</JavaClass.foo: R|ft<kotlin/String, kotlin/String?>|>|().R|kotlin/String.length|
R|/JavaClass.JavaClass|<R|kotlin/String|>(Null(null)).R|SubstitutionOverride</JavaClass.foo: R|ft<kotlin/String, kotlin/String?>|>|().R|kotlin/String.length|
}
@@ -1,6 +1,6 @@
FILE: main.kt
public final fun main(): R|kotlin/Unit| {
R|/MyFunction|<R|ft<kotlin/Int, kotlin/Int?>|, R|ft<kotlin/String, kotlin/String?>|>(<L> = MyFunction@fun <anonymous>(x: R|ft<kotlin/Int, kotlin/Int?>|): R|ft<kotlin/String, kotlin/String?>| <inline=NoInline> {
R|/MyFunction|<R|kotlin/Int|, R|kotlin/String|>(<L> = MyFunction@fun <anonymous>(x: R|ft<kotlin/Int, kotlin/Int?>|): R|ft<kotlin/String, kotlin/String?>| <inline=NoInline> {
^ R|<local>/x|.R|kotlin/Int.toInt|().R|kotlin/Int.toString|()
}
)
@@ -2,8 +2,8 @@ C:
[Source]: public open override fun getName(): R|kotlin/String| from Use site scope of /C [id: 0]
[Enhancement]: public abstract fun getName(): R|ft<kotlin/String, kotlin/String?>| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
[Source]: public open override fun setName(newName: R|kotlin/String|): R|kotlin/Any?| from Use site scope of /C [id: 0]
[SubstitutionOverride]: public abstract fun setName(newName: R|ft<kotlin/String, kotlin/String?>|): R|kotlin/Any?| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
[Enhancement]: public abstract fun setName(newName: R|ft<kotlin/String, kotlin/String?>|): R|ft<T, T?>| from Java enhancement scope for /B [id: 2]
[SubstitutionOverride]: public abstract fun setName(newName: R|ft<kotlin/String, kotlin/String?>|): R|ft<kotlin/Any, kotlin/Any?>| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
[Enhancement]: public abstract fun setName(newName: R|ft<kotlin/String, kotlin/String?>|): R|ft<T & Any, T?>| from Java enhancement scope for /B [id: 2]
[Source]: private final var name: R|kotlin/String| = R|<local>/name| from Use site scope of /C [id: 0]
D:
@@ -1,5 +1,5 @@
FILE: main.kt
public final fun <T : R|kotlin/CharSequence?|> foo(mapper: R|Mapper|, cls: R|java/lang/Class<T>?|): R|kotlin/Unit| {
lval result: R|T & Any| = R|<local>/mapper|.R|/Mapper.readValue|<R|ft<T, T?>|>(R|<local>/cls|)!!
lval result: R|T & Any| = R|<local>/mapper|.R|/Mapper.readValue|<R|T|>(R|<local>/cls|)!!
R|<local>/result|.R|kotlin/CharSequence.length|
}
@@ -3,5 +3,5 @@ FILE: main.kt
public final typealias ImmutableSet<E> = R|MySet<E>|
private final typealias ImmutableMultimap<K, V> = R|ImmutableMap<K, ImmutableSet<V>>|
private final fun <K, V> R|ImmutableMultimap<K, V>|.put(key: R|K|, value: R|V|, oldSet: R|ImmutableSet<V>|): R|ImmutableMultimap<K, V>| {
^put this@R|/put|.R|SubstitutionOverride</MyMap.put: R|ft<MyMap<ft<K, K?>, ft<ImmutableSet<V>, ImmutableSet<V>?>>, MyMap<ft<K, K?>, ft<ImmutableSet<V>, ImmutableSet<V>?>>?>|>|(R|<local>/key|, R|<local>/oldSet|.R|SubstitutionOverride</MySet.add: R|ft<MySet<ft<V, V?>>, MySet<ft<V, V?>>?>|>|(R|<local>/value|))
^put this@R|/put|.R|SubstitutionOverride</MyMap.put: R|ft<MyMap<ft<K & Any, K?>, ft<ImmutableSet<V>, ImmutableSet<V>?>>, MyMap<ft<K & Any, K?>, ft<ImmutableSet<V>, ImmutableSet<V>?>>?>|>|(R|<local>/key|, R|<local>/oldSet|.R|SubstitutionOverride</MySet.add: R|ft<MySet<ft<V & Any, V?>>, MySet<ft<V & Any, V?>>?>|>|(R|<local>/value|))
}
@@ -5,8 +5,8 @@ FILE: concurrentMapOfAliases.kt
super<R|kotlin/Any|>()
}
private final val foo: R|java/util/concurrent/ConcurrentHashMap<ft<kotlin/String, kotlin/String?>, ft<kotlin/CharSequence, kotlin/CharSequence?>>| = Q|java/util/concurrent|.R|java/util/concurrent/ConcurrentHashMap.ConcurrentHashMap|<R|ft<kotlin/String, kotlin/String?>|, R|ft<kotlin/CharSequence, kotlin/CharSequence?>|>()
private get(): R|java/util/concurrent/ConcurrentHashMap<ft<kotlin/String, kotlin/String?>, ft<kotlin/CharSequence, kotlin/CharSequence?>>|
private final val foo: R|java/util/concurrent/ConcurrentHashMap<kotlin/String, kotlin/CharSequence>| = Q|java/util/concurrent|.R|java/util/concurrent/ConcurrentHashMap.ConcurrentHashMap|<R|kotlin/String|, R|kotlin/CharSequence|>()
private get(): R|java/util/concurrent/ConcurrentHashMap<kotlin/String, kotlin/CharSequence>|
private final fun bar(): R|kotlin/Unit| {
this@R|/A|.R|/A.foo|.R|SubstitutionOverride<java/util/concurrent/ConcurrentHashMap.get: R|kotlin/CharSequence?|>|(String(dd))?.{ (this@R|/A|, $subj$).R|/A.baz|() }
@@ -4,5 +4,5 @@ FILE: main.kt
public final typealias ImmutableLinkedHashSet<E> = R|imm/LinkedHashSet<E>|
private final typealias ImmutableMultimap<K, V> = R|ImmutableMap<K, ImmutableSet<V>>|
private final fun <K, V> R|ImmutableMultimap<K, V>|.put(key: R|K|, value: R|V|): R|kotlin/Unit| {
this@R|/put|.R|SubstitutionOverride<imm/Map.get: R|ft<imm/Option<ft<ImmutableSet<V>, ImmutableSet<V>?>>, imm/Option<ft<ImmutableSet<V>, ImmutableSet<V>?>>?>|>|(R|<local>/key|).R|SubstitutionOverride<imm/Option.getOrElse: R|ft<ImmutableSet<V>, ImmutableSet<V>?>|>|(Q|ImmutableLinkedHashSet|.R|imm/LinkedHashSet.empty|<R|ft<V, V?>|>())
this@R|/put|.R|SubstitutionOverride<imm/Map.get: R|ft<imm/Option<ft<ImmutableSet<V>, ImmutableSet<V>?>>, imm/Option<ft<ImmutableSet<V>, ImmutableSet<V>?>>?>|>|(R|<local>/key|).R|SubstitutionOverride<imm/Option.getOrElse: R|ft<ImmutableSet<V>, ImmutableSet<V>?>|>|(Q|ImmutableLinkedHashSet|.R|imm/LinkedHashSet.empty|<R|V|>())
}
@@ -1,6 +1,6 @@
FILE: javaLangComparator.kt
public final fun test_2(list: R|kotlin/collections/List<kotlin/Int>|): R|kotlin/Unit| {
lval comp: R|java/util/Comparator<ft<kotlin/Int, kotlin/Int?>>| = Q|java/util|.R|java/util/Comparator|<R|ft<kotlin/Int, kotlin/Int?>|>(<L> = Comparator@fun <anonymous>(x: R|ft<kotlin/Int, kotlin/Int?>|, y: R|ft<kotlin/Int, kotlin/Int?>|): R|kotlin/Int| <inline=NoInline> {
lval comp: R|java/util/Comparator<kotlin/Int>| = Q|java/util|.R|java/util/Comparator|<R|kotlin/Int|>(<L> = Comparator@fun <anonymous>(x: R|ft<kotlin/Int, kotlin/Int?>|, y: R|ft<kotlin/Int, kotlin/Int?>|): R|kotlin/Int| <inline=NoInline> {
^ Int(1)
}
)
@@ -1,6 +1,6 @@
FILE: kotlinComparatorAlias.kt
public final fun test_1(): R|kotlin/Unit| {
lval comp: R|java/util/Comparator<ft<kotlin/Int, kotlin/Int?>>| = R|java/util/Comparator|<R|ft<kotlin/Int, kotlin/Int?>|>(<L> = Comparator@fun <anonymous>(x: R|ft<kotlin/Int, kotlin/Int?>|, y: R|ft<kotlin/Int, kotlin/Int?>|): R|kotlin/Int| <inline=NoInline> {
lval comp: R|java/util/Comparator<kotlin/Int>| = R|java/util/Comparator|<R|kotlin/Int|>(<L> = Comparator@fun <anonymous>(x: R|ft<kotlin/Int, kotlin/Int?>|, y: R|ft<kotlin/Int, kotlin/Int?>|): R|kotlin/Int| <inline=NoInline> {
^ Int(1)
}
)
@@ -1,6 +1,6 @@
FILE: weakHashMap.kt
public final val someMap: R|java/util/WeakHashMap<ft<kotlin/Any, kotlin/Any?>, ft<kotlin/Any, kotlin/Any?>>| = R|java/util/WeakHashMap.WeakHashMap|<R|ft<kotlin/Any, kotlin/Any?>|, R|ft<kotlin/Any, kotlin/Any?>|>()
public get(): R|java/util/WeakHashMap<ft<kotlin/Any, kotlin/Any?>, ft<kotlin/Any, kotlin/Any?>>|
public final val someMap: R|java/util/WeakHashMap<kotlin/Any?, kotlin/Any?>| = R|java/util/WeakHashMap.WeakHashMap|<R|kotlin/Any?|, R|kotlin/Any?|>()
public get(): R|java/util/WeakHashMap<kotlin/Any?, kotlin/Any?>|
public final fun foo(): R|kotlin/Unit| {
R|/someMap|.R|SubstitutionOverride<java/util/WeakHashMap.get: R|kotlin/Any?|>|(String())
}
@@ -9,9 +9,9 @@ FILE: typeAliasWithForEach.kt
}
public final typealias Arguments = R|kotlin/collections/Map<kotlin/String, ArgsInfo>|
public final fun R|Arguments|.deepCopy(): R|Arguments| {
lval result: R|java/util/HashMap<ft<kotlin/String, kotlin/String?>, ft<ArgsInfo, ArgsInfo?>>| = R|java/util/HashMap.HashMap|<R|ft<kotlin/String, kotlin/String?>|, R|ft<ArgsInfo, ArgsInfo?>|>()
lval result: R|java/util/HashMap<kotlin/String, ArgsInfo>| = R|java/util/HashMap.HashMap|<R|kotlin/String|, R|ArgsInfo|>()
this@R|/deepCopy|.R|SubstitutionOverride<kotlin/collections/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|@EnhancedNullability kotlin/String|, value: R|@EnhancedNullability ArgsInfo|): R|kotlin/Unit| <inline=NoInline> {
R|<local>/result|.R|kotlin/collections/set|<R|ft<kotlin/String, kotlin/String?>|, R|ft<ArgsInfo, ArgsInfo?>|>(R|<local>/key|, R|/ArgsInfoImpl.ArgsInfoImpl|(R|<local>/value|))
R|<local>/result|.R|kotlin/collections/set|<R|kotlin/String|, R|ArgsInfo|>(R|<local>/key|, R|/ArgsInfoImpl.ArgsInfoImpl|(R|<local>/value|))
}
)
^deepCopy R|<local>/result|