~
diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt
index 164407c..ed7de65 100644
--- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt
+++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt
@@ -26,6 +26,8 @@
                 return providers.flatMapTo(mutableSetOf()) { it.findPackageParts(packageFqName) }.toList()
             }
 
+            override fun allPackageNames(): List<String> = providers.flatMap { it.allPackageNames() }
+
             override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> {
                 return providers.flatMapTo(mutableSetOf()) { it.getAnnotationsOnBinaryModule(moduleName) }.toList()
             }
diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt
index 64eb9cf..8881cd0 100644
--- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt
+++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt
@@ -97,6 +97,10 @@
         }
     }
 
+    override fun computePackageSet(): Set<String> = fragmentNamesInLibraries.keys
+
+    override fun mayHaveTopLevelClass(classId: ClassId) = true
+
     @OptIn(SymbolInternals::class)
     override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? {
         val packageStringName = classId.packageFqName.asString()
diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolProvider.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolProvider.kt
index f3670f9..b60c61c 100644
--- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolProvider.kt
+++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolProvider.kt
@@ -73,6 +73,22 @@
 ) : FirSymbolProvider(session) {
     // ------------------------ Caches ------------------------
 
+    private val packageNames by lazy {
+        computePackageSet()
+    }
+
+    private val typeAliasesNamesByPackage: FirCache<FqName, Set<Name>, Nothing?> =
+        session.firCachesFactory.createCache { fqName: FqName ->
+            getPackageParts(fqName).flatMapTo(mutableSetOf()) { it.typeAliasNameIndex.keys }
+        }
+
+    private val allNamesByPackage: FirCache<FqName, Set<Name>, Nothing?> =
+        session.firCachesFactory.createCache { fqName: FqName ->
+            getPackageParts(fqName).flatMapTo(mutableSetOf()) {
+                it.topLevelFunctionNameIndex.keys + it.topLevelPropertyNameIndex.keys
+            }
+        }
+
     private val packagePartsCache = session.firCachesFactory.createCache(::tryComputePackagePartInfos)
     private val typeAliasCache = session.firCachesFactory.createCache(::findAndDeserializeTypeAlias)
     private val classCache: FirCache<ClassId, FirRegularClassSymbol?, FirDeserializationContext?> =
@@ -91,6 +107,9 @@
     // ------------------------ Abstract members ------------------------
 
     protected abstract fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData>
+    protected abstract fun computePackageSet(): Set<String>
+
+    protected abstract fun mayHaveTopLevelClass(classId: ClassId): Boolean
 
     protected abstract fun extractClassMetadata(
         classId: ClassId,
@@ -190,6 +209,10 @@
         parentContext: FirDeserializationContext? = null
     ): FirRegularClassSymbol? {
         val parentClassId = classId.outerClassId
+
+        if (parentClassId == null && !mayHaveTopLevelClass(classId)) return null
+        if (parentClassId != null && !mayHaveTopLevelClass(classId.outermostClassId)) return null
+
         if (parentContext == null && parentClassId != null) {
             val alreadyLoaded = classCache.getValueIfComputed(classId)
             if (alreadyLoaded != null) return alreadyLoaded
@@ -200,26 +223,38 @@
         return classCache.getValue(classId, parentContext)
     }
 
-    private fun getTypeAlias(classId: ClassId): FirTypeAliasSymbol? =
-        if (classId.relativeClassName.isOneSegmentFQN()) typeAliasCache.getValue(classId) else null
+    private fun getTypeAlias(classId: ClassId): FirTypeAliasSymbol? {
+        if (!classId.relativeClassName.isOneSegmentFQN()) return null
+        val packageFqName = classId.packageFqName
+        if (packageFqName.asString() !in packageNames) return null
+        if (classId.shortClassName !in typeAliasesNamesByPackage.getValue(packageFqName)) return null
+
+        return typeAliasCache.getValue(classId)
+    }
 
     // ------------------------ SymbolProvider methods ------------------------
 
     @FirSymbolProviderInternals
     override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
         val callableId = CallableId(packageFqName, name)
-        destination += functionCache.getValue(callableId)
-        destination += propertyCache.getValue(callableId)
+        destination += functionCache.getCallables(callableId)
+        destination += propertyCache.getCallables(callableId)
+    }
+
+    private fun <C : FirCallableSymbol<*>> FirCache<CallableId, List<C>, Nothing?>.getCallables(id: CallableId): List<C> {
+        if (id.packageName.asString() !in packageNames) return emptyList()
+        if (id.callableName !in allNamesByPackage.getValue(id.packageName)) return emptyList()
+        return getValue(id)
     }
 
     @FirSymbolProviderInternals
     override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
-        destination += functionCache.getValue(CallableId(packageFqName, name))
+        destination += functionCache.getCallables(CallableId(packageFqName, name))
     }
 
     @FirSymbolProviderInternals
     override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
-        destination += propertyCache.getValue(CallableId(packageFqName, name))
+        destination += propertyCache.getCallables(CallableId(packageFqName, name))
     }
 
     override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt
index 4e77418..80321f1 100644
--- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt
+++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt
@@ -27,7 +27,7 @@
 import org.jetbrains.kotlin.name.ClassId
 import org.jetbrains.kotlin.name.FqName
 import org.jetbrains.kotlin.resolve.jvm.JvmClassName
-import org.jetbrains.kotlin.serialization.deserialization.*
+import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
 import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
 import java.nio.file.Path
 import java.nio.file.Paths
@@ -91,6 +91,10 @@
         }
     }
 
+    override fun computePackageSet(): Set<String> = packagePartProvider.allPackageNames().toSet()
+
+    override fun mayHaveTopLevelClass(classId: ClassId): Boolean = javaFacade.hasTopLevelClassOf(classId)
+
     private val KotlinJvmBinaryClass.incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>?
         get() {
             // TODO: skipMetadataVersionCheck
diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/OptionalAnnotationClassesProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/OptionalAnnotationClassesProvider.kt
index 0fbdfa7..fb35d2d 100644
--- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/OptionalAnnotationClassesProvider.kt
+++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/OptionalAnnotationClassesProvider.kt
@@ -49,6 +49,10 @@
         return emptyList()
     }
 
+    override fun computePackageSet(): Set<String> = emptySet()
+
+    override fun mayHaveTopLevelClass(classId: ClassId): Boolean = true
+
     override fun extractClassMetadata(
         classId: ClassId,
         parentContext: FirDeserializationContext?
@@ -70,4 +74,4 @@
     }
 
     override fun getPackage(fqName: FqName): FqName? = if (optionalAnnotationClassesAndPackages.second.contains(fqName)) fqName else null
-}
\ No newline at end of file
+}
diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt
index 90bc4dc..fe94302 100644
--- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt
+++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt
@@ -52,6 +52,12 @@
                 parent.findPackageParts(packageFqName)).distinct()
     }
 
+    private val allPackageNames_ by lazy {
+        moduleMappings.flatMap { it.packageFqName2Parts.keys } + parent.allPackageNames()
+    }
+
+    override fun allPackageNames() = allPackageNames_
+
     override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> {
         return parent.getAnnotationsOnBinaryModule(moduleName)
     }
diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt
index 262434c..56f2786 100644
--- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt
+++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt
@@ -39,6 +39,11 @@
         return result.toList()
     }
 
+    private val allPackageNames_ by lazy {
+        loadedModules.flatMap { it.mapping.packageFqName2Parts.keys }
+    }
+
+    override fun allPackageNames() = allPackageNames_
     override fun findMetadataPackageParts(packageFqName: String): List<String> =
         getPackageParts(packageFqName).flatMap(PackageParts::metadataParts).distinct()
 
diff --git a/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/PackagePartProvider.kt b/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/PackagePartProvider.kt
index 2502123..7241161 100644
--- a/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/PackagePartProvider.kt
+++ b/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/PackagePartProvider.kt
@@ -18,6 +18,8 @@
      */
     fun findPackageParts(packageFqName: String): List<String>
 
+    fun allPackageNames(): List<String>
+
     fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId>
 
     fun getAllOptionalAnnotationClasses(): List<ClassData>
@@ -28,5 +30,7 @@
         override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> = emptyList()
 
         override fun getAllOptionalAnnotationClasses(): List<ClassData> = emptyList()
+
+        override fun allPackageNames(): List<String> = emptyList()
     }
 }