From 579838cb4e01f6563532f13eda0ddec9bbfab1bb Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 12 Jul 2019 14:06:20 +0300 Subject: [PATCH] Avoid recursive refinement in NewCapturedTypeConstructor Potentially, it might contain infinite recursive supertypes And for such cases, we have to perform lazy refinement (one level per request) --- .../kotlin/types/checker/NewCapturedType.kt | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt index d133ccc8448..b52ad420853 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt @@ -154,18 +154,28 @@ class NewCapturedType( class NewCapturedTypeConstructor( override val projection: TypeProjection, - private var supertypes: List? = null, + private var supertypesComputation: (() -> List)? = null, private val original: NewCapturedTypeConstructor? = null -) : - CapturedTypeConstructor { - fun initializeSupertypes(supertypes: List) { - assert(this.supertypes == null) { - "Already initialized! oldValue = ${this.supertypes}, newValue = $supertypes" - } - this.supertypes = supertypes +) : CapturedTypeConstructor { + + constructor( + projection: TypeProjection, + supertypes: List, + original: NewCapturedTypeConstructor? = null + ) : this(projection, { supertypes }, original) + + private val _supertypes by lazy(LazyThreadSafetyMode.PUBLICATION) { + supertypesComputation?.invoke() } - override fun getSupertypes() = supertypes ?: emptyList() + fun initializeSupertypes(supertypes: List) { + assert(this.supertypesComputation == null) { + "Already initialized! oldValue = ${this.supertypesComputation}, newValue = $supertypes" + } + this.supertypesComputation = { supertypes } + } + + override fun getSupertypes() = _supertypes ?: emptyList() override fun getParameters(): List = emptyList() override fun isFinal() = false @@ -177,7 +187,11 @@ class NewCapturedTypeConstructor( override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = NewCapturedTypeConstructor( projection.refine(kotlinTypeRefiner), - supertypes?.map { it.refine(kotlinTypeRefiner) }, + supertypesComputation?.let { + { + supertypes.map { it.refine(kotlinTypeRefiner) } + } + }, original ?: this )