[FIR] Bring conflicting overloads errors closer to K1 behavior

#KT-55860 Fixed
This commit is contained in:
Kirill Rakhman
2023-03-24 15:58:05 +01:00
committed by Space Team
parent 9dd778bc89
commit 56da3c2ee2
12 changed files with 124 additions and 28 deletions
@@ -23387,6 +23387,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
} }
@Test
@TestMetadata("conflictingInherited.kt")
public void testConflictingInherited() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/conflictingInherited.kt");
}
@Test @Test
@TestMetadata("covariantOverrides.kt") @TestMetadata("covariantOverrides.kt")
public void testCovariantOverrides() throws Exception { public void testCovariantOverrides() throws Exception {
@@ -23387,6 +23387,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
} }
@Test
@TestMetadata("conflictingInherited.kt")
public void testConflictingInherited() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/conflictingInherited.kt");
}
@Test @Test
@TestMetadata("covariantOverrides.kt") @TestMetadata("covariantOverrides.kt")
public void testCovariantOverrides() throws Exception { public void testCovariantOverrides() throws Exception {
@@ -23387,6 +23387,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
} }
@Test
@TestMetadata("conflictingInherited.kt")
public void testConflictingInherited() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/conflictingInherited.kt");
}
@Test @Test
@TestMetadata("covariantOverrides.kt") @TestMetadata("covariantOverrides.kt")
public void testCovariantOverrides() throws Exception { public void testCovariantOverrides() throws Exception {
@@ -23393,6 +23393,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
} }
@Test
@TestMetadata("conflictingInherited.kt")
public void testConflictingInherited() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/conflictingInherited.kt");
}
@Test @Test
@TestMetadata("covariantOverrides.kt") @TestMetadata("covariantOverrides.kt")
public void testCovariantOverrides() throws Exception { public void testCovariantOverrides() throws Exception {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtRealSourceElementKind
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
@@ -13,6 +14,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.impl.deduplicating import org.jetbrains.kotlin.diagnostics.impl.deduplicating
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.declarations.utils.classId
@@ -195,16 +197,14 @@ object FirImplementationMismatchChecker : FirClassChecker() {
) { ) {
val allFunctions = mutableListOf<FirNamedFunctionSymbol>() val allFunctions = mutableListOf<FirNamedFunctionSymbol>()
scope.processFunctionsByName(name) { sym -> scope.processFunctionsByName(name) { sym ->
val declaredInThisClass = sym.callableId.classId == containingClass.classId when (sym) {
when { is FirIntersectionOverrideFunctionSymbol -> sym.intersections.mapNotNullTo(allFunctions) { it as? FirNamedFunctionSymbol }
sym is FirIntersectionOverrideFunctionSymbol && declaredInThisClass -> else -> allFunctions.add(sym)
sym.intersections.mapNotNullTo(allFunctions) { it as? FirNamedFunctionSymbol }
!declaredInThisClass -> allFunctions.add(sym)
} }
} }
val sameArgumentGroups = allFunctions.groupBy { function -> val sameArgumentGroups = allFunctions.groupBy { function ->
buildList<ConeKotlinType> { buildList {
addIfNotNull(function.resolvedReceiverTypeRef?.type) addIfNotNull(function.resolvedReceiverTypeRef?.type)
function.valueParameterSymbols.mapTo(this) { it.resolvedReturnTypeRef.coneType } function.valueParameterSymbols.mapTo(this) { it.resolvedReturnTypeRef.coneType }
} }
@@ -216,8 +216,30 @@ object FirImplementationMismatchChecker : FirClassChecker() {
} }
} }
clashes.forEach { for (clash in clashes) {
reporter.reportOn(containingClass.source, FirErrors.CONFLICTING_INHERITED_MEMBERS, containingClass.symbol, it.toList(), context) val (first, second) = clash
val firstClassLookupTag = first.containingClassLookupTag()
val secondClassLookupTag = second.containingClassLookupTag()
if (firstClassLookupTag == secondClassLookupTag) {
// Don't report if both declarations came from the same class because either CONFLICTING_OVERLOADS was reported in the
// original class or it's ok to keep compatibility with K1. See KT-55860.
continue
}
val thisClassLookupTag = containingClass.symbol.toLookupTag()
// If one of the declarations is from this class, report CONFLICTING_OVERLOADS, otherwise CONFLICTING_INHERITED_MEMBERS
if (firstClassLookupTag == thisClassLookupTag && first.source?.kind is KtRealSourceElementKind) {
reporter.reportOn(first.source, FirErrors.CONFLICTING_OVERLOADS, clash.toList(), context)
} else if (secondClassLookupTag == thisClassLookupTag && second.source?.kind is KtRealSourceElementKind) {
reporter.reportOn(second.source, FirErrors.CONFLICTING_OVERLOADS, clash.toList(), context)
} else {
reporter.reportOn(
containingClass.source, FirErrors.CONFLICTING_INHERITED_MEMBERS, containingClass.symbol, clash.toList(), context,
)
}
} }
} }
@@ -1,7 +0,0 @@
open class Aaa() {
fun foo() = 1
}
open class Bbb() : Aaa() {
fun <T> foo() = 2
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
open class Aaa() { open class Aaa() {
fun foo() = 1 fun foo() = 1
} }
@@ -0,0 +1,31 @@
// SKIP_TXT
open class A {
fun <T> some(s: String): T = null!!
}
interface I {
fun some(text: String) = ""
}
open <!CONFLICTING_INHERITED_MEMBERS!>class X1<!> : A(), I
open <!CONFLICTING_INHERITED_MEMBERS!>class X2<!> : X1()
// for some reason no error in K1
open class B {
fun <T> some(s: String): T = null!!
fun some(text: String) = ""
}
open class X3 : B()
open class X4 : X3()
open class C {
fun <T> some(s: String): T = null!!
}
open class X5 : C() {
<!CONFLICTING_OVERLOADS!>fun some(text: String)<!> = ""
}
open <!CONFLICTING_INHERITED_MEMBERS!>class X6<!> : X5()
@@ -0,0 +1,31 @@
// SKIP_TXT
open class A {
fun <T> some(s: String): T = null!!
}
interface I {
fun some(text: String) = ""
}
open <!CONFLICTING_INHERITED_MEMBERS!>class X1<!> : A(), I
open class X2 : X1()
// for some reason no error in K1
open class B {
fun <T> some(s: String): T = null!!
fun some(text: String) = ""
}
open class X3 : B()
open class X4 : X3()
open class C {
fun <T> some(s: String): T = null!!
}
open class X5 : C() {
<!CONFLICTING_OVERLOADS!>fun some(text: String)<!> = ""
}
open class X6 : X5()
@@ -1,13 +0,0 @@
interface A {
fun <T> foo()
fun <T> bar()
}
interface B {
fun foo()
fun bar()
}
<!CONFLICTING_INHERITED_MEMBERS!>interface C1<!> : A, B {
override fun bar()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface A { interface A {
fun <T> foo() fun <T> foo()
fun <T> bar() fun <T> bar()
@@ -24135,6 +24135,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/override/clashesOnInheritance"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true);
} }
@Test
@TestMetadata("conflictingInherited.kt")
public void testConflictingInherited() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/conflictingInherited.kt");
}
@Test @Test
@TestMetadata("covariantOverrides.kt") @TestMetadata("covariantOverrides.kt")
public void testCovariantOverrides() throws Exception { public void testCovariantOverrides() throws Exception {