[FE] Detect recursion when typealias referenced as annotation in its RHS
#KT-14612 Fixed
This commit is contained in:
+6
@@ -28743,6 +28743,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/kt14518.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt14612.kt")
|
||||
public void testKt14612() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/kt14612.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt14641.kt")
|
||||
public void testKt14641() throws Exception {
|
||||
|
||||
+22
-3
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.resolve.lazy.descriptors
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.FilteredByPredicateAnnotations
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.resolve.AnnotationResolver
|
||||
@@ -32,6 +34,8 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
import org.jetbrains.kotlin.types.AbbreviatedType
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
|
||||
abstract class LazyAnnotationsContext(
|
||||
val annotationResolver: AnnotationResolver,
|
||||
@@ -77,9 +81,24 @@ class LazyAnnotationDescriptor(
|
||||
c.trace.record(BindingContext.ANNOTATION, annotationEntry, this)
|
||||
}
|
||||
|
||||
override val type by c.storageManager.createLazyValue {
|
||||
c.annotationResolver.resolveAnnotationType(scope, annotationEntry, c.trace)
|
||||
}
|
||||
override val type by c.storageManager.createLazyValue(
|
||||
computable = lazy@{
|
||||
val annotationType = c.annotationResolver.resolveAnnotationType(scope, annotationEntry, c.trace)
|
||||
if (annotationType is AbbreviatedType) {
|
||||
// This is needed to prevent recursion in cases like this: typealias S = @S Ann
|
||||
if (annotationType.annotations.any { it == this }) {
|
||||
annotationType.abbreviation.constructor.declarationDescriptor?.let { typeAliasDescriptor ->
|
||||
c.trace.report(Errors.RECURSIVE_TYPEALIAS_EXPANSION.on(annotationEntry, typeAliasDescriptor))
|
||||
}
|
||||
return@lazy annotationType.replaceAnnotations(FilteredByPredicateAnnotations(annotationType.annotations) { it != this })
|
||||
}
|
||||
}
|
||||
annotationType
|
||||
},
|
||||
onRecursiveCall = {
|
||||
ErrorUtils.createErrorType("Recursion in type of annotation detected")
|
||||
}
|
||||
)
|
||||
|
||||
override val source = annotationEntry.toSourceElement()
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
// ISSUE: KT-14612
|
||||
|
||||
typealias S = @S Suppress
|
||||
@@ -0,0 +1,3 @@
|
||||
// ISSUE: KT-14612
|
||||
|
||||
typealias S = <!RECURSIVE_TYPEALIAS_EXPANSION!>@S<!> Suppress
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
public typealias S = @S /* = kotlin.Suppress */(names = {}) kotlin.Suppress
|
||||
|
||||
Generated
+6
@@ -28839,6 +28839,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/kt14518.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt14612.kt")
|
||||
public void testKt14612() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/kt14612.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt14641.kt")
|
||||
public void testKt14641() throws Exception {
|
||||
|
||||
@@ -79,6 +79,23 @@ class FilteredAnnotations(
|
||||
}
|
||||
}
|
||||
|
||||
class FilteredByPredicateAnnotations(
|
||||
private val delegate: Annotations,
|
||||
private val filter: (AnnotationDescriptor) -> Boolean
|
||||
) : Annotations {
|
||||
override fun isEmpty(): Boolean {
|
||||
return !iterator().hasNext()
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<AnnotationDescriptor> {
|
||||
return delegate.filter(filter).iterator()
|
||||
}
|
||||
|
||||
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? {
|
||||
return super.findAnnotation(fqName)?.takeIf(filter)
|
||||
}
|
||||
}
|
||||
|
||||
class CompositeAnnotations(
|
||||
private val delegates: List<Annotations>
|
||||
) : Annotations {
|
||||
|
||||
Reference in New Issue
Block a user