[IR] Fix missing AMBIGUOUS_ACTUALS
^KT-59938 Fixed Review: https://jetbrains.team/p/kt/reviews/13760 After this patch: > The /compiler/testData/diagnostics/tests/multiplatform/topLevelFun/conflictingImplDeclarations.kt test: Fixed > The /compiler/testData/diagnostics/tests/multiplatform/headerClass/expectDeclarationWithWeakIncompatibilities.kt test: Declarations are in the same module. `PACKAGE_OR_CLASSIFIER_REDECLARATION` is reported anyway > The /compiler/testData/diagnostics/tests/multiplatform/java/varPropertyAgainstJavaGetterAndNonFinalField.kt test: Expect-actual matcher doesn't match fields in K2 https://youtrack.jetbrains.com/issue/KT-63667 => green code > The /compiler/testData/diagnostics/tests/multiplatform/java/propertyAgainstJavaPrivateFieldAndPublicMethod.kt test: Expect-actual matcher doesn't match fields in K2 https://youtrack.jetbrains.com/issue/KT-63667 => green code > The /compiler/testData/diagnostics/tests/multiplatform/java/implicitJavaActualization_multipleActuals.kt test: K2 doesn't have implicit Java actualization. And PACKAGE_OR_CLASSIFIER_REDECLARATION is reported anyway > The /compiler/testData/diagnostics/tests/multiplatform/java/propertyAgainstJavaPublicFieldAndPublicGetter.kt test: Expect-actual matcher doesn't match fields in K2 https://youtrack.jetbrains.com/issue/KT-63667 => green code > The /compiler/testData/diagnostics/tests/multiplatform/actualClassifierMustHasTheSameMembersAsNonFinalExpectClassifierChecker/injectContextReceiverOverload.kt test: Context receivers are not supported in expect-actual matcher. https://youtrack.jetbrains.com/issue/KT-61447 And K2 reports another error right now anyway
This commit is contained in:
+2
-2
@@ -309,12 +309,12 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
|
||||
override fun onMatchedClasses(expectClassSymbol: IrClassSymbol, actualClassSymbol: IrClassSymbol) {
|
||||
destination[expectClassSymbol] = actualClassSymbol
|
||||
expectActualTracker?.reportWithCurrentFile(actualClassSymbol)
|
||||
recordActualForExpectDeclaration(expectClassSymbol, actualClassSymbol, destination)
|
||||
recordActualForExpectDeclaration(expectClassSymbol, actualClassSymbol, destination, diagnosticsReporter)
|
||||
}
|
||||
|
||||
override fun onMatchedCallables(expectSymbol: IrSymbol, actualSymbol: IrSymbol) {
|
||||
expectActualTracker?.reportWithCurrentFile(actualSymbol)
|
||||
recordActualForExpectDeclaration(expectSymbol, actualSymbol, destination)
|
||||
recordActualForExpectDeclaration(expectSymbol, actualSymbol, destination, diagnosticsReporter)
|
||||
}
|
||||
|
||||
override fun onIncompatibleMembersFromClassScope(
|
||||
|
||||
+6
-3
@@ -5,10 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.actualizer
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrDiagnosticReporter
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableDeclaration
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.isExpect
|
||||
@@ -25,7 +25,10 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
* This Actualizer processes expect overridable declarations in non-expect classes and replaces them with the associated actual overridable
|
||||
* declarations overriding the actual base class members.The newly created actual fake overrides are stored in expectActualMap.
|
||||
*/
|
||||
internal class FakeOverridesActualizer(private val expectActualMap: MutableMap<IrSymbol, IrSymbol>) : IrElementVisitorVoid {
|
||||
internal class FakeOverridesActualizer(
|
||||
private val expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
||||
private val diagnosticReporter: IrDiagnosticReporter
|
||||
) : IrElementVisitorVoid {
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
if (!declaration.isExpect) {
|
||||
actualizeFakeOverrides(declaration)
|
||||
@@ -47,7 +50,7 @@ internal class FakeOverridesActualizer(private val expectActualMap: MutableMap<I
|
||||
val actualizedOverrides = overriddenSymbols.map { (it.owner as IrDeclaration).actualize() }
|
||||
val actualFakeOverride = createFakeOverrideMember(actualizedOverrides, parent as IrClass)
|
||||
|
||||
recordActualForExpectDeclaration(this.symbol, actualFakeOverride.symbol, expectActualMap)
|
||||
recordActualForExpectDeclaration(this.symbol, actualFakeOverride.symbol, expectActualMap, diagnosticReporter)
|
||||
|
||||
return actualFakeOverride
|
||||
}
|
||||
|
||||
+7
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibil
|
||||
|
||||
internal object IrActualizationErrors {
|
||||
val NO_ACTUAL_FOR_EXPECT by error2<PsiElement, String, ModuleDescriptor>()
|
||||
val AMBIGUOUS_ACTUALS by error2<PsiElement, String, ModuleDescriptor>()
|
||||
val EXPECT_ACTUAL_MISMATCH by error3<PsiElement, String, String, ExpectActualMatchingCompatibility.Mismatch>()
|
||||
val EXPECT_ACTUAL_INCOMPATIBILITY by error3<PsiElement, String, String, ExpectActualCheckingCompatibility.Incompatible<*>>()
|
||||
val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning3<PsiElement, IrSymbol, IrSymbol, ExpectActualAnnotationsIncompatibilityType<IrConstructorCall>>()
|
||||
@@ -34,6 +35,12 @@ internal object IrActualizationErrors {
|
||||
|
||||
internal object KtDefaultIrActualizationErrorMessages : BaseDiagnosticRendererFactory() {
|
||||
override val MAP = KtDiagnosticFactoryToRendererMap("KT").also { map ->
|
||||
map.put(
|
||||
IrActualizationErrors.AMBIGUOUS_ACTUALS,
|
||||
"{0} has several compatible actual declarations in modules {1}",
|
||||
CommonRenderers.STRING,
|
||||
IrActualizationDiagnosticRenderers.MODULE_WITH_PLATFORM,
|
||||
)
|
||||
map.put(
|
||||
IrActualizationErrors.NO_ACTUAL_FOR_EXPECT,
|
||||
"Expected {0} has no actual declaration in module {1}",
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ class IrActualizer(
|
||||
if (!useIrFakeOverrideBuilder) {
|
||||
// 2. Actualize expect fake overrides in non-expect classes inside common or multi-platform module.
|
||||
// It's probably important to run FakeOverridesActualizer before ActualFakeOverridesAdder
|
||||
FakeOverridesActualizer(expectActualMap).apply { dependentFragments.forEach { visitModuleFragment(it) } }
|
||||
FakeOverridesActualizer(expectActualMap, ktDiagnosticReporter).apply { dependentFragments.forEach { visitModuleFragment(it) } }
|
||||
|
||||
// 3. Add fake overrides to non-expect classes inside common or multi-platform module,
|
||||
// taken from these non-expect classes actualized super classes.
|
||||
|
||||
+12
-8
@@ -55,18 +55,13 @@ internal fun recordActualForExpectDeclaration(
|
||||
expectSymbol: IrSymbol,
|
||||
actualSymbol: IrSymbol,
|
||||
destination: MutableMap<IrSymbol, IrSymbol>,
|
||||
diagnosticsReporter: IrDiagnosticReporter,
|
||||
) {
|
||||
val expectDeclaration = expectSymbol.owner as IrDeclarationBase
|
||||
val actualDeclaration = actualSymbol.owner as IrDeclaration
|
||||
val registeredActual = destination.put(expectSymbol, actualSymbol)
|
||||
require(registeredActual == null || registeredActual == actualSymbol) {
|
||||
"""
|
||||
Expect symbol already has registered mapping
|
||||
|
||||
Expect declaration: ${expectDeclaration.render()}
|
||||
Actual declaration: ${actualDeclaration.render()}
|
||||
Already registered: ${registeredActual!!.owner.render()}
|
||||
""".trimIndent()
|
||||
if (registeredActual != null && registeredActual != actualSymbol) {
|
||||
diagnosticsReporter.reportAmbiguousActuals(expectDeclaration)
|
||||
}
|
||||
if (expectDeclaration is IrTypeParametersContainer) {
|
||||
recordTypeParametersMapping(destination, expectDeclaration, actualDeclaration as IrTypeParametersContainer)
|
||||
@@ -107,6 +102,15 @@ internal fun IrDiagnosticReporter.reportMissingActual(irDeclaration: IrDeclarati
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
internal fun IrDiagnosticReporter.reportAmbiguousActuals(expectSymbol: IrDeclaration) {
|
||||
at(expectSymbol).report(
|
||||
IrActualizationErrors.AMBIGUOUS_ACTUALS,
|
||||
(expectSymbol as? IrDeclarationWithName)?.name?.asString().orEmpty(),
|
||||
expectSymbol.module
|
||||
)
|
||||
}
|
||||
|
||||
internal fun IrDiagnosticReporter.reportExpectActualIncompatibility(
|
||||
expectSymbol: IrSymbol,
|
||||
actualSymbol: IrSymbol,
|
||||
|
||||
Reference in New Issue
Block a user