Fix compatibility of CapturedTypeConstructor and NewCapturedTypeConstructor
Now both of those classes implements one interface with `TypeProjection` property. That allows old captured type approximator use new captured types. That change fixes tests related to diagnostics: - SETTER_PROJECTED_OUT - DEBUG_INFO_UNRESOLVED_WITH_TARGET - UNRESOLVED_REFERENCE_WRONG_RECEIVER Also `typeProjection` property renamed to `projection` according to naming in NI.
This commit is contained in:
@@ -489,7 +489,7 @@ object Renderers {
|
||||
val typeParameter = typeVariableWithCapturedConstraint.originalTypeParameter
|
||||
val upperBound = TypeIntersector.getUpperBoundsAsType(typeParameter)
|
||||
|
||||
assert(!KotlinBuiltIns.isNullableAny(upperBound) && capturedTypeConstructor.typeProjection.projectionKind == Variance.IN_VARIANCE) {
|
||||
assert(!KotlinBuiltIns.isNullableAny(upperBound) && capturedTypeConstructor.projection.projectionKind == Variance.IN_VARIANCE) {
|
||||
"There is the only reason to report TYPE_INFERENCE_CANNOT_CAPTURE_TYPES"
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ object Renderers {
|
||||
newText().normal(
|
||||
typeParameter.name.wrapIntoQuotes() +
|
||||
" cannot capture " +
|
||||
"${capturedTypeConstructor.typeProjection.toString().wrapIntoQuotes()}. " +
|
||||
"${capturedTypeConstructor.projection.toString().wrapIntoQuotes()}. " +
|
||||
explanation
|
||||
)
|
||||
)
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@ interface A<T : A<T?>?> {
|
||||
fun foo(): T?
|
||||
}
|
||||
fun testA(a: A<*>) {
|
||||
a.foo() checkType { <!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><A<*>?>() }
|
||||
a.foo() checkType { _<A<*>?>() }
|
||||
}
|
||||
|
||||
+3
-3
@@ -14,14 +14,14 @@ class A<E> {
|
||||
fun test(a: A<out CharSequence>, z: Out<CharSequence>) {
|
||||
a.foo {
|
||||
val x: String = <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!> // Should be no TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS
|
||||
<!NI;TYPE_MISMATCH, TYPE_MISMATCH!>""<!>
|
||||
<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, TYPE_MISMATCH!>""<!>
|
||||
}
|
||||
a.bar { <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, TYPE_MISMATCH!>Out<CharSequence>()<!> }
|
||||
a.bar { Out() }
|
||||
a.bar { <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, TYPE_MISMATCH!>z.<!NI;TYPE_MISMATCH!>id()<!><!> }
|
||||
|
||||
a.foo {
|
||||
z.foobar(if (1 > 2) return@foo <!TYPE_MISMATCH!>""<!> else "")
|
||||
<!NI;TYPE_MISMATCH, TYPE_MISMATCH!>""<!>
|
||||
z.foobar(if (1 > 2) return@foo <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, TYPE_MISMATCH!>""<!> else "")
|
||||
<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, TYPE_MISMATCH!>""<!>
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -13,15 +13,15 @@ class A<T> {
|
||||
}
|
||||
|
||||
fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
||||
a.<!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo1<!>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>Out<CharSequence>()<!>)
|
||||
a.foo1<<!UPPER_BOUND_VIOLATED!>Out<CharSequence><!>>(Out())
|
||||
a.<!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo1<!>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>Out<CharSequence>()<!>)
|
||||
a.foo1<<!UPPER_BOUND_VIOLATED!>Out<CharSequence><!>>(<!NI;TYPE_MISMATCH!>Out()<!>)
|
||||
|
||||
a.foo1(Out())
|
||||
a.foo1(Out<Nothing>())
|
||||
|
||||
a.<!OI;TYPE_INFERENCE_INCORPORATION_ERROR!>foo2<!>(<!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Inv<!>())
|
||||
a.<!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo2<!>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>Inv<CharSequence>()<!>)
|
||||
a.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>Inv()<!>)
|
||||
a.<!OI;TYPE_INFERENCE_INCORPORATION_ERROR!>foo2<!>(<!NI;TYPE_MISMATCH!><!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Inv<!>()<!>)
|
||||
a.<!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo2<!>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>Inv<CharSequence>()<!>)
|
||||
a.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(<!NI;TYPE_MISMATCH!>Inv()<!>)
|
||||
|
||||
a.foo3(In())
|
||||
a.foo3(In<CharSequence>())
|
||||
@@ -31,13 +31,13 @@ fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
||||
b.foo1(Out<CharSequence>())
|
||||
b.foo1<Out<CharSequence>>(Out())
|
||||
|
||||
b.<!OI;TYPE_INFERENCE_INCORPORATION_ERROR!>foo2<!>(<!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Inv<!>())
|
||||
b.<!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo2<!>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>Inv<CharSequence>()<!>)
|
||||
b.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>Inv()<!>)
|
||||
b.<!OI;TYPE_INFERENCE_INCORPORATION_ERROR!>foo2<!>(<!NI;TYPE_MISMATCH!><!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Inv<!>()<!>)
|
||||
b.<!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo2<!>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>Inv<CharSequence>()<!>)
|
||||
b.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(<!NI;TYPE_MISMATCH!>Inv()<!>)
|
||||
|
||||
|
||||
b.<!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo3<!>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>In<CharSequence>()<!>)
|
||||
b.foo3<<!UPPER_BOUND_VIOLATED!>In<CharSequence><!>>(In())
|
||||
b.<!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo3<!>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>In<CharSequence>()<!>)
|
||||
b.foo3<<!UPPER_BOUND_VIOLATED!>In<CharSequence><!>>(<!NI;TYPE_MISMATCH!>In()<!>)
|
||||
|
||||
b.foo3(In<Any?>())
|
||||
b.foo3(In())
|
||||
|
||||
@@ -13,9 +13,9 @@ class Inv2<<!FINITE_BOUNDS_VIOLATION!>T : Inv2<in T><!>>(val x: T)
|
||||
fun main(a: A<*>, j: JavaClass<*>, i2: Inv2<*>) {
|
||||
// Probably it's too restrictive to suppose star projection type here as Any?,
|
||||
// but looks like we can refine it later
|
||||
a.foo() checkType { <!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Any?>() }
|
||||
j.foo() checkType { <!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Any?>() }
|
||||
i2.x checkType { <!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Any?>() }
|
||||
a.foo() checkType { _<Any?>() }
|
||||
j.foo() checkType { _<Any?>() }
|
||||
i2.x checkType { _<Any?>() }
|
||||
|
||||
j.bar(<!NI;CONSTANT_EXPECTED_TYPE_MISMATCH, OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, <!NI;CONSTANT_EXPECTED_TYPE_MISMATCH, OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>, <!NI;TYPE_MISMATCH, OI;TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS!>Any()<!>)
|
||||
j.bar(null)
|
||||
|
||||
+1
-1
@@ -5,6 +5,6 @@ interface Tr<T> {
|
||||
}
|
||||
|
||||
fun test(t: Tr<*>) {
|
||||
<!OI;SETTER_PROJECTED_OUT!>t.v<!> = t
|
||||
<!SETTER_PROJECTED_OUT!>t.v<!> = <!NI;TYPE_MISMATCH!>t<!>
|
||||
t.v checkType { _<Tr<*>>() }
|
||||
}
|
||||
+2
-2
@@ -8,7 +8,7 @@ interface Tr<T> {
|
||||
|
||||
fun test(t: Tr<*>) {
|
||||
t.v = null!!
|
||||
<!OI;SETTER_PROJECTED_OUT!>t.v<!> = ""
|
||||
<!OI;SETTER_PROJECTED_OUT!>t.v<!> = null
|
||||
<!SETTER_PROJECTED_OUT!>t.v<!> = ""
|
||||
<!SETTER_PROJECTED_OUT!>t.v<!> = null
|
||||
t.v checkType { _<Any?>() }
|
||||
}
|
||||
Vendored
+1
-1
@@ -7,5 +7,5 @@ interface Tr<T> {
|
||||
fun test(t: Tr<out String>) {
|
||||
// resolved as t.v = t.v + null!!, where type of right operand is String,
|
||||
// so TYPE_MISMATCH: String is not <: of Captured(out String)
|
||||
<!OI;SETTER_PROJECTED_OUT!>t.v<!> += null!!
|
||||
<!SETTER_PROJECTED_OUT!>t.v<!> += null!!
|
||||
}
|
||||
+1
-1
@@ -14,5 +14,5 @@ class Owner<in T> {
|
||||
fun getT() = u
|
||||
}
|
||||
|
||||
<!NI;TYPE_VARIANCE_CONFLICT!>fun foo(arg: Inner<*>)<!> = arg.getT()
|
||||
fun foo(arg: Inner<*>) = arg.getT()
|
||||
}
|
||||
+2
-2
@@ -3,7 +3,7 @@ package
|
||||
public final class Owner</*0*/ in T> {
|
||||
public constructor Owner</*0*/ in T>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun foo(/*0*/ arg: Owner<T>.Inner<*>): T
|
||||
public final fun foo(/*0*/ arg: Owner<T>.Inner<*>): kotlin.Any?
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
@@ -26,7 +26,7 @@ public interface Rec</*0*/ T : Rec<T>> {
|
||||
|
||||
public interface Super</*0*/ out U> {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ p: Rec<*>): Rec<out Rec<out Rec<out Rec<out Rec<out kotlin.Any?>>>>>
|
||||
public open fun foo(/*0*/ p: Rec<*>): Rec<*>
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ interface B<R, T: B<List<R>, <!UPPER_BOUND_VIOLATED!>T<!>>> {
|
||||
}
|
||||
|
||||
fun testB(b: B<*, *>) {
|
||||
<!OI;TYPE_MISMATCH!>b<!>.r().checkType { _<Any?>() }
|
||||
<!OI;TYPE_MISMATCH!>b<!>.t().checkType { <!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><B<List<*>, *>>() }
|
||||
<!OI;TYPE_MISMATCH!>b<!>.<!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>r<!>().<!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>checkType<!> { <!NI;UNRESOLVED_REFERENCE!>_<!><Any?>() }
|
||||
<!OI;TYPE_MISMATCH!>b<!>.<!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>t<!>().<!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>checkType<!> { <!NI;UNRESOLVED_REFERENCE!>_<!><B<List<*>, *>>() }
|
||||
|
||||
<!OI;TYPE_MISMATCH!><!OI;TYPE_MISMATCH!>b<!>.t()<!>.r().size
|
||||
<!OI;TYPE_MISMATCH!><!OI;TYPE_MISMATCH!>b<!>.<!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>t<!>()<!>.<!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>r<!>().<!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>size<!>
|
||||
}
|
||||
|
||||
|
||||
+14
-10
@@ -27,22 +27,26 @@ import org.jetbrains.kotlin.types.Variance.OUT_VARIANCE
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
class CapturedTypeConstructor(
|
||||
val typeProjection: TypeProjection
|
||||
) : TypeConstructor {
|
||||
interface CapturedTypeConstructor : TypeConstructor {
|
||||
val projection: TypeProjection
|
||||
}
|
||||
|
||||
class CapturedTypeConstructorImpl(
|
||||
override val projection: TypeProjection
|
||||
) : CapturedTypeConstructor {
|
||||
var newTypeConstructor: NewCapturedTypeConstructor? = null
|
||||
|
||||
init {
|
||||
assert(typeProjection.projectionKind != Variance.INVARIANT) {
|
||||
"Only nontrivial projections can be captured, not: $typeProjection"
|
||||
assert(projection.projectionKind != Variance.INVARIANT) {
|
||||
"Only nontrivial projections can be captured, not: $projection"
|
||||
}
|
||||
}
|
||||
|
||||
override fun getParameters(): List<TypeParameterDescriptor> = listOf()
|
||||
|
||||
override fun getSupertypes(): Collection<KotlinType> {
|
||||
val superType = if (typeProjection.projectionKind == Variance.OUT_VARIANCE)
|
||||
typeProjection.type
|
||||
val superType = if (projection.projectionKind == Variance.OUT_VARIANCE)
|
||||
projection.type
|
||||
else
|
||||
builtIns.nullableAnyType
|
||||
return listOf(superType)
|
||||
@@ -54,14 +58,14 @@ class CapturedTypeConstructor(
|
||||
|
||||
override fun getDeclarationDescriptor() = null
|
||||
|
||||
override fun toString() = "CapturedTypeConstructor($typeProjection)"
|
||||
override fun toString() = "CapturedTypeConstructor($projection)"
|
||||
|
||||
override fun getBuiltIns(): KotlinBuiltIns = typeProjection.type.constructor.builtIns
|
||||
override fun getBuiltIns(): KotlinBuiltIns = projection.type.constructor.builtIns
|
||||
}
|
||||
|
||||
class CapturedType(
|
||||
val typeProjection: TypeProjection,
|
||||
override val constructor: CapturedTypeConstructor = CapturedTypeConstructor(typeProjection),
|
||||
override val constructor: CapturedTypeConstructor = CapturedTypeConstructorImpl(typeProjection),
|
||||
override val isMarkedNullable: Boolean = false,
|
||||
override val annotations: Annotations = Annotations.EMPTY
|
||||
) : SimpleType(), SubtypingRepresentatives {
|
||||
|
||||
@@ -98,10 +98,10 @@ private fun substituteCapturedTypesWithProjections(typeProjection: TypeProjectio
|
||||
val typeSubstitutor = TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
||||
override fun get(key: TypeConstructor): TypeProjection? {
|
||||
val capturedTypeConstructor = key as? CapturedTypeConstructor ?: return null
|
||||
if (capturedTypeConstructor.typeProjection.isStarProjection) {
|
||||
return TypeProjectionImpl(Variance.OUT_VARIANCE, capturedTypeConstructor.typeProjection.type)
|
||||
if (capturedTypeConstructor.projection.isStarProjection) {
|
||||
return TypeProjectionImpl(Variance.OUT_VARIANCE, capturedTypeConstructor.projection.type)
|
||||
}
|
||||
return capturedTypeConstructor.typeProjection
|
||||
return capturedTypeConstructor.projection
|
||||
}
|
||||
})
|
||||
return typeSubstitutor.substituteWithoutApproximation(typeProjection)
|
||||
@@ -127,7 +127,7 @@ fun approximateCapturedTypes(type: KotlinType): ApproximationBounds<KotlinType>
|
||||
|
||||
val typeConstructor = type.constructor
|
||||
if (type.isCaptured()) {
|
||||
val typeProjection = (typeConstructor as CapturedTypeConstructor).typeProjection
|
||||
val typeProjection = (typeConstructor as CapturedTypeConstructor).projection
|
||||
fun KotlinType.makeNullableIfNeeded() = TypeUtils.makeNullableIfNeeded(this, type.isMarkedNullable)
|
||||
val bound = typeProjection.type.makeNullableIfNeeded()
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
@@ -145,7 +146,7 @@ class NewCapturedType(
|
||||
NewCapturedType(captureStatus, constructor, lowerType, annotations, newNullability)
|
||||
}
|
||||
|
||||
class NewCapturedTypeConstructor(val projection: TypeProjection, private var supertypes: List<UnwrappedType>? = null) : TypeConstructor {
|
||||
class NewCapturedTypeConstructor(override val projection: TypeProjection, private var supertypes: List<UnwrappedType>? = null) : CapturedTypeConstructor {
|
||||
fun initializeSupertypes(supertypes: List<UnwrappedType>) {
|
||||
assert(this.supertypes == null) {
|
||||
"Already initialized! oldValue = ${this.supertypes}, newValue = $supertypes"
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.isFinalClass
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructorImpl
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.TypeCheckerContext.LowerCapturedTypePolicy.*
|
||||
@@ -136,12 +136,12 @@ object NewKotlinTypeChecker : KotlinTypeChecker {
|
||||
val constructor = type.constructor
|
||||
when (constructor) {
|
||||
// Type itself can be just SimpleTypeImpl, not CapturedType. see KT-16147
|
||||
is CapturedTypeConstructor -> {
|
||||
val lowerType = constructor.typeProjection.takeIf { it.projectionKind == Variance.IN_VARIANCE }?.type?.unwrap()
|
||||
is CapturedTypeConstructorImpl -> {
|
||||
val lowerType = constructor.projection.takeIf { it.projectionKind == Variance.IN_VARIANCE }?.type?.unwrap()
|
||||
|
||||
// it is incorrect calculate this type directly because of recursive star projections
|
||||
if (constructor.newTypeConstructor == null) {
|
||||
constructor.newTypeConstructor = NewCapturedTypeConstructor(constructor.typeProjection, constructor.supertypes.map { it.unwrap() })
|
||||
constructor.newTypeConstructor = NewCapturedTypeConstructor(constructor.projection, constructor.supertypes.map { it.unwrap() })
|
||||
}
|
||||
return NewCapturedType(CaptureStatus.FOR_SUBTYPING, constructor.newTypeConstructor!!,
|
||||
lowerType, type.annotations, type.isMarkedNullable)
|
||||
|
||||
Reference in New Issue
Block a user