Add equality constraints without subtyping
^KT-42195 Fixed ^KT-41741 Fixed
This commit is contained in:
+2
-2
@@ -26,8 +26,8 @@ FILE: upperBoundViolated.kt
|
||||
lval b5: R|B<A>| = R|/B.B|<<ERROR TYPE REF: Symbol not found, for `UnexistingType`>>()
|
||||
R|/fest|<R|kotlin/Boolean|>()
|
||||
R|/fest|<R|C|>()
|
||||
R|/fest|<R|C|>()
|
||||
R|/fest|<R|B<C>|>()
|
||||
R|/fest|<R|HHH|>()
|
||||
R|/fest|<R|JJJ|>()
|
||||
}
|
||||
public open class S<F, G : R|F|> : R|kotlin/Any| {
|
||||
public constructor<F, G : R|F|>(): R|S<F, G>| {
|
||||
|
||||
+3
-3
@@ -5,11 +5,11 @@ 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<ft<kotlin/String, kotlin/String?>!, ft<MyAlias, MyAlias?>!>| = Q|java/util/concurrent|.R|java/util/concurrent/ConcurrentHashMap.ConcurrentHashMap|<R|ft<kotlin/String, kotlin/String?>!|, R|ft<MyAlias, MyAlias?>!|>()
|
||||
private get(): R|java/util/concurrent/ConcurrentHashMap<ft<kotlin/String, kotlin/String?>!, ft<MyAlias, MyAlias?>!>|
|
||||
|
||||
private final fun bar(): R|kotlin/Unit| {
|
||||
this@R|/A|.R|/A.foo|.R|FakeOverride<java/util/concurrent/ConcurrentHashMap.get: R|kotlin/CharSequence?|>|(String(dd))?.{ (this@R|/A|, $subj$).R|/A.baz|() }
|
||||
this@R|/A|.R|/A.foo|.R|FakeOverride<java/util/concurrent/ConcurrentHashMap.get: R|MyAlias?|>|(String(dd))?.{ (this@R|/A|, $subj$).R|/A.baz|() }
|
||||
}
|
||||
|
||||
private final fun R|MyAlias|.baz(): R|kotlin/Unit| {
|
||||
|
||||
+23
@@ -3023,6 +3023,29 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AddEqualityConstraintsWithoutSubtyping extends AbstractFirOldFrontendDiagnosticsTestWithStdlib {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAddEqualityConstraintsWithoutSubtyping() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt41741.kt")
|
||||
public void testKt41741() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping/kt41741.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42195.kt")
|
||||
public void testKt42195() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping/kt42195.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+2
@@ -34,6 +34,8 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
||||
isFromNullabilityConstraint: Boolean = false
|
||||
)
|
||||
|
||||
abstract fun addEqualityConstraint(typeVariable: TypeConstructorMarker, type: KotlinTypeMarker)
|
||||
|
||||
override fun getLowerCapturedTypePolicy(subType: SimpleTypeMarker, superType: CapturedTypeMarker): LowerCapturedTypePolicy {
|
||||
return when {
|
||||
isMyTypeVariable(subType) -> {
|
||||
|
||||
+6
-2
@@ -40,15 +40,19 @@ class ConstraintIncorporator(
|
||||
fun addNewIncorporatedConstraint(typeVariable: TypeVariableMarker, type: KotlinTypeMarker, constraintContext: ConstraintContext)
|
||||
}
|
||||
|
||||
fun incorporateIntoOtherConstraints(c: Context, typeVariable: TypeVariableMarker, constraint: Constraint) {
|
||||
fun incorporateEqualityConstraint(c: Context, typeVariable: TypeVariableMarker, constraint: Constraint) = with(c) {
|
||||
// we shouldn't incorporate recursive constraint -- It is too dangerous
|
||||
if (c.areThereRecursiveConstraints(typeVariable, constraint)) return
|
||||
|
||||
c.directWithVariable(typeVariable, constraint)
|
||||
if (constraint.type.contains { it is TypeVariableTypeConstructorMarker }) {
|
||||
c.otherInsideMyConstraint(typeVariable, constraint)
|
||||
}
|
||||
c.insideOtherConstraint(typeVariable, constraint)
|
||||
}
|
||||
|
||||
// \alpha is typeVariable, \beta -- other type variable registered in ConstraintStorage
|
||||
fun incorporate(c: Context, typeVariable: TypeVariableMarker, constraint: Constraint) {
|
||||
fun incorporateSubtypeConstraint(c: Context, typeVariable: TypeVariableMarker, constraint: Constraint) {
|
||||
// we shouldn't incorporate recursive constraint -- It is too dangerous
|
||||
if (c.areThereRecursiveConstraints(typeVariable, constraint)) return
|
||||
|
||||
|
||||
+54
-15
@@ -39,28 +39,42 @@ class ConstraintInjector(
|
||||
|
||||
fun addInitialSubtypeConstraint(c: Context, lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker, position: ConstraintPosition) {
|
||||
val initialConstraint = InitialConstraint(lowerType, upperType, UPPER, position).also { c.addInitialConstraint(it) }
|
||||
val typeCheckerContext = TypeCheckerContext(c, IncorporationConstraintPosition(position, initialConstraint))
|
||||
|
||||
updateAllowedTypeDepth(c, lowerType)
|
||||
updateAllowedTypeDepth(c, upperType)
|
||||
|
||||
addSubTypeConstraintAndIncorporateIt(
|
||||
c,
|
||||
lowerType,
|
||||
upperType,
|
||||
TypeCheckerContext(c, IncorporationConstraintPosition(position, initialConstraint))
|
||||
)
|
||||
addSubTypeConstraintAndIncorporateIt(c, lowerType, upperType, typeCheckerContext)
|
||||
}
|
||||
|
||||
fun addInitialEqualityConstraint(c: Context, a: KotlinTypeMarker, b: KotlinTypeMarker, position: ConstraintPosition) {
|
||||
val initialConstraint = InitialConstraint(a, b, EQUALITY, position).also { c.addInitialConstraint(it) }
|
||||
|
||||
updateAllowedTypeDepth(c, a)
|
||||
updateAllowedTypeDepth(c, b)
|
||||
private fun Context.addInitialEqualityConstraintThroughSubtyping(
|
||||
a: KotlinTypeMarker,
|
||||
b: KotlinTypeMarker,
|
||||
typeCheckerContext: TypeCheckerContext
|
||||
) {
|
||||
updateAllowedTypeDepth(this, a)
|
||||
updateAllowedTypeDepth(this, b)
|
||||
addSubTypeConstraintAndIncorporateIt(this, a, b, typeCheckerContext)
|
||||
addSubTypeConstraintAndIncorporateIt(this, b, a, typeCheckerContext)
|
||||
}
|
||||
|
||||
fun addInitialEqualityConstraint(c: Context, a: KotlinTypeMarker, b: KotlinTypeMarker, position: ConstraintPosition) = with(c) {
|
||||
val (typeVariable, equalType) = when {
|
||||
a.typeConstructor(c) is TypeVariableTypeConstructorMarker -> a to b
|
||||
b.typeConstructor(c) is TypeVariableTypeConstructorMarker -> b to a
|
||||
else -> return
|
||||
}
|
||||
val initialConstraint = InitialConstraint(typeVariable, equalType, EQUALITY, position).also { c.addInitialConstraint(it) }
|
||||
val typeCheckerContext = TypeCheckerContext(c, IncorporationConstraintPosition(position, initialConstraint))
|
||||
|
||||
addSubTypeConstraintAndIncorporateIt(c, a, b, typeCheckerContext)
|
||||
addSubTypeConstraintAndIncorporateIt(c, b, a, typeCheckerContext)
|
||||
// We add constraints like `T? == Foo!` in the old way
|
||||
if (!typeVariable.isSimpleType() || typeVariable.isMarkedNullable()) {
|
||||
addInitialEqualityConstraintThroughSubtyping(typeVariable, equalType, typeCheckerContext)
|
||||
return
|
||||
}
|
||||
|
||||
updateAllowedTypeDepth(c, equalType)
|
||||
addEqualityConstraintAndIncorporateIt(c, typeVariable, equalType, typeCheckerContext)
|
||||
}
|
||||
|
||||
private fun addSubTypeConstraintAndIncorporateIt(
|
||||
@@ -72,6 +86,26 @@ class ConstraintInjector(
|
||||
typeCheckerContext.setConstrainingTypesToPrintDebugInfo(lowerType, upperType)
|
||||
typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
|
||||
|
||||
processConstraints(c, typeCheckerContext, constraintIncorporator::incorporateSubtypeConstraint)
|
||||
}
|
||||
|
||||
private fun addEqualityConstraintAndIncorporateIt(
|
||||
c: Context,
|
||||
typeVariable: KotlinTypeMarker,
|
||||
equalType: KotlinTypeMarker,
|
||||
typeCheckerContext: TypeCheckerContext
|
||||
) {
|
||||
typeCheckerContext.setConstrainingTypesToPrintDebugInfo(typeVariable, equalType)
|
||||
typeCheckerContext.addEqualityConstraint(typeVariable.typeConstructor(c), equalType)
|
||||
|
||||
processConstraints(c, typeCheckerContext, constraintIncorporator::incorporateEqualityConstraint)
|
||||
}
|
||||
|
||||
private fun processConstraints(
|
||||
c: Context,
|
||||
typeCheckerContext: TypeCheckerContext,
|
||||
incorporate: (c: TypeCheckerContext, typeVariable: TypeVariableMarker, constraint: Constraint) -> Unit
|
||||
) {
|
||||
while (typeCheckerContext.hasConstraintsToProcess()) {
|
||||
for ((typeVariable, constraint) in typeCheckerContext.extractAllConstraints()!!) {
|
||||
if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue
|
||||
@@ -82,7 +116,7 @@ class ConstraintInjector(
|
||||
// it is important, that we add constraint here(not inside TypeCheckerContext), because inside incorporation we read constraints
|
||||
constraints.addConstraint(constraint)?.let {
|
||||
if (!constraint.isNullabilityConstraint) {
|
||||
constraintIncorporator.incorporate(typeCheckerContext, typeVariable, it)
|
||||
incorporate(typeCheckerContext, typeVariable, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,7 +139,8 @@ class ConstraintInjector(
|
||||
}
|
||||
|
||||
private fun Context.shouldWeSkipConstraint(typeVariable: TypeVariableMarker, constraint: Constraint): Boolean {
|
||||
assert(constraint.kind != EQUALITY)
|
||||
if (constraint.kind == EQUALITY)
|
||||
return false
|
||||
|
||||
val constraintType = constraint.type
|
||||
|
||||
@@ -221,6 +256,10 @@ class ConstraintInjector(
|
||||
isFromNullabilityConstraint: Boolean
|
||||
) = addConstraint(typeVariable, subType, LOWER, isFromNullabilityConstraint)
|
||||
|
||||
override fun addEqualityConstraint(typeVariable: TypeConstructorMarker, type: KotlinTypeMarker) {
|
||||
addConstraint(typeVariable, type, EQUALITY, false)
|
||||
}
|
||||
|
||||
private fun isCapturedTypeFromSubtyping(type: KotlinTypeMarker) =
|
||||
when ((type as? CapturedTypeMarker)?.captureStatus()) {
|
||||
null, CaptureStatus.FROM_EXPRESSION -> false
|
||||
|
||||
@@ -48,7 +48,7 @@ fun <T> bar(a: Any): T = a as T
|
||||
|
||||
fun <T> foo() {
|
||||
foo<<!UNRESOLVED_REFERENCE!>Color.RED<!>>()
|
||||
foo<RedAlias>()
|
||||
foo<<!UPPER_BOUND_VIOLATED!>RedAlias<!>>()
|
||||
<!INAPPLICABLE_CANDIDATE!>bar<!><<!UNRESOLVED_REFERENCE!>Color.RED<!>>(Color.RED)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ fun <T> test2(t : T)
|
||||
t.bar()
|
||||
}
|
||||
|
||||
val t1 = test2<<!UPPER_BOUND_VIOLATED!>A<!>>(A())
|
||||
val t1 = test2<<!UPPER_BOUND_VIOLATED!>A<!>>(<!TYPE_MISMATCH!>A()<!>)
|
||||
val t2 = test2<<!UPPER_BOUND_VIOLATED!>B<!>>(C())
|
||||
val t3 = test2<C>(C())
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -15,5 +15,5 @@ fun <K, V> B<K>.foo(p: KProperty1<K, V>) {}
|
||||
class C : A
|
||||
|
||||
fun <R : A> B<R>.test(){
|
||||
foo(<!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>C::bla<!>)
|
||||
foo(<!TYPE_MISMATCH, TYPE_MISMATCH!>C::bla<!>)
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ fun main() {
|
||||
val x1 = select<Any?>(id { <!CANNOT_INFER_PARAMETER_TYPE!>x<!>, <!CANNOT_INFER_PARAMETER_TYPE, CANNOT_INFER_PARAMETER_TYPE!>y<!> -> }, { x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!> -> })
|
||||
val x2 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id<!> { x, <!CANNOT_INFER_PARAMETER_TYPE!>y<!> -> }, { x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!> -> })
|
||||
|
||||
val x3 = select(id(fun (x, y) {}), fun (x: Int, y) {})
|
||||
val x3 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id<!>(fun (x, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {}), fun (x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {})
|
||||
|
||||
val x4 = select<Any?>((fun (<!CANNOT_INFER_PARAMETER_TYPE!>x<!>, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {}), fun (x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {})
|
||||
val x5 = select<Any?>(id(fun (<!CANNOT_INFER_PARAMETER_TYPE, CANNOT_INFER_PARAMETER_TYPE!>x<!>, <!CANNOT_INFER_PARAMETER_TYPE, CANNOT_INFER_PARAMETER_TYPE!>y<!>) {}), fun (x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {})
|
||||
|
||||
@@ -27,20 +27,20 @@ interface Foo {
|
||||
// CR on property with to receivers are forbidden
|
||||
fun <T: Foo> test() {
|
||||
// with LHS and property
|
||||
bar8<T>(<!TYPE_MISMATCH, TYPE_MISMATCH!>Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x1<!><!>)
|
||||
bar8<T>(<!TYPE_MISMATCH!>Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x1<!><!>)
|
||||
bar8<Foo>(Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x1<!>)
|
||||
bar8(Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x1<!>)
|
||||
|
||||
// with LHS and mutable property
|
||||
bar8<T>(<!TYPE_MISMATCH, TYPE_MISMATCH!>Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x2<!><!>)
|
||||
bar8<T>(<!TYPE_MISMATCH!>Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x2<!><!>)
|
||||
bar8<Foo>(Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x2<!>)
|
||||
bar8(Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x2<!>)
|
||||
|
||||
// with LHS and propery + mutable property (mixed)
|
||||
bar8<T>(<!TYPE_MISMATCH, TYPE_MISMATCH!>Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x3<!><!>)
|
||||
bar8<T>(<!TYPE_MISMATCH!>Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x3<!><!>)
|
||||
bar8<Foo>(Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x3<!>)
|
||||
bar8(Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x3<!>)
|
||||
bar9<T>(<!TYPE_MISMATCH, TYPE_MISMATCH!>Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x3<!><!>)
|
||||
bar9<T>(<!TYPE_MISMATCH!>Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x3<!><!>)
|
||||
bar9<Foo>(Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x3<!>)
|
||||
bar9(Foo::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x3<!>)
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: Simple.java
|
||||
// FULL_JDK
|
||||
// WITH_RUNTIME
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -CAST_NEVER_SUCCEEDS -UNUSED_VARIABLE
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Simple<K, V, C extends E, E extends Collection<V>> {
|
||||
public Simple(Map<K, C> backingMap, Supplier<? extends C> innerCollectionCreator) {
|
||||
// TODO
|
||||
}
|
||||
public final void add(K key, V value) {
|
||||
//TODO
|
||||
}
|
||||
public static class ListSimple<K, V> extends Simple<K, V, List<V>, List<V>> {
|
||||
public ListSimple(Map<K, List<V>> backingMap, Supplier<? extends List<V>> innerCollectionCreator) {
|
||||
super(backingMap, innerCollectionCreator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
import java.util.*
|
||||
|
||||
fun <K, V, C : E, E : Collection<V>, B: Simple<K, V, C, E>> Iterable<V>.groupByTo(destination: B, keySelector: (V) -> K) = null as B
|
||||
|
||||
enum class Format { Foo, Bar }
|
||||
|
||||
class Instance(val format: Format)
|
||||
|
||||
fun main(x: List<Instance>) {
|
||||
val doesntWork = x.groupByTo(
|
||||
Simple.ListSimple(EnumMap<Format, List<Instance>>(Format::class.java), ::LinkedList)
|
||||
) { it.format } // Internal Error occurred while analyzing this expression
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ x: kotlin.collections.List<Instance>): kotlin.Unit
|
||||
public fun </*0*/ K, /*1*/ V, /*2*/ C : E, /*3*/ E : kotlin.collections.Collection<V>, /*4*/ B : Simple<K, V, C, E>> kotlin.collections.Iterable<V>.groupByTo(/*0*/ destination: B, /*1*/ keySelector: (V) -> K): B
|
||||
|
||||
public final enum class Format : kotlin.Enum<Format> {
|
||||
enum entry Foo
|
||||
|
||||
enum entry Bar
|
||||
|
||||
private constructor Format()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Format): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<Format!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Format
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<Format>
|
||||
}
|
||||
|
||||
public final class Instance {
|
||||
public constructor Instance(/*0*/ format: Format)
|
||||
public final val format: Format
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class Simple</*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!, /*2*/ C : E!, /*3*/ E : kotlin.collections.(Mutable)Collection<V!>!> {
|
||||
public constructor Simple</*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!, /*2*/ C : E!, /*3*/ E : kotlin.collections.(Mutable)Collection<V!>!>(/*0*/ backingMap: kotlin.collections.(Mutable)Map<K!, C!>!, /*1*/ innerCollectionCreator: java.util.function.Supplier<out C!>!)
|
||||
public final fun add(/*0*/ key: K!, /*1*/ value: V!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public open class ListSimple</*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!> : Simple<K!, V!, kotlin.collections.(Mutable)List<V!>!, kotlin.collections.(Mutable)List<V!>!> {
|
||||
public constructor ListSimple</*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!>(/*0*/ backingMap: kotlin.collections.(Mutable)Map<K!, kotlin.collections.(Mutable)List<V!>!>!, /*1*/ innerCollectionCreator: java.util.function.Supplier<out kotlin.collections.(Mutable)List<V!>!>!)
|
||||
public final override /*1*/ /*fake_override*/ fun add(/*0*/ key: K!, /*1*/ value: V!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// FIR_IDENTICAL
|
||||
|
||||
sealed class Tree<TIndex, out TCommon, out TInner, out TLeaf> {
|
||||
abstract val value: TCommon
|
||||
abstract val children: Map<TIndex, Tree<TIndex, TCommon, TInner, TLeaf>>
|
||||
|
||||
data class Inner<TIndex, TCommon, TInner, TLeaf>(
|
||||
override val value: TCommon,
|
||||
val innerValue: TInner,
|
||||
override val children: Map<TIndex, Tree<TIndex, TCommon, TInner, TLeaf>>
|
||||
) : Tree<TIndex, TCommon, TInner, TLeaf>()
|
||||
|
||||
data class Leaf<TIndex, TCommon, TLeaf>(
|
||||
override val value: TCommon,
|
||||
val leafValue: TLeaf
|
||||
) : Tree<TIndex, TCommon, Nothing, TLeaf>() {
|
||||
override val children: Map<TIndex, Tree<TIndex, TCommon, Nothing, TLeaf>> get() = emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
val tree = Tree.Inner(
|
||||
"root",
|
||||
Unit,
|
||||
mapOf(
|
||||
1 to Tree.Leaf("1", 1),
|
||||
2 to Tree.Inner(
|
||||
"2",
|
||||
Unit,
|
||||
mapOf(
|
||||
1 to Tree.Leaf("21", 2),
|
||||
2 to Tree.Inner(
|
||||
"22",
|
||||
Unit,
|
||||
mapOf(1 to Tree.Leaf("221", 3))
|
||||
),
|
||||
3 to Tree.Leaf("23", 4)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package
|
||||
|
||||
public val tree: Tree.Inner<kotlin.Int, kotlin.String, kotlin.Unit, kotlin.Int>
|
||||
|
||||
public sealed class Tree</*0*/ TIndex, /*1*/ out TCommon, /*2*/ out TInner, /*3*/ out TLeaf> {
|
||||
private constructor Tree</*0*/ TIndex, /*1*/ out TCommon, /*2*/ out TInner, /*3*/ out TLeaf>()
|
||||
public abstract val children: kotlin.collections.Map<TIndex, Tree<TIndex, TCommon, TInner, TLeaf>>
|
||||
public abstract val value: TCommon
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public final data class Inner</*0*/ TIndex, /*1*/ TCommon, /*2*/ TInner, /*3*/ TLeaf> : Tree<TIndex, TCommon, TInner, TLeaf> {
|
||||
public constructor Inner</*0*/ TIndex, /*1*/ TCommon, /*2*/ TInner, /*3*/ TLeaf>(/*0*/ value: TCommon, /*1*/ innerValue: TInner, /*2*/ children: kotlin.collections.Map<TIndex, Tree<TIndex, TCommon, TInner, TLeaf>>)
|
||||
public open override /*1*/ val children: kotlin.collections.Map<TIndex, Tree<TIndex, TCommon, TInner, TLeaf>>
|
||||
public final val innerValue: TInner
|
||||
public open override /*1*/ val value: TCommon
|
||||
public final operator /*synthesized*/ fun component1(): TCommon
|
||||
public final operator /*synthesized*/ fun component2(): TInner
|
||||
public final operator /*synthesized*/ fun component3(): kotlin.collections.Map<TIndex, Tree<TIndex, TCommon, TInner, TLeaf>>
|
||||
public final /*synthesized*/ fun copy(/*0*/ value: TCommon = ..., /*1*/ innerValue: TInner = ..., /*2*/ children: kotlin.collections.Map<TIndex, Tree<TIndex, TCommon, TInner, TLeaf>> = ...): Tree.Inner<TIndex, TCommon, TInner, TLeaf>
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final data class Leaf</*0*/ TIndex, /*1*/ TCommon, /*2*/ TLeaf> : Tree<TIndex, TCommon, kotlin.Nothing, TLeaf> {
|
||||
public constructor Leaf</*0*/ TIndex, /*1*/ TCommon, /*2*/ TLeaf>(/*0*/ value: TCommon, /*1*/ leafValue: TLeaf)
|
||||
public open override /*1*/ val children: kotlin.collections.Map<TIndex, Tree<TIndex, TCommon, kotlin.Nothing, TLeaf>>
|
||||
public final val leafValue: TLeaf
|
||||
public open override /*1*/ val value: TCommon
|
||||
public final operator /*synthesized*/ fun component1(): TCommon
|
||||
public final operator /*synthesized*/ fun component2(): TLeaf
|
||||
public final /*synthesized*/ fun copy(/*0*/ value: TCommon = ..., /*1*/ leafValue: TLeaf = ...): Tree.Leaf<TIndex, TCommon, TLeaf>
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -29,7 +29,7 @@ fun case_3(a: Any) {
|
||||
// TESTCASE NUMBER: 4
|
||||
open class TypeToken<T>
|
||||
|
||||
val case_4 = object : TypeToken<@<!OI;DEBUG_INFO_MISSING_UNRESOLVED!>Ann<!>(10) String>() {}
|
||||
val case_4 = object : TypeToken<@<!DEBUG_INFO_MISSING_UNRESOLVED!>Ann<!>(10) String>() {}
|
||||
|
||||
// TESTCASE NUMBER: 5
|
||||
fun case_5(a: Any) {
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ annotation class Ann
|
||||
*/
|
||||
open class TypeToken<T>
|
||||
|
||||
val case_1 = object : TypeToken<@<!OI;DEBUG_INFO_MISSING_UNRESOLVED!>Ann<!>(<!DEBUG_INFO_MISSING_UNRESOLVED!>unresolved_reference<!>) String>() {}
|
||||
val case_1 = object : TypeToken<@<!DEBUG_INFO_MISSING_UNRESOLVED!>Ann<!>(<!DEBUG_INFO_MISSING_UNRESOLVED!>unresolved_reference<!>) String>() {}
|
||||
|
||||
/*
|
||||
* TESTCASE NUMBER: 2
|
||||
|
||||
+23
@@ -3173,6 +3173,29 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AddEqualityConstraintsWithoutSubtyping extends AbstractDiagnosticsTestWithStdLib {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAddEqualityConstraintsWithoutSubtyping() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt41741.kt")
|
||||
public void testKt41741() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping/kt41741.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42195.kt")
|
||||
public void testKt42195() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping/kt42195.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+23
@@ -3173,6 +3173,29 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AddEqualityConstraintsWithoutSubtyping extends AbstractDiagnosticsTestWithStdLibUsingJavac {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAddEqualityConstraintsWithoutSubtyping() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt41741.kt")
|
||||
public void testKt41741() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping/kt41741.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42195.kt")
|
||||
public void testKt42195() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping/kt42195.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+14
-14
@@ -18,46 +18,46 @@ class Test1<T>()
|
||||
where
|
||||
T : A,
|
||||
T : B,
|
||||
<error>B</error> : T // error
|
||||
<error descr="[NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER] B does not refer to a type parameter of Test1">B</error> : T // error
|
||||
{
|
||||
|
||||
fun test(t : T) {
|
||||
<error>T</error>.<error>foo</error>()
|
||||
<error>T</error>.<error>bar</error>()
|
||||
<error descr="[TYPE_PARAMETER_ON_LHS_OF_DOT] Type parameter 'T' cannot have or inherit a companion object, so it cannot be on the left hand side of dot">T</error>.<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: foo">foo</error>()
|
||||
<error descr="[TYPE_PARAMETER_ON_LHS_OF_DOT] Type parameter 'T' cannot have or inherit a companion object, so it cannot be on the left hand side of dot">T</error>.<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: bar">bar</error>()
|
||||
t.foo()
|
||||
t.bar()
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
Test1<<error>B</error>>()
|
||||
Test1<<error>A</error>>()
|
||||
Test1<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">B</error>>()
|
||||
Test1<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'B'">A</error>>()
|
||||
Test1<C>()
|
||||
}
|
||||
|
||||
class Foo() {}
|
||||
|
||||
class Bar<T : <warning>Foo</warning>>
|
||||
class Bar<T : <warning descr="[FINAL_UPPER_BOUND] 'Foo' is a final type, and thus a value of the type parameter is predetermined">Foo</warning>>
|
||||
|
||||
class Buzz<T> where T : <warning>Bar<<error>Int</error>></warning>, T : <error>nioho</error>
|
||||
class Buzz<T> where T : <warning descr="[FINAL_UPPER_BOUND] 'Bar<Int>' is a final type, and thus a value of the type parameter is predetermined">Bar<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'Foo'">Int</error>></warning>, T : <error descr="[UNRESOLVED_REFERENCE] Unresolved reference: nioho">nioho</error>
|
||||
|
||||
class X<T : <warning>Foo</warning>>
|
||||
class Y<<error>T</error>> where T : <warning>Foo</warning>, T : <error>Bar<Foo></error>
|
||||
class X<T : <warning descr="[FINAL_UPPER_BOUND] 'Foo' is a final type, and thus a value of the type parameter is predetermined">Foo</warning>>
|
||||
class Y<<error descr="[CONFLICTING_UPPER_BOUNDS] Upper bounds of T have empty intersection">T</error>> where T : <warning descr="[FINAL_UPPER_BOUND] 'Foo' is a final type, and thus a value of the type parameter is predetermined">Foo</warning>, T : <error descr="[ONLY_ONE_CLASS_BOUND_ALLOWED] Only one of the upper bounds can be a class">Bar<Foo></error>
|
||||
|
||||
fun <T> test2(t : T)
|
||||
where
|
||||
T : A,
|
||||
T : B,
|
||||
<error>B</error> : T
|
||||
<error descr="[NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER] B does not refer to a type parameter of test2">B</error> : T
|
||||
{
|
||||
<error>T</error>.<error>foo</error>()
|
||||
<error>T</error>.<error>bar</error>()
|
||||
<error descr="[TYPE_PARAMETER_ON_LHS_OF_DOT] Type parameter 'T' cannot have or inherit a companion object, so it cannot be on the left hand side of dot">T</error>.<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: foo">foo</error>()
|
||||
<error descr="[TYPE_PARAMETER_ON_LHS_OF_DOT] Type parameter 'T' cannot have or inherit a companion object, so it cannot be on the left hand side of dot">T</error>.<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: bar">bar</error>()
|
||||
t.foo()
|
||||
t.bar()
|
||||
}
|
||||
|
||||
val t1 = test2<<error>A</error>>(A())
|
||||
val t2 = test2<<error>B</error>>(C())
|
||||
val t1 = test2<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'B'">A</error>>(<error descr="[TYPE_MISMATCH] Type mismatch: inferred type is A but B was expected">A()</error>)
|
||||
val t2 = test2<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">B</error>>(C())
|
||||
val t3 = test2<C>(C())
|
||||
|
||||
val <T, B: T> Pair<T, B>.x : Int get() = 0
|
||||
|
||||
Reference in New Issue
Block a user