AA FE1.0: Fix StackOverflowError during resolution to a function w/ recursive type parameter

^KT-55825 Fixed
This commit is contained in:
Jinseong Jeon
2022-12-26 10:04:03 -08:00
committed by Yan Zhulanow
parent 0c516f8483
commit 2dca2b4827
7 changed files with 161 additions and 1 deletions
@@ -231,7 +231,12 @@ private fun KotlinType.hasReferenceOtherThan(allowedTypeParameterDescriptors: Se
declarationDescriptor !in allowedTypeParameterDescriptors ||
declarationDescriptor.upperBounds.any { it.hasReferenceOtherThan(allowedTypeParameterDescriptors) }
}
else -> arguments.any { it.type.hasReferenceOtherThan(allowedTypeParameterDescriptors) }
else -> arguments.any { typeProjection ->
// A star projection type (lazily) built by type parameter will be yet another type with a star projection,
// resulting in stack overflow if we keep checking allowed type parameter descriptors
!typeProjection.isStarProjection &&
typeProjection.type.hasReferenceOtherThan(allowedTypeParameterDescriptors)
}
}
}
@@ -700,6 +700,12 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated extends A
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/qualifiedCalleeExpressionOfImplicitInvoke.kt");
}
@Test
@TestMetadata("recursiveTypeParameter.kt")
public void testRecursiveTypeParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.kt");
}
@Test
@TestMetadata("resolveCallInSuperConstructorParam.kt")
public void testResolveCallInSuperConstructorParam() throws Exception {
@@ -700,6 +700,12 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/qualifiedCalleeExpressionOfImplicitInvoke.kt");
}
@Test
@TestMetadata("recursiveTypeParameter.kt")
public void testRecursiveTypeParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.kt");
}
@Test
@TestMetadata("resolveCallInSuperConstructorParam.kt")
public void testResolveCallInSuperConstructorParam() throws Exception {
@@ -700,6 +700,12 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated ext
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/qualifiedCalleeExpressionOfImplicitInvoke.kt");
}
@Test
@TestMetadata("recursiveTypeParameter.kt")
public void testRecursiveTypeParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.kt");
}
@Test
@TestMetadata("resolveCallInSuperConstructorParam.kt")
public void testResolveCallInSuperConstructorParam() throws Exception {
@@ -0,0 +1,49 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue:
symbol = KtNamedClassOrObjectSymbol:
annotationsList: []
classIdIfNonLocal: RunnerModule
classKind: CLASS
companionObject: null
contextReceivers: []
isData: false
isExternal: false
isFun: false
isInline: false
isInner: false
modality: FINAL
name: RunnerModule
origin: SOURCE
superTypes: [
AbstractModule
]
symbolKind: TOP_LEVEL
typeParameters: []
visibility: Public
type = RunnerModule
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /AbstractModule.install(<dispatch receiver>: AbstractModule, builder: AbstractModule.Builder<*>!): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = builder
receiverType = null
returnType = AbstractModule.Builder<*>!
symbol = builder: AbstractModule.Builder<*>!
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /AbstractModule.install
typeArgumentsMapping = {}
argumentMapping = {
CoroutineModule.builder() -> (KtVariableLikeSignature:
name = builder
receiverType = null
returnType = AbstractModule.Builder<*>!
symbol = builder: AbstractModule.Builder<*>!
callableIdIfNonLocal = null)
}
@@ -0,0 +1,39 @@
// FILE: RunnerModule.kt
class RunnerModule : AbstractModule() {
fun configure() {
<expr>install(CoroutineModule.builder())</expr>
}
}
// FILE: Module.java
public interface Module {
public interface Builder {
Module build();
}
}
// FILE: AbstractModule.java
public abstract class AbstractModule {
public abstract static class Builder<B extends Builder<B>> implements Module.Builder {
protected abstract B self();
public abstract Module build();
}
protected void install(Builder<?> builder) {}
}
// FILE: CoroutineModule.kt
class CoroutineModule : AbstractModule() {
class Builder : AbstractModule.Builder<Builder>() {
protected override fun self(): Builder = this
override fun build(): Module = CoroutineModule()
}
companion object {
fun builder(): Builder = Builder()
}
}
@@ -0,0 +1,49 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue:
symbol = KtNamedClassOrObjectSymbol:
annotationsList: []
classIdIfNonLocal: RunnerModule
classKind: CLASS
companionObject: null
contextReceivers: []
isData: false
isExternal: false
isFun: false
isInline: false
isInner: false
modality: FINAL
name: RunnerModule
origin: SOURCE
superTypes: [
AbstractModule
]
symbolKind: TOP_LEVEL
typeParameters: []
visibility: Public
type = RunnerModule
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /AbstractModule.install(<dispatch receiver>: AbstractModule, builder: ft<AbstractModule.Builder<*>, AbstractModule.Builder<*>?>): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = builder
receiverType = null
returnType = ft<AbstractModule.Builder<*>, AbstractModule.Builder<*>?>
symbol = builder: ft<AbstractModule.Builder<*>, AbstractModule.Builder<*>?>
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /AbstractModule.install
typeArgumentsMapping = {}
argumentMapping = {
CoroutineModule.builder() -> (KtVariableLikeSignature:
name = builder
receiverType = null
returnType = ft<AbstractModule.Builder<*>, AbstractModule.Builder<*>?>
symbol = builder: ft<AbstractModule.Builder<*>, AbstractModule.Builder<*>?>
callableIdIfNonLocal = null)
}