google / ksp

Kotlin Symbol Processing API
https://github.com/google/ksp
Apache License 2.0
2.72k stars 254 forks source link

KSP2: IllegalArgumentException: Failed requirement. #1966

Open ZacSweers opened 2 weeks ago

ZacSweers commented 2 weeks ago

We encountered a crash in KSP2 (version 2.0.0-1.0.22) in a very specific scenario. The crash comes from FIR/AA, but not sure if this is something wrong with KSP2's impl as the code itself compiles fine in K2 without KSP running.

Repro:

// in :lib1
interface IRepro {
  val prefs: Runnable
}

// in :lib2
abstract class BaseRepro(
  override val prefs: Runnable,
) : IRepro

When KSP2 runs on lib2, the below trace happens

Caused by: java.lang.IllegalArgumentException: Failed requirement.  
    at org.jetbrains.kotlin.fir.scopes.impl.FirOverrideUtilsKt.isAbstractAccordingToRawStatus(FirOverrideUtils.kt:104)  
    at org.jetbrains.kotlin.fir.java.scopes.JavaOverrideChecker.chooseIntersectionVisibility(JavaOverrideChecker.kt:398)    
    at org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScopeContext.createIntersectionOverride(FirTypeIntersectionScopeContext.kt:219)  
    at org.jetbrains.kotlin.fir.scopes.impl.FirIntersectionOverrideStorage$cacheByScope$1$1.invoke(FirTypeIntersectionScopeContext.kt:514)  
    at org.jetbrains.kotlin.fir.scopes.impl.FirIntersectionOverrideStorage$cacheByScope$1$1.invoke(FirTypeIntersectionScopeContext.kt:513)  
    at org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.FirThreadSafeCache.getValue(FirThreadSafeCache.kt:27) 
    at org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScopeContext$ResultOfIntersection$NonTrivial.chosenSymbol_delegate$lambda$0(FirTypeIntersectionScopeContext.kt:72)   
    at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)  
    at org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScopeContext$ResultOfIntersection$NonTrivial.getChosenSymbol(FirTypeIntersectionScopeContext.kt:70)  
    at org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteMemberScope.collectProperties(JavaClassUseSiteMemberScope.kt:178)   
    at org.jetbrains.kotlin.fir.scopes.impl.AbstractFirUseSiteMemberScope.processPropertiesByName(AbstractFirUseSiteMemberScope.kt:156) 
    at org.jetbrains.kotlin.fir.java.scopes.JavaClassMembersEnhancementScope.processPropertiesByName(JavaClassMembersEnhancementScope.kt:33)    
    at org.jetbrains.kotlin.fir.scopes.FirDelegatingContainingNamesAwareScope.processPropertiesByName(FirDelegatingContainingNamesAwareScope.kt:46) 
    at org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScopeKt.processAllCallables(FirContainingNamesAwareScope.kt:32)   
    at org.jetbrains.kotlin.analysis.api.fir.scopes.FirCallableFilteringScope.cachedCallableNames_delegate$lambda$2(FirCallableFilteringScope.kt:24)    
    at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)   
    at org.jetbrains.kotlin.analysis.api.fir.scopes.FirCallableFilteringScope.getCachedCallableNames(FirCallableFilteringScope.kt:22)   
    at org.jetbrains.kotlin.analysis.api.fir.scopes.FirCallableFilteringScope.getCallableNames(FirCallableFilteringScope.kt:32) 
    at org.jetbrains.kotlin.analysis.api.fir.scopes.KtFirDelegatingNamesAwareScope.getPossibleCallableNames(KtFirDelegatingNamesAwareScope.kt:25)   
    at org.jetbrains.kotlin.analysis.api.fir.scopes.KtFirBasedScope.getCallableSymbols(KtFirBasedScope.kt:27)   
    at org.jetbrains.kotlin.analysis.api.scopes.KtScope.getCallableSymbols$default(KtScope.kt:31)   
    at org.jetbrains.kotlin.analysis.api.scopes.KtScope$getAllSymbols$1$1.invokeSuspend(KtScope.kt:19)  
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)   
    at kotlin.sequences.SequenceBuilderIterator.hasNext(SequenceBuilder.kt:129) 
    at kotlin.sequences.FlatteningSequence$iterator$1.ensureItemIterator(Sequences.kt:331)  
    at kotlin.sequences.FlatteningSequence$iterator$1.hasNext(Sequences.kt:318) 
    at kotlin.sequences.DistinctIterator.computeNext(Sequences.kt:588)  
    at kotlin.collections.AbstractIterator.tryToComputeNext(AbstractIterator.kt:55) 
    at kotlin.collections.AbstractIterator.hasNext(AbstractIterator.kt:34)  
    at kotlin.sequences.TransformingSequence$iterator$1.hasNext(Sequences.kt:214)   
    at com.google.devtools.ksp.common.MemoizedSequence$CachedIterator.hasNext(MemoizedSequence.kt:32)   
    at com.google.devtools.ksp.impl.symbol.kotlin.KSClassDeclarationImpl$declarations$2.invoke(KSClassDeclarationImpl.kt:240)   
    at com.google.devtools.ksp.impl.symbol.kotlin.KSClassDeclarationImpl$declarations$2.invoke(KSClassDeclarationImpl.kt:178)   
    at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)  
    at com.google.devtools.ksp.impl.symbol.kotlin.KSClassDeclarationImpl.getDeclarations(KSClassDeclarationImpl.kt:178) 
    at com.google.devtools.ksp.common.symbolCollector.visitDeclarationContainer(IncrementalContextBase.kt:56)   
    at com.google.devtools.ksp.common.symbolCollector.visitDeclarationContainer(IncrementalContextBase.kt:34)   
    at com.google.devtools.ksp.visitor.KSDefaultVisitor.visitClassDeclaration(KSDefaultVisitor.kt:80)   
    at com.google.devtools.ksp.impl.symbol.kotlin.KSClassDeclarationImpl.accept(KSClassDeclarationImpl.kt:175)  
    at com.google.devtools.ksp.common.symbolCollector.visitDeclarationContainer(IncrementalContextBase.kt:57)   
    at com.google.devtools.ksp.common.symbolCollector.visitDeclarationContainer(IncrementalContextBase.kt:34)   
    at com.google.devtools.ksp.visitor.KSDefaultVisitor.visitFile(KSDefaultVisitor.kt:32)   
    at com.google.devtools.ksp.impl.symbol.kotlin.KSFileJavaImpl.accept(KSFileJavaImpl.kt:58)   
    at com.google.devtools.ksp.common.IncrementalContextBase.collectDefinedSymbols(IncrementalContextBase.kt:111)   
    at com.google.devtools.ksp.common.IncrementalContextBase.calcDirtyFiles(IncrementalContextBase.kt:218)  
    at com.google.devtools.ksp.impl.KotlinSymbolProcessing.execute(KotlinSymbolProcessing.kt:486)   
    at com.google.devtools.ksp.impl.KSPLoader$Companion.loadAndRunKSP(KSPLoader.kt:36)  
    at com.google.devtools.ksp.impl.KSPLoader.loadAndRunKSP(KSPLoader.kt)
ZacSweers commented 2 weeks ago

Tried a few different attempted workarounds but no luck so far

neetopia commented 2 weeks ago

potentially could be a same issue as #1930

tldr: when getting declarations of a class KSP queries analysis API for declared member scope, inside which AA will perform a serial of checks including checking for override e.t.c.. which has put an assertion for the symbols to be checked in resolved status, I am not certain about the cause of the status not being resolved though, since manually resolving does not seem to help, the check was added recently, I might need to talk to JB regarding this.

ZacSweers commented 2 weeks ago

Possibly yeah. Looks like this also happens with functions

ZacSweers commented 2 weeks ago

Also happens if the base class is an abstract or open class

ZacSweers commented 2 weeks ago

Actually this seems to intermittently also happen with non-java classes too :/

ZacSweers commented 2 weeks ago

I am able to get this working by just not using constructor parameter properties

abstract class BaseRepro(
  prefs: Runnable,
) : IRepro {
  override val prefs: Runnable = prefs
}
neetopia commented 2 weeks ago

Actually this seems to intermittently also happen with non-java classes too :/

can I get a case for non-java classes?

ZacSweers commented 2 weeks ago

Just another kotlin class in another module

neetopia commented 2 weeks ago

My concern is this is more widespread than #1930 , I've created https://youtrack.jetbrains.com/issue/KT-69070 issue for this, feel free to add more context there if you feel the issue is related in your case.