From 0ec152e457cd04aebef58e76c34ab74eb14863f1 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Tue, 22 Dec 2020 12:45:46 +0100 Subject: [PATCH] FIR IDE: fix deadlock in override check We should not call withFir nestedly as resolving in read action causing deadlocks --- .../KtFirSymbolDeclarationOverridesProvider.kt | 10 ++++------ .../api/fir/utils/FirRefWithValidityCheck.kt | 12 ++++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt index edf229da4a4..10924fc58a2 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt @@ -43,12 +43,10 @@ internal class KtFirSymbolDeclarationOverridesProvider( check(callableSymbol is KtFirSymbol<*>) check(containingDeclaration is KtFirClassOrObjectSymbol) - return callableSymbol.firRef.withFir(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { firCallableElement -> - - containingDeclaration.firRef.withFir(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { containingDeclaration -> - - val firTypeScope = containingDeclaration.unsubstitutedScope( - containingDeclaration.session, + return containingDeclaration.firRef.withFir(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { firContainer -> + callableSymbol.firRef.withFirUnsafe { firCallableElement -> + val firTypeScope = firContainer.unsubstitutedScope( + firContainer.session, ScopeSession(), withForcedTypeCalculator = false ) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/FirRefWithValidityCheck.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/FirRefWithValidityCheck.kt index 43e6c915848..1cfb2cfbec8 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/FirRefWithValidityCheck.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/FirRefWithValidityCheck.kt @@ -41,6 +41,18 @@ internal class FirRefWithValidityCheck(fir: D, resolveSt } } + /** + * Runs [action] with fir element *without* any lock hold + * Consider using this only when you are completely sure + * that fir or one of it's container already holds the lock (i.e, corresponding withFir call was made) + */ + inline fun withFirUnsafe(action: (fir: D) -> R): R { + token.assertIsValidAndAccessible() + val fir = firWeakRef.get() + ?: throw EntityWasGarbageCollectedException("FirElement") + return action(fir) + } + val resolveState get() = resolveStateWeakRef.get() ?: throw EntityWasGarbageCollectedException("FirModuleResolveState")