[FIR] Report INNER_CLASS_CONSTRUCTOR_NO_RECEIVER on delegated constructor calls

#KT-59677 Fixed
This commit is contained in:
Kirill Rakhman
2024-03-18 17:45:41 +01:00
committed by Space Team
parent a13756cfe9
commit 72235b8527
10 changed files with 35 additions and 17 deletions
@@ -1,4 +1,4 @@
class Outer { open inner class Inner }
fun test() {
val x = object : <!UNRESOLVED_REFERENCE!>Outer.Inner<!>() { }
val x = object : <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>Outer.Inner<!>() { }
}
@@ -38,7 +38,7 @@ interface E {
}
class Test2 : A.APublicI, <!FINAL_SUPERTYPE, UNRESOLVED_REFERENCE!>B.BInner<!>() {
class Test2 : A.APublicI, <!FINAL_SUPERTYPE, INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>B.BInner<!>() {
}
@@ -50,7 +50,7 @@ class Test4 : E, A.<!INVISIBLE_REFERENCE!>AProtectedI<!> {
}
class Test5 : C.CPublicI, <!FINAL_SUPERTYPE, UNRESOLVED_REFERENCE!>B.BInner<!>() {
class Test5 : C.CPublicI, <!FINAL_SUPERTYPE, INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>B.BInner<!>() {
}
@@ -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()
@@ -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
)
}
@@ -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
@@ -167,3 +168,5 @@ class TypeVariableAsExplicitReceiver(
object CallToDeprecatedOverrideOfHidden : ResolutionDiagnostic(RESOLVED)
class AmbiguousInterceptedSymbol(val pluginNames: List<String>) : ResolutionDiagnostic(RESOLVED_WITH_ERROR)
class MissingInnerClassConstructorReceiver(val candidateSymbol: FirRegularClassSymbol) : ResolutionDiagnostic(INAPPLICABLE)
@@ -1,6 +1,6 @@
class Test {
@`InnerAnnotation` <!REPEATED_ANNOTATION!>@InnerAnnotation<!>
companion object : StaticClass(), <!MANY_CLASSES_IN_SUPERTYPE_LIST, UNRESOLVED_REFERENCE!>InnerClass<!>() {
companion object : StaticClass(), <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER, MANY_CLASSES_IN_SUPERTYPE_LIST!>InnerClass<!>() {
}
@@ -5,8 +5,8 @@ class TestSome<P> {
}
class Test {
companion object : <!UNRESOLVED_REFERENCE!>InnerClass<!>() {
val a = object: <!UNRESOLVED_REFERENCE!>InnerClass<!>() {
companion object : <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>InnerClass<!>() {
val a = object: <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>InnerClass<!>() {
}
fun more(): InnerClass {
@@ -5,8 +5,8 @@ class TestSome<P> {
}
class Test {
object Some : <!UNRESOLVED_REFERENCE!>InnerClass<!>() {
val a = object: <!UNRESOLVED_REFERENCE!>InnerClass<!>() {
object Some : <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>InnerClass<!>() {
val a = object: <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>InnerClass<!>() {
}
fun more(): InnerClass {
+1 -1
View File
@@ -7,7 +7,7 @@ class Outer {
class Nested1 : OpenNested()
class Nested2 : <!FINAL_SUPERTYPE!>FinalNested<!>()
class Nested3 : <!UNRESOLVED_REFERENCE!>OpenInner<!>()
class Nested3 : <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>OpenInner<!>()
class Nested4 : <!FINAL_SUPERTYPE!>FinalInner<!>()
inner class Inner1 : OpenNested()
@@ -21,16 +21,16 @@ class Generic<T1> {
open inner class Generic<T2>
inner class Test1 : GI<T1>()
inner class Test2 : <!UNRESOLVED_REFERENCE!>GIInt<!>()
inner class Test2 : <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>GIInt<!>()
inner class Test3 : <!CONSTRUCTOR_OR_SUPERTYPE_ON_TYPEALIAS_WITH_TYPE_PROJECTION_WARNING!>GIStar<!>()
inner class Test3a : test.Generic<<!PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE!>*<!>>.Inner()
inner class Test4<T2> : GG<T1, T2>()
inner class Test5 : GG<T1, Int>()
inner class Test6 : <!UNRESOLVED_REFERENCE!>GG<Int, T1><!>()
inner class Test7 : <!UNRESOLVED_REFERENCE!>GG<Int, Int><!>()
inner class Test8 : <!UNRESOLVED_REFERENCE!>GIntG<Int><!>()
inner class Test9 : <!UNRESOLVED_REFERENCE!>GGInt<Int><!>()
inner class Test6 : <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>GG<Int, T1><!>()
inner class Test7 : <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>GG<Int, Int><!>()
inner class Test8 : <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>GIntG<Int><!>()
inner class Test9 : <!INNER_CLASS_CONSTRUCTOR_NO_RECEIVER!>GGInt<Int><!>()
inner class Test10 : GGInt<T1>()
inner class Test11 : GG<T1, Int> {