Fix inline class recursion through type parameters
Note that inline class such as inline class Id<T>(val x: T) is prohibited in 1.3.0.
This commit is contained in:
+6
-1
@@ -13,4 +13,9 @@ inline class TestNullable(val x: <!INLINE_CLASS_CANNOT_BE_RECURSIVE!>TestNullabl
|
||||
|
||||
inline class TestRecursionInTypeArguments(val x: List<TestRecursionInTypeArguments>)
|
||||
|
||||
inline class TestRecursionInArray(val x: Array<TestRecursionInArray>)
|
||||
inline class TestRecursionInArray(val x: Array<TestRecursionInArray>)
|
||||
|
||||
inline class TestRecursionInUpperBounds<T : TestRecursionInUpperBounds<T>>(val x: <!INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>T<!>)
|
||||
|
||||
inline class Id<T>(val x: <!INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>T<!>)
|
||||
inline class TestRecursionThroughId(val x: Id<TestRecursionThroughId>)
|
||||
@@ -1,5 +1,13 @@
|
||||
package
|
||||
|
||||
public final inline class Id</*0*/ T> {
|
||||
public constructor Id</*0*/ T>(/*0*/ x: T)
|
||||
public final val x: T
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final inline class Test1 {
|
||||
public constructor Test1(/*0*/ x: Test1)
|
||||
public final val x: Test1
|
||||
@@ -71,3 +79,19 @@ public final inline class TestRecursionInTypeArguments {
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final inline class TestRecursionInUpperBounds</*0*/ T : TestRecursionInUpperBounds<T>> {
|
||||
public constructor TestRecursionInUpperBounds</*0*/ T : TestRecursionInUpperBounds<T>>(/*0*/ x: T)
|
||||
public final val x: T
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final inline class TestRecursionThroughId {
|
||||
public constructor TestRecursionThroughId(/*0*/ x: Id<TestRecursionThroughId>)
|
||||
public final val x: Id<TestRecursionThroughId>
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -37,12 +34,21 @@ fun KotlinType.substitutedUnderlyingType(): KotlinType? {
|
||||
fun KotlinType.isRecursiveInlineClassType() =
|
||||
isRecursiveInlineClassTypeInner(hashSetOf())
|
||||
|
||||
private fun KotlinType.isRecursiveInlineClassTypeInner(visited: HashSet<ClassDescriptor>): Boolean {
|
||||
val descriptor = constructor.declarationDescriptor as? ClassDescriptor ?: return false
|
||||
if (visited.contains(descriptor)) return true
|
||||
if (!descriptor.isInlineClass()) return false
|
||||
visited.add(descriptor)
|
||||
return unsubstitutedUnderlyingType()?.isRecursiveInlineClassTypeInner(visited) ?: false
|
||||
private fun KotlinType.isRecursiveInlineClassTypeInner(visited: HashSet<ClassifierDescriptor>): Boolean {
|
||||
val descriptor = constructor.declarationDescriptor?.original ?: return false
|
||||
|
||||
if (!visited.add(descriptor)) return true
|
||||
|
||||
return when (descriptor) {
|
||||
is ClassDescriptor ->
|
||||
descriptor.isInlineClass() &&
|
||||
unsubstitutedUnderlyingType()?.isRecursiveInlineClassTypeInner(visited) == true
|
||||
|
||||
is TypeParameterDescriptor ->
|
||||
descriptor.upperBounds.any { it.isRecursiveInlineClassTypeInner(visited) }
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
fun KotlinType.isNullableUnderlyingType(): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user