[FIR] Make resolution of classes in FirProvider more reasonable.
See the `privateInFile.fir.kt` test. Type mismatches are simply confusing. `inheritorOfExpectSealedClass.out` reports unresolved reference probably because now it resolves into the expect declaration, rather than the actual one. K1 doesn't report UNRESOLVED_REFERENCE in this case. But this is red code anyway. And this behavior still depends on the order in which the compiler receives both the declarations. ^KT-59927 ^KT-62567
This commit is contained in:
committed by
Space Team
parent
a9ceae9667
commit
41c3f98419
+4
-4
@@ -16,14 +16,14 @@ class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : <!FINAL_SUPERTYPE, SUPERTYPE_NOT_INITIALIZED!>A<!> {
|
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : <!SUPERTYPE_NOT_INITIALIZED!>A<!> {
|
||||||
<!CONFLICTING_OVERLOADS!><!NOTHING_TO_OVERRIDE!>override<!> fun rest(s: String)<!> {}
|
<!CONFLICTING_OVERLOADS!>override fun rest(s: String)<!> {}
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>fun rest(s: String)<!> {}
|
<!CONFLICTING_OVERLOADS!>fun <!VIRTUAL_MEMBER_HIDDEN!>rest<!>(s: String)<!> {}
|
||||||
|
|
||||||
fun rest(l: Long) {}
|
fun rest(l: Long) {}
|
||||||
|
|
||||||
<!NOTHING_TO_OVERRIDE!>override<!> val u = 310
|
override val u = 310
|
||||||
}
|
}
|
||||||
|
|
||||||
interface <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
|
interface <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
|
||||||
|
|||||||
-75
@@ -1,75 +0,0 @@
|
|||||||
// LL_FIR_DIVERGENCE
|
|
||||||
// The compiler doesn't specify which declaration of `A` is chosen in supertype resolution given that `A` has multiple redeclarations.
|
|
||||||
// LL_FIR_DIVERGENCE
|
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>fun test(x: Int)<!> {}
|
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>fun test(y: Int)<!> {}
|
|
||||||
|
|
||||||
fun test() {}
|
|
||||||
|
|
||||||
fun test(z: Int, c: Char) {}
|
|
||||||
|
|
||||||
open class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
|
|
||||||
open fun rest(s: String) {}
|
|
||||||
|
|
||||||
open val u = 20
|
|
||||||
}
|
|
||||||
|
|
||||||
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : <!SUPERTYPE_NOT_INITIALIZED!>A<!> {
|
|
||||||
<!CONFLICTING_OVERLOADS!>override fun rest(s: String)<!> {}
|
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>fun <!VIRTUAL_MEMBER_HIDDEN!>rest<!>(s: String)<!> {}
|
|
||||||
|
|
||||||
fun rest(l: Long) {}
|
|
||||||
|
|
||||||
override val u = 310
|
|
||||||
}
|
|
||||||
|
|
||||||
interface <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
|
|
||||||
|
|
||||||
enum class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
|
|
||||||
|
|
||||||
val <!REDECLARATION!>u<!> = 10
|
|
||||||
val <!REDECLARATION!>u<!> = 20
|
|
||||||
|
|
||||||
val <!SYNTAX!>(a,b)<!> = 30 to 40
|
|
||||||
val <!SYNTAX!>(c,d)<!> = 50 to 60
|
|
||||||
|
|
||||||
typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = A
|
|
||||||
typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = B
|
|
||||||
|
|
||||||
typealias BA = A
|
|
||||||
|
|
||||||
fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> kek(t: T) where T : (String) -> Any?, T : <!FINAL_UPPER_BOUND!>Char<!> {}
|
|
||||||
fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> kek(t: T) where T : () -> Boolean, T : <!FINAL_UPPER_BOUND!>String<!> {}
|
|
||||||
fun <T : <!FINAL_UPPER_BOUND!>Int<!>> kek(t: T) {}
|
|
||||||
|
|
||||||
fun lol(a: Array<Int>) {}
|
|
||||||
fun lol(a: Array<Boolean>) {}
|
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> mem(t: T)<!> where T : () -> Boolean, T : <!FINAL_UPPER_BOUND!>String<!> {}
|
|
||||||
<!CONFLICTING_OVERLOADS!>fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> mem(t: T)<!> where T : <!FINAL_UPPER_BOUND!>String<!>, T : () -> Boolean {}
|
|
||||||
|
|
||||||
class M {
|
|
||||||
companion <!REDECLARATION!>object<!> {}
|
|
||||||
val <!REDECLARATION!>Companion<!> = object : Any() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun B.foo() {}
|
|
||||||
|
|
||||||
class L {
|
|
||||||
fun B.foo() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>fun mest()<!> {}
|
|
||||||
|
|
||||||
class <!CONFLICTING_OVERLOADS!>mest<!>
|
|
||||||
|
|
||||||
<!FUNCTION_DECLARATION_WITH_NO_NAME!>fun()<!> {}
|
|
||||||
|
|
||||||
<!FUNCTION_DECLARATION_WITH_NO_NAME!>private fun()<!> {}
|
|
||||||
+1
-1
@@ -6,7 +6,7 @@ interface C : <!INTERFACE_WITH_SUPERCLASS!>A<!>
|
|||||||
|
|
||||||
interface D : C, <!INTERFACE_WITH_SUPERCLASS!>A<!>
|
interface D : C, <!INTERFACE_WITH_SUPERCLASS!>A<!>
|
||||||
|
|
||||||
class E : <!SINGLETON_IN_SUPERTYPE!>B<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST!>A<!>()
|
class E : <!FINAL_SUPERTYPE!>B<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST!>A<!>()
|
||||||
|
|
||||||
sealed class P {
|
sealed class P {
|
||||||
object H: P()
|
object H: P()
|
||||||
|
|||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
// LL_FIR_DIVERGENCE
|
|
||||||
// The compiler doesn't specify which declaration of `B` is chosen in supertype resolution given that `B` is declared both as a class and
|
|
||||||
// as an object.
|
|
||||||
// LL_FIR_DIVERGENCE
|
|
||||||
|
|
||||||
sealed class A
|
|
||||||
|
|
||||||
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : A()
|
|
||||||
|
|
||||||
interface C : <!INTERFACE_WITH_SUPERCLASS!>A<!>
|
|
||||||
|
|
||||||
interface D : C, <!INTERFACE_WITH_SUPERCLASS!>A<!>
|
|
||||||
|
|
||||||
class E : <!FINAL_SUPERTYPE!>B<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST!>A<!>()
|
|
||||||
|
|
||||||
sealed class P {
|
|
||||||
object H: P()
|
|
||||||
class J : P()
|
|
||||||
|
|
||||||
object T {
|
|
||||||
object V : P()
|
|
||||||
class M : P()
|
|
||||||
}
|
|
||||||
|
|
||||||
val p: P = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
val r = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class K : P()
|
|
||||||
|
|
||||||
object <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> {
|
|
||||||
class I : P()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
class L : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>()
|
|
||||||
val a = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+12
-4
@@ -123,8 +123,12 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: FirKotli
|
|||||||
override fun visitRegularClass(regularClass: FirRegularClass, data: FirRecorderData) {
|
override fun visitRegularClass(regularClass: FirRegularClass, data: FirRecorderData) {
|
||||||
val classId = regularClass.symbol.classId
|
val classId = regularClass.symbol.classId
|
||||||
val prevFile = data.state.classifierContainerFileMap.put(classId, data.file)
|
val prevFile = data.state.classifierContainerFileMap.put(classId, data.file)
|
||||||
data.state.classifierMap.put(classId, regularClass)?.let {
|
val storedClassifier = data.state.classifierMap.getOrPut(classId) { regularClass }
|
||||||
data.nameConflictsTracker?.registerClassifierRedeclaration(classId, regularClass.symbol, data.file, it.symbol, prevFile)
|
|
||||||
|
if (storedClassifier != regularClass) {
|
||||||
|
data.nameConflictsTracker?.registerClassifierRedeclaration(
|
||||||
|
classId, regularClass.symbol, data.file, storedClassifier.symbol, prevFile,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!classId.isNestedClass && !classId.isLocal) {
|
if (!classId.isNestedClass && !classId.isLocal) {
|
||||||
@@ -138,8 +142,12 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: FirKotli
|
|||||||
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: FirRecorderData) {
|
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: FirRecorderData) {
|
||||||
val classId = typeAlias.symbol.classId
|
val classId = typeAlias.symbol.classId
|
||||||
val prevFile = data.state.classifierContainerFileMap.put(classId, data.file)
|
val prevFile = data.state.classifierContainerFileMap.put(classId, data.file)
|
||||||
data.state.classifierMap.put(classId, typeAlias)?.let {
|
val storedClassifier = data.state.classifierMap.getOrPut(classId) { typeAlias }
|
||||||
data.nameConflictsTracker?.registerClassifierRedeclaration(classId, typeAlias.symbol, data.file, it.symbol, prevFile)
|
|
||||||
|
if (storedClassifier != typeAlias) {
|
||||||
|
data.nameConflictsTracker?.registerClassifierRedeclaration(
|
||||||
|
classId, typeAlias.symbol, data.file, storedClassifier.symbol, prevFile,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.state.classifierInPackage.getOrPut(classId.packageFqName, ::mutableSetOf).add(classId.shortClassName)
|
data.state.classifierInPackage.getOrPut(classId.packageFqName, ::mutableSetOf).add(classId.shortClassName)
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
compiler/testData/cli/metadata/inheritorOfExpectSealedClass/common-2.kt:1:21: error: 'actual class Base : Any' has no corresponding expected declaration
|
compiler/testData/cli/metadata/inheritorOfExpectSealedClass/common-2.kt:1:21: error: 'actual class Base : Any' has no corresponding expected declaration
|
||||||
actual sealed class Base
|
actual sealed class Base
|
||||||
^
|
^
|
||||||
|
compiler/testData/cli/metadata/inheritorOfExpectSealedClass/common-3.kt:1:17: error: unresolved reference '<init>'.
|
||||||
|
class Derived : Base()
|
||||||
|
^
|
||||||
COMPILATION_ERROR
|
COMPILATION_ERROR
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ private class C {
|
|||||||
private typealias TA = C
|
private typealias TA = C
|
||||||
|
|
||||||
private val test1: <!INVISIBLE_REFERENCE!>C<!> = <!INVISIBLE_REFERENCE!>C<!>()
|
private val test1: <!INVISIBLE_REFERENCE!>C<!> = <!INVISIBLE_REFERENCE!>C<!>()
|
||||||
private val test1co: <!INVISIBLE_REFERENCE!>C<!>.Companion = <!INITIALIZER_TYPE_MISMATCH, INVISIBLE_REFERENCE, NO_COMPANION_OBJECT!>C<!>
|
private val test1co: <!INVISIBLE_REFERENCE!>C<!>.Companion = <!INVISIBLE_REFERENCE!>C<!>
|
||||||
|
|
||||||
private val test2: <!INVISIBLE_REFERENCE!>TA<!> = <!INVISIBLE_REFERENCE!>TA<!>()
|
private val test2: <!INVISIBLE_REFERENCE!>TA<!> = <!INVISIBLE_REFERENCE!>TA<!>()
|
||||||
private val test2co = <!INVISIBLE_REFERENCE!>TA<!>
|
private val test2co = <!INVISIBLE_REFERENCE!>TA<!>
|
||||||
|
|
||||||
// FILE: file2.kt
|
// FILE: file2.kt
|
||||||
private val test1: C = C()
|
private val test1: C = C()
|
||||||
private val test1co: C.Companion = <!INITIALIZER_TYPE_MISMATCH, NO_COMPANION_OBJECT!>C<!>
|
private val test1co: C.Companion = C
|
||||||
|
|
||||||
private val test2: TA = <!INVISIBLE_REFERENCE!>TA<!>()
|
private val test2: TA = TA()
|
||||||
private val test2co = TA
|
private val test2co = TA
|
||||||
|
|
||||||
private class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!>
|
private class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!>
|
||||||
|
|||||||
Reference in New Issue
Block a user