[FIR] Fix false positive errors on Throws::class, Throws()
^KT-63794 Fixed
This commit is contained in:
committed by
Space Team
parent
8dcd4efbc1
commit
3d77d09260
+48
-7
@@ -11,11 +11,8 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.CallableCopyTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.TypeAliasConstructorsSubstitutingScope
|
||||
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
||||
import org.jetbrains.kotlin.fir.scopes.scopeForClass
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
@@ -86,7 +83,12 @@ fun FirScope.getSingleVisibleClassifier(
|
||||
if (result == null) {
|
||||
result = classifierSymbol
|
||||
} else {
|
||||
isAmbiguousResult = true
|
||||
val checkResult = checkUnambiguousClassifiers(result!!, classifierSymbol, session)
|
||||
if (checkResult.shouldReplaceResult) {
|
||||
result = classifierSymbol
|
||||
} else {
|
||||
isAmbiguousResult = checkResult.isAmbiguousResult
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,8 +139,12 @@ private fun FirScope.getFirstClassifierOrNull(
|
||||
}
|
||||
result != null -> {
|
||||
if (isSuccessResult == isSuccessCandidate) {
|
||||
// results are similar => ambiguity
|
||||
isAmbiguousResult = true
|
||||
val checkResult = checkUnambiguousClassifiers(result!!.symbol, symbol, session)
|
||||
if (checkResult.shouldReplaceResult) {
|
||||
result = SymbolWithSubstitutor(symbol, substitutor)
|
||||
} else {
|
||||
isAmbiguousResult = checkResult.isAmbiguousResult
|
||||
}
|
||||
} else {
|
||||
// ignore unsuccessful result if we have successful one
|
||||
}
|
||||
@@ -154,6 +160,41 @@ private fun FirScope.getFirstClassifierOrNull(
|
||||
return result.takeUnless { isAmbiguousResult }
|
||||
}
|
||||
|
||||
private data class CheckUnambiguousClassifiersResult(val shouldReplaceResult: Boolean, val isAmbiguousResult: Boolean)
|
||||
|
||||
/**
|
||||
* Handle special cases when classifiers don't cause ambiguity (`Throws`)
|
||||
*
|
||||
* The following output options are possible:
|
||||
* * `shouldReplaceResult = true, isAmbiguousResult = false` means successful disambiguation
|
||||
* but the previous result should be replaced with the new one (typically class symbol wins typealias)
|
||||
* * `shouldReplaceResult = false, isAmbiguousResult = false` means successful disambiguation
|
||||
* but the new result should be discarded
|
||||
* * `shouldReplaceResult = false, isAmbiguousResult = true` means unsuccessful disambiguation
|
||||
* and both results become irrelevant
|
||||
*/
|
||||
private fun checkUnambiguousClassifiers(
|
||||
foundClassifierSymbol: FirClassifierSymbol<*>,
|
||||
newClassifierSymbol: FirClassifierSymbol<*>,
|
||||
session: FirSession,
|
||||
): CheckUnambiguousClassifiersResult {
|
||||
val classTypealiasesThatDontCauseAmbiguity = session.platformClassMapper.classTypealiasesThatDontCauseAmbiguity
|
||||
|
||||
if (foundClassifierSymbol is FirTypeAliasSymbol && newClassifierSymbol is FirRegularClassSymbol &&
|
||||
classTypealiasesThatDontCauseAmbiguity[newClassifierSymbol.classId] == foundClassifierSymbol.classId
|
||||
) {
|
||||
return CheckUnambiguousClassifiersResult(shouldReplaceResult = true, isAmbiguousResult = false)
|
||||
}
|
||||
|
||||
if (newClassifierSymbol is FirTypeAliasSymbol && foundClassifierSymbol is FirRegularClassSymbol &&
|
||||
classTypealiasesThatDontCauseAmbiguity[foundClassifierSymbol.classId] == newClassifierSymbol.classId
|
||||
) {
|
||||
return CheckUnambiguousClassifiersResult(shouldReplaceResult = false, isAmbiguousResult = false)
|
||||
}
|
||||
|
||||
return CheckUnambiguousClassifiersResult(shouldReplaceResult = false, isAmbiguousResult = true)
|
||||
}
|
||||
|
||||
private fun processSyntheticConstructors(
|
||||
matchedSymbol: FirClassLikeSymbol<*>,
|
||||
processor: (FirFunctionSymbol<*>) -> Unit,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-63794
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// FILE: main1.kt
|
||||
package abc1
|
||||
@@ -163,3 +164,10 @@ fun foo3() {}
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
|
||||
// FILE: main10.kt
|
||||
|
||||
val x: Throws? = null
|
||||
val y = Throws()
|
||||
val z = Throws::exceptionClasses
|
||||
val w = Throws::class
|
||||
@@ -1,5 +1,10 @@
|
||||
package
|
||||
|
||||
public val w: kotlin.reflect.KClass<kotlin.Throws /* = kotlin.jvm.Throws */>
|
||||
public val x: kotlin.Throws? /* = kotlin.jvm.Throws? */ = null
|
||||
public val y: kotlin.Throws /* = kotlin.jvm.Throws */
|
||||
public val z: kotlin.reflect.KProperty1<kotlin.Throws /* = kotlin.jvm.Throws */, kotlin.Array<out kotlin.reflect.KClass<out kotlin.Throwable>>>
|
||||
|
||||
package abc1 {
|
||||
@kotlin.Throws /* = kotlin.jvm.Throws */(exceptionClasses = {java.lang.Exception::class}) public fun foo1(): kotlin.Unit
|
||||
@kotlin.Throws /* = kotlin.jvm.Throws */(exceptionClasses = {java.lang.Exception::class}) public fun foo2(): kotlin.Unit
|
||||
|
||||
Reference in New Issue
Block a user