diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirFunInterfaceConstructorReferenceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirFunInterfaceConstructorReferenceChecker.kt index de130fb32ae..17f67001444 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirFunInterfaceConstructorReferenceChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirFunInterfaceConstructorReferenceChecker.kt @@ -6,17 +6,15 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.declaration.hasModifier import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn -import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction -import org.jetbrains.kotlin.fir.declarations.isInterface +import org.jetbrains.kotlin.fir.declarations.isFun import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference -import org.jetbrains.kotlin.lexer.KtTokens object FirFunInterfaceConstructorReferenceChecker : FirQualifiedAccessChecker() { override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { @@ -26,11 +24,10 @@ object FirFunInterfaceConstructorReferenceChecker : FirQualifiedAccessChecker() val referredDeclaration = reference.resolvedSymbol.fir if (referredDeclaration is FirSimpleFunction && - referredDeclaration.returnTypeRef.toRegularClass(context.session).isFunInterface() + referredDeclaration.origin == FirDeclarationOrigin.SamConstructor && + referredDeclaration.returnTypeRef.toRegularClass(context.session)?.isFun == true ) { reporter.reportOn(reference.source, FUN_INTERFACE_CONSTRUCTOR_REFERENCE, context) } } - - private fun FirRegularClass?.isFunInterface() = this != null && isInterface && hasModifier(KtTokens.FUN_KEYWORD) } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 588e85c9a99..aead931b6ec 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -689,7 +689,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(CANNOT_INFER_PARAMETER_TYPE, "cannot infer a type for this parameter. Please specify it explicitly.") // Fun interfaces - map.put(FUN_INTERFACE_CONSTRUCTOR_REFERENCE, "Functional interface constructor references are prohibited") + map.put(FUN_INTERFACE_CONSTRUCTOR_REFERENCE, "Functional/SAM interface constructor references are prohibited") // Properties & accessors map.put( diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt index 82c091d06ce..0951f09154b 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt @@ -81,6 +81,7 @@ inline val FirMemberDeclaration.isConst: Boolean get() = status.isConst inline val FirMemberDeclaration.isLateInit: Boolean get() = status.isLateInit inline val FirMemberDeclaration.isFromSealedClass: Boolean get() = status.isFromSealedClass inline val FirMemberDeclaration.isFromEnumClass: Boolean get() = status.isFromEnumClass +inline val FirMemberDeclaration.isFun: Boolean get() = status.isFun inline val FirFunction<*>.hasBody get() = body != null diff --git a/compiler/testData/diagnostics/tests/funInterface/prohibitFunInterfaceConstructorReferences.fir.kt b/compiler/testData/diagnostics/tests/funInterface/prohibitFunInterfaceConstructorReferences.fir.kt new file mode 100644 index 00000000000..e34a72ac745 --- /dev/null +++ b/compiler/testData/diagnostics/tests/funInterface/prohibitFunInterfaceConstructorReferences.fir.kt @@ -0,0 +1,7 @@ +fun interface Foo { + fun run() +} + +val x = ::Foo +val y = Foo { } +val z = ::Runnable diff --git a/compiler/testData/diagnostics/tests/funInterface/prohibitFunInterfaceConstructorReferences.kt b/compiler/testData/diagnostics/tests/funInterface/prohibitFunInterfaceConstructorReferences.kt index d515dd88574..aa4297708f0 100644 --- a/compiler/testData/diagnostics/tests/funInterface/prohibitFunInterfaceConstructorReferences.kt +++ b/compiler/testData/diagnostics/tests/funInterface/prohibitFunInterfaceConstructorReferences.kt @@ -1,5 +1,3 @@ -// FIR_IDENTICAL - fun interface Foo { fun run() }