diff --git a/compiler/fir/analysis-tests/testData/resolve/problems/objectDerivedFromInnerClass.kt b/compiler/fir/analysis-tests/testData/resolve/problems/objectDerivedFromInnerClass.kt index c4675e18159..a6c2c2697ee 100644 --- a/compiler/fir/analysis-tests/testData/resolve/problems/objectDerivedFromInnerClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/problems/objectDerivedFromInnerClass.kt @@ -1,4 +1,4 @@ class Outer { open inner class Inner } fun test() { - val x = object : Outer.Inner() { } + val x = object : Outer.Inner() { } } diff --git a/compiler/fir/analysis-tests/testData/resolve/visibility/exposedSupertype.kt b/compiler/fir/analysis-tests/testData/resolve/visibility/exposedSupertype.kt index 3b73f5eba39..3708acddd99 100644 --- a/compiler/fir/analysis-tests/testData/resolve/visibility/exposedSupertype.kt +++ b/compiler/fir/analysis-tests/testData/resolve/visibility/exposedSupertype.kt @@ -38,7 +38,7 @@ interface E { } -class Test2 : A.APublicI, B.BInner() { +class Test2 : A.APublicI, B.BInner() { } @@ -50,7 +50,7 @@ class Test4 : E, A.AProtectedI { } -class Test5 : C.CPublicI, B.BInner() { +class Test5 : C.CPublicI, B.BInner() { } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index ef6ac44117b..8504c486f7e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -400,6 +400,11 @@ private fun mapInapplicableCandidateError( is AmbiguousInterceptedSymbol -> FirErrors.PLUGIN_AMBIGUOUS_INTERCEPTED_SYMBOL.createOn(source, rootCause.pluginNames) + is MissingInnerClassConstructorReceiver -> FirErrors.INNER_CLASS_CONSTRUCTOR_NO_RECEIVER.createOn( + source, + rootCause.candidateSymbol + ) + else -> genericDiagnostic } }.distinct() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt index 3e7db07f790..118ad8cc0db 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.delegatingConstructorScope import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.fir.types.typeContext import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.types.AbstractTypeChecker @@ -103,7 +104,7 @@ class FirTowerResolver( if (outerType != null) components.implicitReceiverStack.receiversAsReversed().drop(1).firstOrNull { AbstractTypeChecker.isSubtypeOf(components.session.typeContext, it.type, outerType) - } ?: return collector // TODO: report diagnostic about not-found receiver, KT-59677 + } else null @@ -120,7 +121,16 @@ class FirTowerResolver( scope, dispatchReceiver?.receiverExpression, givenExtensionReceiverOptions = emptyList() - ), + ).apply { + if (outerType != null && dispatchReceiver == null) { + val diagnostic = constructedType + .toRegularClassSymbol(context.session) + ?.let(::MissingInnerClassConstructorReceiver) + ?: InapplicableCandidate + + addDiagnostic(diagnostic) + } + }, context ) } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt index db8a37c4779..472e250d581 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeTypeVariable import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget @@ -166,4 +167,6 @@ class TypeVariableAsExplicitReceiver( object CallToDeprecatedOverrideOfHidden : ResolutionDiagnostic(RESOLVED) -class AmbiguousInterceptedSymbol(val pluginNames: List) : ResolutionDiagnostic(RESOLVED_WITH_ERROR) \ No newline at end of file +class AmbiguousInterceptedSymbol(val pluginNames: List) : ResolutionDiagnostic(RESOLVED_WITH_ERROR) + +class MissingInnerClassConstructorReceiver(val candidateSymbol: FirRegularClassSymbol) : ResolutionDiagnostic(INAPPLICABLE) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inner/classesInClassObjectHeader.fir.kt b/compiler/testData/diagnostics/tests/inner/classesInClassObjectHeader.fir.kt index 8aeb5dca6f8..ce2aff674d8 100644 --- a/compiler/testData/diagnostics/tests/inner/classesInClassObjectHeader.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/classesInClassObjectHeader.fir.kt @@ -1,6 +1,6 @@ class Test { @`InnerAnnotation` @InnerAnnotation - companion object : StaticClass(), InnerClass() { + companion object : StaticClass(), InnerClass() { } diff --git a/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.fir.kt b/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.fir.kt index 2a9f653a6a4..5c11101ebc2 100644 --- a/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.fir.kt @@ -5,8 +5,8 @@ class TestSome

{ } class Test { - companion object : InnerClass() { - val a = object: InnerClass() { + companion object : InnerClass() { + val a = object: InnerClass() { } fun more(): InnerClass { diff --git a/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.fir.kt b/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.fir.kt index 5998f3f60ca..d816d2717af 100644 --- a/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.fir.kt @@ -5,8 +5,8 @@ class TestSome

{ } class Test { - object Some : InnerClass() { - val a = object: InnerClass() { + object Some : InnerClass() { + val a = object: InnerClass() { } fun more(): InnerClass { diff --git a/compiler/testData/diagnostics/tests/inner/modality.fir.kt b/compiler/testData/diagnostics/tests/inner/modality.fir.kt index 64ad3c04c72..87eacfe0ede 100644 --- a/compiler/testData/diagnostics/tests/inner/modality.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/modality.fir.kt @@ -7,7 +7,7 @@ class Outer { class Nested1 : OpenNested() class Nested2 : FinalNested() - class Nested3 : OpenInner() + class Nested3 : OpenInner() class Nested4 : FinalInner() inner class Inner1 : OpenNested() diff --git a/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.fir.kt b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.fir.kt index c437687760e..f59075cfc1e 100644 --- a/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.fir.kt @@ -21,16 +21,16 @@ class Generic { open inner class Generic inner class Test1 : GI() - inner class Test2 : GIInt() + inner class Test2 : GIInt() inner class Test3 : GIStar() inner class Test3a : test.Generic<*>.Inner() inner class Test4 : GG() inner class Test5 : GG() - inner class Test6 : GG() - inner class Test7 : GG() - inner class Test8 : GIntG() - inner class Test9 : GGInt() + inner class Test6 : GG() + inner class Test7 : GG() + inner class Test8 : GIntG() + inner class Test9 : GGInt() inner class Test10 : GGInt() inner class Test11 : GG {