Added captured types and approximation

CapturedType captures type projection while solving the constraint system.
During the substitution type containing captured types is approximated
to get rid of captured types and (for simple cases) replace them with corresponding type projections.

Note that Array<Array< CapturedType(out Int) >> is (over)approximated by Array<out<Array<out Int>>

See 'Mixed-site variance' by Ross Tate for details.

 #KT-2570 Fixed
 #KT-2872 Fixed
 #KT-3213 Fixed
This commit is contained in:
Svetlana Isakova
2014-09-23 15:29:47 +04:00
parent e798b7c6d1
commit cd359a046c
36 changed files with 798 additions and 114 deletions
@@ -47,7 +47,7 @@ public class ConstraintsUtil {
Collection<JetType> conflictingTypes = constraintSystem.getTypeBounds(firstConflictingParameter).getValues(); Collection<JetType> conflictingTypes = constraintSystem.getTypeBounds(firstConflictingParameter).getValues();
ArrayList<Map<TypeConstructor, TypeProjection>> substitutionContexts = Lists.newArrayList(); List<Map<TypeConstructor, TypeProjection>> substitutionContexts = Lists.newArrayList();
for (JetType type : conflictingTypes) { for (JetType type : conflictingTypes) {
Map<TypeConstructor, TypeProjection> context = Maps.newLinkedHashMap(); Map<TypeConstructor, TypeProjection> context = Maps.newLinkedHashMap();
context.put(firstConflictingParameter.getTypeConstructor(), new TypeProjectionImpl(type)); context.put(firstConflictingParameter.getTypeConstructor(), new TypeProjectionImpl(type));
@@ -226,6 +226,9 @@ public abstract class AbstractTracingStrategy implements TracingStrategy {
assert !noExpectedType(data.expectedType) : "Expected type doesn't exist, but there is an expected type mismatch error"; assert !noExpectedType(data.expectedType) : "Expected type doesn't exist, but there is an expected type mismatch error";
trace.report(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH.on(reference, data.expectedType, substitutedReturnType)); trace.report(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH.on(reference, data.expectedType, substitutedReturnType));
} }
//else if (status.hasConflictWithCapturedType()) {
// trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(reference, data));
//}
else if (status.hasViolatedUpperBound()) { else if (status.hasViolatedUpperBound()) {
trace.report(TYPE_INFERENCE_UPPER_BOUND_VIOLATED.on(reference, data)); trace.report(TYPE_INFERENCE_UPPER_BOUND_VIOLATED.on(reference, data));
} }
@@ -0,0 +1,11 @@
class Contr<in T>
fun foo<T>(a: Contr<T>) {}
// T captures 'in Int'
// lower: Contr<Any?>
// upper: Contr<Int>
// T captures 'out Int'
// lower: Contr<Int>
// upper: Contr<out Any?>
@@ -0,0 +1,11 @@
class Cov<out T>
fun foo<T>(a: Cov<T>) {}
// T captures 'in Int'
// lower: Cov<Int>
// upper: Cov<Any?>
// T captures 'out Int'
// lower: Cov<Nothing>
// upper: Cov<Int>
@@ -0,0 +1,11 @@
class Inv<T>
fun foo<T>(a: Inv<T>) {}
// T captures 'in Int'
// lower: Nothing
// upper: Inv<in Int>
// T captures 'out Int'
// lower: Nothing
// upper: Inv<out Int>
@@ -0,0 +1,12 @@
class Cov<out T>
class Inv<T>
fun foo<T>(a: Cov<Inv<T>>) {}
// T captures 'in Int'
// lower: Cov<Nothing>
// upper: Cov<Inv<in Int>>
// T captures 'out Int'
// lower: Cov<Nothing>
// upper: Cov<Inv<out Int>>
@@ -0,0 +1,11 @@
class Inv<T>
fun foo<T>(a: Inv<Inv<T>>) {}
// T captures 'in Int'
// lower: Nothing
// upper: Inv<out Inv<in Int>>
// T captures 'out Int'
// lower: Nothing
// upper: Inv<out Inv<out Int>>
@@ -0,0 +1,11 @@
class Inv<T>
fun foo<T>(a: Inv<Inv<Inv<T>>>) {}
// T captures 'in Int'
// lower: Nothing
// upper: Inv<out Inv<out Inv<in Int>>>
// T captures 'out Int'
// lower: Nothing
// upper: Inv<out Inv<out Inv<out Int>>>
@@ -0,0 +1,11 @@
class Inv<T>
fun foo<T>(a: Inv<in T>) {}
// T captures 'in Int'
// lower: Inv<Any?>
// upper: Inv<in Int>
// T captures 'out Int'
// lower: Inv<in Int>
// upper: Inv<out Any?>
@@ -0,0 +1,11 @@
class Inv<T>
fun foo<T>(a: Inv<out T>) {}
// T captures 'in Int'
// lower: Inv<out Int>
// upper: Inv<out Any?>
// T captures 'out Int'
// lower: Inv<Nothing>
// upper: Inv<out Int>
@@ -14280,15 +14280,15 @@ package java {
private final inner class EntryIterator : java.util.HashMap.HashIterator<kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!> { private final inner class EntryIterator : java.util.HashMap.HashIterator<kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!> {
private constructor EntryIterator() private constructor EntryIterator()
public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>! public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -14342,15 +14342,15 @@ package java {
private final inner class KeyIterator : java.util.HashMap.HashIterator<K!> { private final inner class KeyIterator : java.util.HashMap.HashIterator<K!> {
private constructor KeyIterator() private constructor KeyIterator()
public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -14377,15 +14377,15 @@ package java {
private final inner class ValueIterator : java.util.HashMap.HashIterator<V!> { private final inner class ValueIterator : java.util.HashMap.HashIterator<V!> {
private constructor ValueIterator() private constructor ValueIterator()
public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): V! public open override /*1*/ fun next(): V!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -15376,14 +15376,14 @@ package java {
public/*package*/ final inner class DescendingKeyIterator : java.util.TreeMap.PrivateEntryIterator<K!> { public/*package*/ final inner class DescendingKeyIterator : java.util.TreeMap.PrivateEntryIterator<K!> {
public/*package*/ constructor DescendingKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor DescendingKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -15510,14 +15510,14 @@ package java {
public/*package*/ final inner class EntryIterator : java.util.TreeMap.PrivateEntryIterator<kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!> { public/*package*/ final inner class EntryIterator : java.util.TreeMap.PrivateEntryIterator<kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!> {
public/*package*/ constructor EntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor EntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>! public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -15545,14 +15545,14 @@ package java {
public/*package*/ final inner class KeyIterator : java.util.TreeMap.PrivateEntryIterator<K!> { public/*package*/ final inner class KeyIterator : java.util.TreeMap.PrivateEntryIterator<K!> {
public/*package*/ constructor KeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor KeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -15670,14 +15670,14 @@ package java {
public/*package*/ constructor DescendingSubMapEntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor DescendingSubMapEntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any! public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any!
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>! public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ fun remove(): kotlin.Unit public open override /*1*/ fun remove(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit
@@ -15688,14 +15688,14 @@ package java {
public/*package*/ constructor DescendingSubMapKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor DescendingSubMapKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any! public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any!
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ fun remove(): kotlin.Unit public open override /*1*/ fun remove(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit
@@ -15728,14 +15728,14 @@ package java {
public/*package*/ constructor SubMapEntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor SubMapEntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any! public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any!
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>! public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ fun remove(): kotlin.Unit public open override /*1*/ fun remove(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit
@@ -15764,14 +15764,14 @@ package java {
public/*package*/ constructor SubMapKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor SubMapKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any! public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any!
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ fun remove(): kotlin.Unit public open override /*1*/ fun remove(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit
@@ -15833,14 +15833,14 @@ package java {
public/*package*/ final inner class ValueIterator : java.util.TreeMap.PrivateEntryIterator<V!> { public/*package*/ final inner class ValueIterator : java.util.TreeMap.PrivateEntryIterator<V!> {
public/*package*/ constructor ValueIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor ValueIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): V! public open override /*1*/ fun next(): V!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -0,0 +1,29 @@
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_VARIABLE
// FILE: A.java
public class A {
public static <T> Class<T> foo(Class<T> clazz) {
return clazz;
}
public static <T> Class<Class<T>> bar(Class<T> clazz) {
throw new Exception();
}
}
// FILE: b.kt
fun test1(clazz: Class<out Int>) {
val foo0: Class<out Int> = A.foo(clazz)
val foo1 = A.foo(clazz)
foo1 checkType { it: _< Class<out Int> > }
// should be ok
foo1 checkType { <!TYPE_MISMATCH!>it<!>: _< Class<out Int?> > }
}
fun tes2t(clazz: Class<in Int>) {
val foo0: Class<out Class<in Int>> = A.bar(clazz)
val foo1 = A.bar(clazz)
foo1 checkType { it: _< Class<out Class<in Int>> > }
// should be ok
foo1 checkType { <!TYPE_MISMATCH!>it<!>: _< Class<out Class<in Int?>> > }
}
@@ -0,0 +1,15 @@
package
internal fun tes2t(/*0*/ clazz: java.lang.Class<in kotlin.Int>): kotlin.Unit
internal fun test1(/*0*/ clazz: java.lang.Class<out kotlin.Int>): kotlin.Unit
public open class A {
public constructor A()
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
// Static members
public open fun </*0*/ T> bar(/*0*/ clazz: java.lang.Class<T!>!): java.lang.Class<java.lang.Class<T!>!>!
public open fun </*0*/ T> foo(/*0*/ clazz: java.lang.Class<T!>!): java.lang.Class<T!>!
}
@@ -0,0 +1,16 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// !CHECK_TYPE
fun <T> foo(array: Array<T>): Array<T> = array
fun test1(a1: Array<out Int>) {
val b1: Array<out Int> = foo(a1)
val c1 = foo(a1)
c1 checkType { it : _<Array<out Int>> }
}
fun test2(a2: Array<in Int>) {
val b2: Array<in Int> = foo(a2)
val c2 = foo(a2)
c2 checkType { it : _<Array<in Int>> }
}
@@ -0,0 +1,5 @@
package
internal fun </*0*/ T> foo(/*0*/ array: kotlin.Array<T>): kotlin.Array<T>
internal fun test1(/*0*/ a1: kotlin.Array<out kotlin.Int>): kotlin.Unit
internal fun test2(/*0*/ a2: kotlin.Array<in kotlin.Int>): kotlin.Unit
@@ -0,0 +1,16 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// !CHECK_TYPE
fun <T> foo(a: Array<T>): Array<Array<T>> = throw Exception()
fun test1(a1: Array<out Int>) {
val b1: Array<out Array<out Int>> = foo(a1)
val c1 = foo(a1)
c1 checkType { it : _<Array<out Array<out Int>>> }
}
fun test2(a2: Array<in Int>) {
val b2: Array<out Array<in Int>> = foo(a2)
val c2 = foo(a2)
c2 checkType { it : _<Array<out Array<in Int>>> }
}
@@ -0,0 +1,5 @@
package
internal fun </*0*/ T> foo(/*0*/ a: kotlin.Array<T>): kotlin.Array<kotlin.Array<T>>
internal fun test1(/*0*/ a1: kotlin.Array<out kotlin.Int>): kotlin.Unit
internal fun test2(/*0*/ a2: kotlin.Array<in kotlin.Int>): kotlin.Unit
@@ -0,0 +1,9 @@
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_VARIABLE
fun <T> foo(l: MutableList<T>): MutableList<T> = l
fun test(l: MutableList<out Int>) {
val a: MutableList<out Int> = foo(l)
val b = foo(l)
b checkType { it: _< MutableList<out Int> > }
}
@@ -0,0 +1,4 @@
package
internal fun </*0*/ T> foo(/*0*/ l: kotlin.MutableList<T>): kotlin.MutableList<T>
internal fun test(/*0*/ l: kotlin.MutableList<out kotlin.Int>): kotlin.Unit
@@ -0,0 +1,6 @@
fun <T> Array<T>.foo() {}
fun test(array: Array<out Int>) {
array.foo()
<!TYPE_MISMATCH!>array<!>.foo<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>out<!> Int>()
}
@@ -0,0 +1,4 @@
package
internal fun test(/*0*/ array: kotlin.Array<out kotlin.Int>): kotlin.Unit
internal fun </*0*/ T> kotlin.Array<T>.foo(): kotlin.Unit
@@ -14286,15 +14286,15 @@ package java {
private final inner class EntryIterator : java.util.HashMap.HashIterator<kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!> { private final inner class EntryIterator : java.util.HashMap.HashIterator<kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!> {
private constructor EntryIterator() private constructor EntryIterator()
public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>! public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -14348,15 +14348,15 @@ package java {
private final inner class KeyIterator : java.util.HashMap.HashIterator<K!> { private final inner class KeyIterator : java.util.HashMap.HashIterator<K!> {
private constructor KeyIterator() private constructor KeyIterator()
public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -14383,15 +14383,15 @@ package java {
private final inner class ValueIterator : java.util.HashMap.HashIterator<V!> { private final inner class ValueIterator : java.util.HashMap.HashIterator<V!> {
private constructor ValueIterator() private constructor ValueIterator()
public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var current: java.util.HashMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var index: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): V! public open override /*1*/ fun next(): V!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.HashMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -15382,14 +15382,14 @@ package java {
public/*package*/ final inner class DescendingKeyIterator : java.util.TreeMap.PrivateEntryIterator<K!> { public/*package*/ final inner class DescendingKeyIterator : java.util.TreeMap.PrivateEntryIterator<K!> {
public/*package*/ constructor DescendingKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor DescendingKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -15516,14 +15516,14 @@ package java {
public/*package*/ final inner class EntryIterator : java.util.TreeMap.PrivateEntryIterator<kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!> { public/*package*/ final inner class EntryIterator : java.util.TreeMap.PrivateEntryIterator<kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!> {
public/*package*/ constructor EntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor EntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>! public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -15551,14 +15551,14 @@ package java {
public/*package*/ final inner class KeyIterator : java.util.TreeMap.PrivateEntryIterator<K!> { public/*package*/ final inner class KeyIterator : java.util.TreeMap.PrivateEntryIterator<K!> {
public/*package*/ constructor KeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor KeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -15676,14 +15676,14 @@ package java {
public/*package*/ constructor DescendingSubMapEntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor DescendingSubMapEntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any! public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any!
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>! public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ fun remove(): kotlin.Unit public open override /*1*/ fun remove(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit
@@ -15694,14 +15694,14 @@ package java {
public/*package*/ constructor DescendingSubMapKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor DescendingSubMapKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any! public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any!
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ fun remove(): kotlin.Unit public open override /*1*/ fun remove(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit
@@ -15734,14 +15734,14 @@ package java {
public/*package*/ constructor SubMapEntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor SubMapEntryIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any! public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any!
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>! public open override /*1*/ fun next(): kotlin.(Mutable)Map.(Mutable)Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ fun remove(): kotlin.Unit public open override /*1*/ fun remove(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit
@@ -15770,14 +15770,14 @@ package java {
public/*package*/ constructor SubMapKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor SubMapKeyIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!, /*1*/ p1: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any! public/*package*/ final override /*1*/ /*fake_override*/ val fenceKey: kotlin.Any!
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): K! public open override /*1*/ fun next(): K!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ fun remove(): kotlin.Unit public open override /*1*/ fun remove(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeAscending(): kotlin.Unit
public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit public/*package*/ final override /*1*/ /*fake_override*/ fun removeDescending(): kotlin.Unit
@@ -15839,14 +15839,14 @@ package java {
public/*package*/ final inner class ValueIterator : java.util.TreeMap.PrivateEntryIterator<V!> { public/*package*/ final inner class ValueIterator : java.util.TreeMap.PrivateEntryIterator<V!> {
public/*package*/ constructor ValueIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!) public/*package*/ constructor ValueIterator(/*0*/ p0: java.util.TreeMap.Entry<K!, V!>!)
public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int public/*package*/ final override /*1*/ /*fake_override*/ var expectedModCount: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var lastReturned: java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ var next: java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean public final override /*1*/ /*fake_override*/ fun hasNext(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun next(): V! public open override /*1*/ fun next(): V!
public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun nextEntry(): java.util.TreeMap.Entry<K!, V!>!
public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K, V>! public/*package*/ final override /*1*/ /*fake_override*/ fun prevEntry(): java.util.TreeMap.Entry<K!, V!>!
public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun remove(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -4899,7 +4899,7 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
@TestMetadata("compiler/testData/diagnostics/tests/inference") @TestMetadata("compiler/testData/diagnostics/tests/inference")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({Inference.Constraints.class, Inference.NestedCalls.class, Inference.Regressions.class, Inference.ReportingImprovements.class, Inference.Substitutions.class, Inference.UpperBounds.class, Inference.Varargs.class}) @InnerTestClasses({Inference.CapturedTypes.class, Inference.Constraints.class, Inference.NestedCalls.class, Inference.Regressions.class, Inference.ReportingImprovements.class, Inference.Substitutions.class, Inference.UpperBounds.class, Inference.Varargs.class})
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
public static class Inference extends AbstractJetDiagnosticsTest { public static class Inference extends AbstractJetDiagnosticsTest {
public void testAllFilesPresentInInference() throws Exception { public void testAllFilesPresentInInference() throws Exception {
@@ -5086,6 +5086,45 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class CapturedTypes extends AbstractJetDiagnosticsTest {
public void testAllFilesPresentInCapturedTypes() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/capturedTypes"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("captureForPlatformTypes.kt")
public void testCaptureForPlatformTypes() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/captureForPlatformTypes.kt");
doTest(fileName);
}
@TestMetadata("capturedType.kt")
public void testCapturedType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedType.kt");
doTest(fileName);
}
@TestMetadata("capturedTypeAndApproximation.kt")
public void testCapturedTypeAndApproximation() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeAndApproximation.kt");
doTest(fileName);
}
@TestMetadata("kt2570.kt")
public void testKt2570() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/kt2570.kt");
doTest(fileName);
}
@TestMetadata("kt2872.kt")
public void testKt2872() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/kt2872.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/diagnostics/tests/inference/constraints") @TestMetadata("compiler/testData/diagnostics/tests/inference/constraints")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -0,0 +1,75 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.resolve.typeApproximation
import org.jetbrains.jet.JetLiteFixture
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment
import org.jetbrains.jet.ConfigurationKind
import java.io.File
import org.jetbrains.jet.lang.resolve.lazy.JvmResolveUtil
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
import org.jetbrains.jet.lang.types.TypeSubstitutor
import org.jetbrains.jet.lang.types.TypeProjectionImpl
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.types.Variance
import org.jetbrains.jet.lang.types.typesApproximation.approximateCapturedTypes
import org.jetbrains.jet.JetTestUtils
import org.jetbrains.jet.lang.psi.JetPsiFactory
import org.jetbrains.jet.lang.resolve.calls.inference.CapturedTypeConstructor
import org.jetbrains.jet.lang.types.JetTypeImpl
import org.jetbrains.jet.lang.resolve.calls.inference.createCapturedType
abstract public class AbstractCapturedTypeApproximationTest() : JetLiteFixture() {
override fun createEnvironment(): JetCoreEnvironment = createEnvironmentWithMockJdk(ConfigurationKind.ALL)
public fun doTest(filePath: String) {
val file = File(filePath)
val text = JetTestUtils.doLoadFile(file)!!
val jetFile = JetPsiFactory(getProject()).createFile(text)
val bindingContext = JvmResolveUtil.analyzeOneFileWithJavaIntegration(jetFile).bindingContext
val functions = bindingContext.getSliceContents(BindingContext.FUNCTION)
val functionFoo = functions.values().firstOrNull { it.getName().asString() == "foo" } ?:
throw AssertionError("Function 'foo' is not declared")
val typeParameter = functionFoo.getTypeParameters().first()
val parameter = functionFoo.getValueParameters().first().getType()
val result = StringBuilder {
val endIndex = text.indexOf("// T captures")
appendln(if (endIndex == -1) text else text.substring(0, endIndex).trimTrailing())
for (variance in listOf(Variance.IN_VARIANCE, Variance.OUT_VARIANCE)) {
val captured = createCapturedType(TypeProjectionImpl(variance, KotlinBuiltIns.getInstance().getIntType()))
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter.getTypeConstructor() to TypeProjectionImpl(captured)))
val typeWithCapturedType = typeSubstitutor.substituteWithoutApproximation(
TypeProjectionImpl(Variance.INVARIANT, parameter))!!.getType()
val (lower, upper) = approximateCapturedTypes(typeWithCapturedType)
appendln()
appendln("// T captures '${(captured.getConstructor() as CapturedTypeConstructor).typeProjection}'")
appendln("// lower: $lower")
appendln("// upper: $upper")
}
}.toString()
JetTestUtils.assertEqualsToFile(file, result)
}
}
@@ -0,0 +1,86 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.resolve.typeApproximation;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.jet.JUnit3RunnerWithInners;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.test.InnerTestClasses;
import org.jetbrains.jet.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/capturedTypeApproximation")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class CapturedTypeApproximationTestGenerated extends AbstractCapturedTypeApproximationTest {
public void testAllFilesPresentInCapturedTypeApproximation() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/capturedTypeApproximation"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("contravariant.kt")
public void testContravariant() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/capturedTypeApproximation/contravariant.kt");
doTest(fileName);
}
@TestMetadata("covariant.kt")
public void testCovariant() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/capturedTypeApproximation/covariant.kt");
doTest(fileName);
}
@TestMetadata("invariant.kt")
public void testInvariant() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/capturedTypeApproximation/invariant.kt");
doTest(fileName);
}
@TestMetadata("nestedCov.kt")
public void testNestedCov() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/capturedTypeApproximation/nestedCov.kt");
doTest(fileName);
}
@TestMetadata("nestedInv.kt")
public void testNestedInv() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/capturedTypeApproximation/nestedInv.kt");
doTest(fileName);
}
@TestMetadata("nestedInvLevel2.kt")
public void testNestedInvLevel2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/capturedTypeApproximation/nestedInvLevel2.kt");
doTest(fileName);
}
@TestMetadata("useSiteVarianceIn.kt")
public void testUseSiteVarianceIn() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/capturedTypeApproximation/useSiteVarianceIn.kt");
doTest(fileName);
}
@TestMetadata("useSiteVarianceOut.kt")
public void testUseSiteVarianceOut() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/capturedTypeApproximation/useSiteVarianceOut.kt");
doTest(fileName);
}
}
@@ -235,7 +235,7 @@ public class TypeSubstitutorTest extends KotlinTestWithEnvironment {
public void testOutInProjection() throws Exception { public void testOutInProjection() throws Exception {
doTest( doTest(
"C<out Any>", "C<out Any?>",
"C<out T>", "C<out T>",
map("T", "in String") map("T", "in String")
); );
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.calls.inference
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.types.TypeProjection
import org.jetbrains.jet.lang.types.TypeConstructor
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.types.Variance
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.types.JetTypeImpl
import org.jetbrains.jet.lang.types.ErrorUtils
public class CapturedTypeConstructor(
public val typeProjection: TypeProjection
): TypeConstructor {
{
assert(typeProjection.getProjectionKind() != Variance.INVARIANT) {
"Only nontrivial projections can be captured, not: $typeProjection"
}
}
override fun getParameters(): List<TypeParameterDescriptor> = listOf()
override fun getSupertypes(): Collection<JetType> {
val superType = if (typeProjection.getProjectionKind() == Variance.OUT_VARIANCE)
typeProjection.getType()
else
KotlinBuiltIns.getInstance().getNullableAnyType()
return listOf(superType)
}
override fun isFinal() = true
override fun isDenotable() = false
override fun getDeclarationDescriptor() = null
override fun getAnnotations() = Annotations.EMPTY
override fun toString() = "Captured($typeProjection)"
}
public fun createCapturedType(typeProjection: TypeProjection): JetType {
val scope = ErrorUtils.createErrorScope("No member resolution should be done on captured type, " +
"it used only during constraint system resolution", true)
return JetTypeImpl(Annotations.EMPTY, CapturedTypeConstructor(typeProjection), false, listOf(), scope)
}
public fun JetType.isCaptured(): Boolean = getConstructor() is CapturedTypeConstructor
@@ -43,6 +43,8 @@ public trait ConstraintPosition {
val kind: ConstraintPositionKind val kind: ConstraintPositionKind
fun isStrong(): Boolean = kind != TYPE_BOUND_POSITION fun isStrong(): Boolean = kind != TYPE_BOUND_POSITION
fun isCaptureAllowed(): Boolean = kind in setOf(VALUE_PARAMETER_POSITION, RECEIVER_POSITION)
} }
private open data class ConstraintPositionImpl(override val kind: ConstraintPositionKind) : ConstraintPosition { private open data class ConstraintPositionImpl(override val kind: ConstraintPositionKind) : ConstraintPosition {
@@ -53,14 +55,11 @@ private data class ConstraintPositionWithIndex(override val kind: ConstraintPosi
} }
class CompoundConstraintPosition( class CompoundConstraintPosition(
val positions: Collection<ConstraintPosition> vararg positions: ConstraintPosition
) : ConstraintPositionImpl(ConstraintPositionKind.COMPOUND_CONSTRAINT_POSITION) { ) : ConstraintPositionImpl(ConstraintPositionKind.COMPOUND_CONSTRAINT_POSITION) {
val positions: Collection<ConstraintPosition> = positions.toList()
override fun isStrong() = positions.any { it.isStrong() } override fun isStrong() = positions.any { it.isStrong() }
override fun toString() = "$kind(${positions.joinToString()}" override fun toString() = "$kind(${positions.joinToString()}"
}
public fun getCompoundConstraintPosition(vararg positions: ConstraintPosition): ConstraintPosition {
return CompoundConstraintPosition(positions.toList())
} }
@@ -41,7 +41,6 @@ import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.Constra
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.* import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.CompoundConstraintPosition import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.CompoundConstraintPosition
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.getCompoundConstraintPosition
import org.jetbrains.jet.lang.types.CustomTypeVariable import org.jetbrains.jet.lang.types.CustomTypeVariable
import org.jetbrains.jet.lang.types.getCustomTypeVariable import org.jetbrains.jet.lang.types.getCustomTypeVariable
import org.jetbrains.jet.lang.types.isFlexible import org.jetbrains.jet.lang.types.isFlexible
@@ -226,6 +225,14 @@ public class ConstraintSystemImpl : ConstraintSystem {
return true return true
} }
override fun capture(typeVariable: JetType, typeProjection: TypeProjection): Boolean {
if (isMyTypeVariable(typeVariable) && constraintPosition.isCaptureAllowed()) {
generateTypeParameterCaptureConstraint(typeVariable, typeProjection, constraintPosition)
return true
}
return false
}
override fun noCorrespondingSupertype(subtype: JetType, supertype: JetType): Boolean { override fun noCorrespondingSupertype(subtype: JetType, supertype: JetType): Boolean {
errorConstraintPositions.add(constraintPosition) errorConstraintPositions.add(constraintPosition)
return true return true
@@ -303,9 +310,16 @@ public class ConstraintSystemImpl : ConstraintSystem {
generateTypeParameterConstraint(superType, subType, boundKind, constraintPosition) generateTypeParameterConstraint(superType, subType, boundKind, constraintPosition)
return return
} }
// if superType is nullable and subType is not nullable, unsafe call error will be generated later, // if superType is nullable and subType is not nullable, unsafe call or type mismatch error will be generated later,
// but constraint system should be solved anyway // but constraint system should be solved anyway
typeCheckingProcedure.isSubtypeOf(TypeUtils.makeNotNullable(subType), TypeUtils.makeNotNullable(superType)) val subTypeNotNullable = TypeUtils.makeNotNullable(subType)
val superTypeNotNullable = TypeUtils.makeNotNullable(superType)
if (constraintKind == EQUAL) {
typeCheckingProcedure.equalTypes(subTypeNotNullable, superTypeNotNullable)
}
else {
typeCheckingProcedure.isSubtypeOf(subTypeNotNullable, superTypeNotNullable)
}
} }
simplifyConstraint(newSubType, superType) simplifyConstraint(newSubType, superType)
} }
@@ -352,6 +366,16 @@ public class ConstraintSystemImpl : ConstraintSystem {
} }
} }
private fun generateTypeParameterCaptureConstraint(
parameterType: JetType,
constrainingTypeProjection: TypeProjection,
constraintPosition: ConstraintPosition
) {
val typeBounds = getTypeBounds(parameterType)
val capturedType = createCapturedType(constrainingTypeProjection)
typeBounds.addBound(EXACT_BOUND, capturedType, constraintPosition)
}
public fun processDeclaredBoundConstraints() { public fun processDeclaredBoundConstraints() {
for ((typeParameterDescriptor, typeBounds) in typeParameterBounds) { for ((typeParameterDescriptor, typeBounds) in typeParameterBounds) {
for (declaredUpperBound in typeParameterDescriptor.getUpperBounds()) { for (declaredUpperBound in typeParameterDescriptor.getUpperBounds()) {
@@ -359,7 +383,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
val bounds = ArrayList(typeBounds.bounds) val bounds = ArrayList(typeBounds.bounds)
for (bound in bounds) { for (bound in bounds) {
if (bound.kind == LOWER_BOUND || bound.kind == EXACT_BOUND) { if (bound.kind == LOWER_BOUND || bound.kind == EXACT_BOUND) {
val position = getCompoundConstraintPosition( val position = CompoundConstraintPosition(
TYPE_BOUND_POSITION.position(typeParameterDescriptor.getIndex()), bound.position) TYPE_BOUND_POSITION.position(typeParameterDescriptor.getIndex()), bound.position)
addSubtypeConstraint(bound.constrainingType, declaredUpperBound, position) addSubtypeConstraint(bound.constrainingType, declaredUpperBound, position)
} }
@@ -368,7 +392,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
val typeBoundsForUpperBound = getTypeBounds(declaredUpperBound) val typeBoundsForUpperBound = getTypeBounds(declaredUpperBound)
for (bound in typeBoundsForUpperBound.bounds) { for (bound in typeBoundsForUpperBound.bounds) {
if (bound.kind == UPPER_BOUND || bound.kind == EXACT_BOUND) { if (bound.kind == UPPER_BOUND || bound.kind == EXACT_BOUND) {
val position = getCompoundConstraintPosition( val position = CompoundConstraintPosition(
TYPE_BOUND_POSITION.position(typeParameterDescriptor.getIndex()), bound.position) TYPE_BOUND_POSITION.position(typeParameterDescriptor.getIndex()), bound.position)
typeBounds.addBound(UPPER_BOUND, bound.constrainingType, position) typeBounds.addBound(UPPER_BOUND, bound.constrainingType, position)
} }
@@ -156,7 +156,8 @@ public class TypeBoundsImpl(
private fun tryPossibleAnswer(possibleAnswer: JetType?): Boolean { private fun tryPossibleAnswer(possibleAnswer: JetType?): Boolean {
if (possibleAnswer == null) return false if (possibleAnswer == null) return false
if (!possibleAnswer.getConstructor().isDenotable()) return false // a captured type might be an answer
if (!possibleAnswer.getConstructor().isDenotable() && !possibleAnswer.isCaptured()) return false
for (bound in bounds) { for (bound in bounds) {
when (bound.kind) { when (bound.kind) {
@@ -0,0 +1,136 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.types.typesApproximation
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
import org.jetbrains.jet.lang.types.TypeProjection
import org.jetbrains.jet.lang.types.TypeProjectionImpl
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.types.Variance
import java.util.ArrayList
import org.jetbrains.jet.lang.types.JetTypeImpl
import org.jetbrains.jet.lang.types.TypeUtils
import org.jetbrains.jet.lang.resolve.calls.inference.CapturedTypeConstructor
import org.jetbrains.jet.lang.types.TypeSubstitutor
import org.jetbrains.jet.lang.types.TypeSubstitution
import org.jetbrains.jet.lang.types.TypeConstructor
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
import org.jetbrains.jet.lang.types.LazyType
import org.jetbrains.jet.lang.resolve.calls.inference.isCaptured
public data class ApproximationBounds<T>(
public val lower: T,
public val upper: T
)
private class TypeArgument(
val typeParameter: TypeParameterDescriptor,
val inProjection: JetType,
val outProjection: JetType
) {
val isConsistent: Boolean
get() = JetTypeChecker.DEFAULT.isSubtypeOf(inProjection, outProjection)
}
private val NULLABLE_ANY = KotlinBuiltIns.getInstance().getNullableAnyType()
private val NOTHING = KotlinBuiltIns.getInstance().getNothingType()
private fun TypeArgument.toTypeProjection(): TypeProjection {
assert(isConsistent) { "Only consistent enhanced type propection can be converted to type projection" }
fun removeProjectionIfRedundant(variance: Variance) = if (variance == typeParameter.getVariance()) Variance.INVARIANT else variance
return when {
inProjection == outProjection -> TypeProjectionImpl(inProjection)
inProjection == NOTHING -> TypeProjectionImpl(removeProjectionIfRedundant(Variance.OUT_VARIANCE), outProjection)
outProjection == NULLABLE_ANY -> TypeProjectionImpl(removeProjectionIfRedundant(Variance.IN_VARIANCE), inProjection)
else -> throw AssertionError("Enhanced type projection can't be converted to type projection: $this")
}
}
private fun TypeProjection.toTypeArgument(typeParameter: TypeParameterDescriptor) =
when (TypeSubstitutor.combine(typeParameter.getVariance(), getProjectionKind()) : Variance) {
Variance.INVARIANT -> TypeArgument(typeParameter, getType(), getType())
Variance.IN_VARIANCE -> TypeArgument(typeParameter, getType(), NULLABLE_ANY)
Variance.OUT_VARIANCE -> TypeArgument(typeParameter, NOTHING, getType())
}
public fun approximateCapturedTypesIfNecessary(typeProjection: TypeProjection?): TypeProjection? {
if (typeProjection == null) return null
val type = typeProjection.getType()
if (!TypeUtils.containsSpecialType(type, { it.isCaptured() })) {
return typeProjection
}
val howThisTypeIsUsed = typeProjection.getProjectionKind()
if (howThisTypeIsUsed == Variance.OUT_VARIANCE) {
// only 'return' type containing captured types should be over-approximated
val approximation = approximateCapturedTypes(type)
return TypeProjectionImpl(howThisTypeIsUsed, approximation.upper)
}
return substituteCapturedTypes(typeProjection)
}
private fun substituteCapturedTypes(typeProjection: TypeProjection): TypeProjection? {
val typeSubstitutor = TypeSubstitutor.create(object : TypeSubstitution {
override fun get(typeConstructor: TypeConstructor?): TypeProjection? {
return (typeConstructor as? CapturedTypeConstructor)?.typeProjection
}
override fun isEmpty() = false
})
return typeSubstitutor.substituteWithoutApproximation(typeProjection)
}
public fun approximateCapturedTypes(type: JetType): ApproximationBounds<JetType> {
val typeConstructor = type.getConstructor()
if (type.isCaptured()) {
val typeProjection = (typeConstructor as CapturedTypeConstructor).typeProjection
return when (typeProjection.getProjectionKind()) {
Variance.IN_VARIANCE -> ApproximationBounds(typeProjection.getType(), NULLABLE_ANY)
Variance.OUT_VARIANCE -> ApproximationBounds(NOTHING, typeProjection.getType())
else -> throw AssertionError("Only nontrivial projections should have been captured, not: $typeProjection")
}
}
if (type.getArguments().isEmpty()) {
return ApproximationBounds(type, type)
}
val lowerBoundArguments = ArrayList<TypeArgument>()
val upperBoundArguments = ArrayList<TypeArgument>()
for ((typeProjection, typeParameter) in type.getArguments().zip(typeConstructor.getParameters())) {
val (lower, upper) = approximateProjection(typeProjection.toTypeArgument(typeParameter))
lowerBoundArguments.add(lower)
upperBoundArguments.add(upper)
}
val lowerBoundIsTrivial = lowerBoundArguments.any { !it.isConsistent }
return ApproximationBounds(
if (lowerBoundIsTrivial) NOTHING else type.replaceTypeArguments(lowerBoundArguments),
type.replaceTypeArguments(upperBoundArguments))
}
private fun JetType.replaceTypeArguments(newTypeArguments: List<TypeArgument>): JetType {
assert(getArguments().size() == newTypeArguments.size()) { "Incorrect type arguments $newTypeArguments" }
return JetTypeImpl(getAnnotations(), getConstructor(), isMarkedNullable(), newTypeArguments.map { it.toTypeProjection() }, getMemberScope())
}
private fun approximateProjection(typeArgument: TypeArgument): ApproximationBounds<TypeArgument> {
val (inLower, inUpper) = approximateCapturedTypes(typeArgument.inProjection)
val (outLower, outUpper) = approximateCapturedTypes(typeArgument.outProjection)
return ApproximationBounds(
lower = TypeArgument(typeArgument.typeParameter, inUpper, outLower),
upper = TypeArgument(typeArgument.typeParameter, inLower, outUpper))
}
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope; import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lang.types.typeUtil.TypeUtilPackage; import org.jetbrains.jet.lang.types.typeUtil.TypeUtilPackage;
import org.jetbrains.jet.lang.types.typesApproximation.TypesApproximationPackage;
import java.util.*; import java.util.*;
@@ -60,18 +61,22 @@ public class TypeSubstitutor {
} }
} }
@NotNull
public static TypeSubstitutor create(@NotNull TypeSubstitution substitution) { public static TypeSubstitutor create(@NotNull TypeSubstitution substitution) {
return new TypeSubstitutor(substitution); return new TypeSubstitutor(substitution);
} }
@NotNull
public static TypeSubstitutor create(@NotNull TypeSubstitution... substitutions) { public static TypeSubstitutor create(@NotNull TypeSubstitution... substitutions) {
return create(new CompositeTypeSubstitution(substitutions)); return create(new CompositeTypeSubstitution(substitutions));
} }
@NotNull
public static TypeSubstitutor create(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) { public static TypeSubstitutor create(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
return create(new MapToTypeSubstitutionAdapter(substitutionContext)); return create(new MapToTypeSubstitutionAdapter(substitutionContext));
} }
@NotNull
public static TypeSubstitutor create(@NotNull JetType context) { public static TypeSubstitutor create(@NotNull JetType context) {
return create(buildSubstitutionContext(context.getConstructor().getParameters(), context.getArguments())); return create(buildSubstitutionContext(context.getConstructor().getParameters(), context.getArguments()));
} }
@@ -135,6 +140,12 @@ public class TypeSubstitutor {
@Nullable @Nullable
public TypeProjection substitute(@NotNull TypeProjection typeProjection) { public TypeProjection substitute(@NotNull TypeProjection typeProjection) {
TypeProjection substitutedTypeProjection = substituteWithoutApproximation(typeProjection);
return TypesApproximationPackage.approximateCapturedTypesIfNecessary(substitutedTypeProjection);
}
@Nullable
public TypeProjection substituteWithoutApproximation(@NotNull TypeProjection typeProjection) {
if (isEmpty()) { if (isEmpty()) {
return typeProjection; return typeProjection;
} }
@@ -159,14 +170,15 @@ public class TypeSubstitutor {
unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibility.getLowerBound()), recursionDepth + 1); unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibility.getLowerBound()), recursionDepth + 1);
TypeProjection substitutedUpper = TypeProjection substitutedUpper =
unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibility.getUpperBound()), recursionDepth + 1); unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibility.getUpperBound()), recursionDepth + 1);
// todo: projection kind is neglected
return new TypeProjectionImpl(originalProjectionKind, Variance substitutedProjectionKind = substitutedLower.getProjectionKind();
DelegatingFlexibleType.create( assert (substitutedProjectionKind == substitutedUpper.getProjectionKind()) &&
substitutedLower.getType(), originalProjectionKind == Variance.INVARIANT || originalProjectionKind == substitutedProjectionKind :
substitutedUpper.getType(), "Unexpected substituted projection kind: " + substitutedProjectionKind + "; original: " + originalProjectionKind;
flexibility.getExtraCapabilities()
) JetType substitutedFlexibleType = DelegatingFlexibleType.create(
); substitutedLower.getType(), substitutedUpper.getType(), flexibility.getExtraCapabilities());
return new TypeProjectionImpl(substitutedProjectionKind, substitutedFlexibleType);
} }
if (KotlinBuiltIns.isNothing(type) || type.isError()) return originalProjection; if (KotlinBuiltIns.isNothing(type) || type.isError()) return originalProjection;
@@ -174,15 +186,12 @@ public class TypeSubstitutor {
TypeProjection replacement = substitution.get(type.getConstructor()); TypeProjection replacement = substitution.get(type.getConstructor());
if (replacement != null) { if (replacement != null) {
// It must be a type parameter: only they can be directly substituted for
TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor();
switch (conflictType(originalProjectionKind, replacement.getProjectionKind())) { switch (conflictType(originalProjectionKind, replacement.getProjectionKind())) {
case OUT_IN_IN_POSITION: case OUT_IN_IN_POSITION:
throw new SubstitutionException("Out-projection in in-position"); throw new SubstitutionException("Out-projection in in-position");
case IN_IN_OUT_POSITION: case IN_IN_OUT_POSITION:
//noinspection ConstantConditions // todo use the right type parameter variance and upper bound
return TypeUtils.makeStarProjection(typeParameter); return new TypeProjectionImpl(Variance.OUT_VARIANCE, KotlinBuiltIns.getInstance().getNullableAnyType());
case NO_CONFLICT: case NO_CONFLICT:
JetType substitutedType; JetType substitutedType;
CustomTypeVariable typeVariable = TypesPackage.getCustomTypeVariable(type); CustomTypeVariable typeVariable = TypesPackage.getCustomTypeVariable(type);
@@ -191,7 +200,7 @@ public class TypeSubstitutor {
} }
else { else {
// this is a simple type T or T?: if it's T, we should just take replacement, if T? - we make replacement nullable // this is a simple type T or T?: if it's T, we should just take replacement, if T? - we make replacement nullable
substitutedType = type.isMarkedNullable() ? TypeUtils.makeNullable(replacement.getType()) : replacement.getType(); substitutedType = TypeUtils.makeNullableIfNeeded(replacement.getType(), type.isMarkedNullable());
} }
Variance resultingProjectionKind = combine(originalProjectionKind, replacement.getProjectionKind()); Variance resultingProjectionKind = combine(originalProjectionKind, replacement.getProjectionKind());
@@ -201,14 +210,21 @@ public class TypeSubstitutor {
} }
} }
// The type is not within the substitution range, i.e. Foo, Bar<T> etc. // The type is not within the substitution range, i.e. Foo, Bar<T> etc.
return substituteCompoundType(type, originalProjectionKind, recursionDepth); return substituteCompoundType(originalProjection, recursionDepth);
} }
private TypeProjection substituteCompoundType( private TypeProjection substituteCompoundType(
final JetType type, TypeProjection originalProjection,
Variance projectionKind,
int recursionDepth int recursionDepth
) throws SubstitutionException { ) throws SubstitutionException {
final JetType type = originalProjection.getType();
Variance projectionKind = originalProjection.getProjectionKind();
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
// substitution can't change type parameter
// todo substitute bounds
return originalProjection;
}
List<TypeProjection> substitutedArguments = substituteTypeArguments( List<TypeProjection> substitutedArguments = substituteTypeArguments(
type.getConstructor().getParameters(), type.getArguments(), recursionDepth); type.getConstructor().getParameters(), type.getArguments(), recursionDepth);
@@ -265,10 +281,12 @@ public class TypeSubstitutor {
return substitutedArguments; return substitutedArguments;
} }
private static Variance combine(Variance typeParameterVariance, Variance projectionKind) { @NotNull
public static Variance combine(@NotNull Variance typeParameterVariance, @NotNull Variance projectionKind) {
if (typeParameterVariance == Variance.INVARIANT) return projectionKind; if (typeParameterVariance == Variance.INVARIANT) return projectionKind;
if (projectionKind == Variance.INVARIANT) return typeParameterVariance; if (projectionKind == Variance.INVARIANT) return typeParameterVariance;
if (typeParameterVariance == projectionKind) return projectionKind; if (typeParameterVariance == projectionKind) return projectionKind;
//todo ask why?
return Variance.IN_VARIANCE; return Variance.IN_VARIANCE;
} }
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.types.checker;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor; import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
class TypeCheckerTypingConstraints implements TypingConstraints { class TypeCheckerTypingConstraints implements TypingConstraints {
@Override @Override
@@ -36,6 +37,11 @@ class TypeCheckerTypingConstraints implements TypingConstraints {
return typeCheckingProcedure.isSubtypeOf(subtype, supertype); return typeCheckingProcedure.isSubtypeOf(subtype, supertype);
} }
@Override
public boolean capture(@NotNull JetType type, @NotNull TypeProjection typeProjection) {
return false;
}
@Override @Override
public boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) { public boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) {
return false; // type checking fails return false; // type checking fails
@@ -106,6 +106,9 @@ public class TypeCheckingProcedure {
TypeProjection typeProjection1 = type1Arguments.get(i); TypeProjection typeProjection1 = type1Arguments.get(i);
TypeParameterDescriptor typeParameter2 = constructor2.getParameters().get(i); TypeParameterDescriptor typeParameter2 = constructor2.getParameters().get(i);
TypeProjection typeProjection2 = type2Arguments.get(i); TypeProjection typeProjection2 = type2Arguments.get(i);
if (capture(typeProjection1, typeProjection2, typeParameter1)) {
continue;
}
if (getEffectiveProjectionKind(typeParameter1, typeProjection1) != getEffectiveProjectionKind(typeParameter2, typeProjection2)) { if (getEffectiveProjectionKind(typeParameter1, typeProjection1) != getEffectiveProjectionKind(typeParameter2, typeProjection2)) {
return false; return false;
} }
@@ -225,6 +228,8 @@ public class TypeCheckingProcedure {
JetType superIn = getInType(parameter, superArgument); JetType superIn = getInType(parameter, superArgument);
JetType superOut = getOutType(parameter, superArgument); JetType superOut = getOutType(parameter, superArgument);
if (capture(subArgument, superArgument, parameter)) continue;
boolean argumentIsErrorType = subArgument.getType().isError() || superArgument.getType().isError(); boolean argumentIsErrorType = subArgument.getType().isError() || superArgument.getType().isError();
if (!argumentIsErrorType && parameter.getVariance() == INVARIANT if (!argumentIsErrorType && parameter.getVariance() == INVARIANT
&& subArgument.getProjectionKind() == INVARIANT && superArgument.getProjectionKind() == INVARIANT) { && subArgument.getProjectionKind() == INVARIANT && superArgument.getProjectionKind() == INVARIANT) {
@@ -237,4 +242,25 @@ public class TypeCheckingProcedure {
} }
return true; return true;
} }
private boolean capture(
@NotNull TypeProjection firstProjection,
@NotNull TypeProjection secondProjection,
@NotNull TypeParameterDescriptor parameter
) {
// Capturing makes sense only for invariant classes
if (parameter.getVariance() != INVARIANT) return false;
// Now, both subtype and supertype relations transform to equality constraints on type arguments:
// Array<T> is a subtype, supertype or equal to Array<out Int> then T captures a type that extends Int: 'Captured(out Int)'
// Array<T> is a subtype, supertype or equal to Array<in Int> then T captures a type that extends Int: 'Captured(in Int)'
if (firstProjection.getProjectionKind() == INVARIANT && secondProjection.getProjectionKind() != INVARIANT) {
return constraints.capture(firstProjection.getType(), secondProjection);
}
if (firstProjection.getProjectionKind() != INVARIANT && secondProjection.getProjectionKind() == INVARIANT) {
return constraints.capture(secondProjection.getType(), firstProjection);
}
return false;
}
} }
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.types.checker;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor; import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
/** /**
* Methods of this class return true to continue type checking and false to fail * Methods of this class return true to continue type checking and false to fail
@@ -30,5 +31,7 @@ public interface TypingConstraints {
boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype, @NotNull TypeCheckingProcedure typeCheckingProcedure); boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype, @NotNull TypeCheckingProcedure typeCheckingProcedure);
boolean capture(@NotNull JetType type, @NotNull TypeProjection typeProjection);
boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype); boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype);
} }
@@ -116,6 +116,7 @@ import org.jetbrains.jet.lang.resolve.java.AbstractJavaTypeSubstitutorTest
import org.jetbrains.jet.plugin.intentions.declarations.AbstractJoinLinesTest import org.jetbrains.jet.plugin.intentions.declarations.AbstractJoinLinesTest
import org.jetbrains.jet.codegen.AbstractScriptCodegenTest import org.jetbrains.jet.codegen.AbstractScriptCodegenTest
import org.jetbrains.jet.plugin.parameterInfo.AbstractFunctionParameterInfoTest import org.jetbrains.jet.plugin.parameterInfo.AbstractFunctionParameterInfoTest
import org.jetbrains.jet.resolve.typeApproximation.AbstractCapturedTypeApproximationTest
import org.jetbrains.jet.psi.patternMatching.AbstractJetPsiUnifierTest import org.jetbrains.jet.psi.patternMatching.AbstractJetPsiUnifierTest
import org.jetbrains.jet.completion.weighers.AbstractBasicCompletionWeigherTest import org.jetbrains.jet.completion.weighers.AbstractBasicCompletionWeigherTest
import org.jetbrains.jet.completion.weighers.AbstractSmartCompletionWeigherTest import org.jetbrains.jet.completion.weighers.AbstractSmartCompletionWeigherTest
@@ -167,6 +168,10 @@ fun main(args: Array<String>) {
model("constraintSystem", extension = "bounds") model("constraintSystem", extension = "bounds")
} }
testClass(javaClass<AbstractCapturedTypeApproximationTest>()) {
model("capturedTypeApproximation")
}
testClass(javaClass<AbstractJetParsingTest>()) { testClass(javaClass<AbstractJetParsingTest>()) {
model("psi", testMethod = "doParsingTest", pattern = "^(.*)\\.kts?$") model("psi", testMethod = "doParsingTest", pattern = "^(.*)\\.kts?$")
model("parseCodeFragment/expression", testMethod = "doExpressionCodeFragmentParsingTest", extension = "kt") model("parseCodeFragment/expression", testMethod = "doExpressionCodeFragmentParsingTest", extension = "kt")