[FIR] Prevent missing diagnostics on free lambdas

The change in `FirPsiDiagnosticTestGenerated.Resolve#testCast`
only highlights the existing
problem that we don't assign a
valid type to `_`.

^KT-58906 Fixed
This commit is contained in:
Nikolay Lunyak
2023-08-07 15:58:16 +03:00
committed by Space Team
parent 9a719066e3
commit 71cc634a7c
18 changed files with 73 additions and 20 deletions
@@ -195,6 +195,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
}
@Test
@TestMetadata("compilerCrashParameterType.kt")
public void testCompilerCrashParameterType() throws Exception {
runTest("compiler/testData/diagnostics/tests/compilerCrashParameterType.kt");
}
@Test
@TestMetadata("Constants.kt")
public void testConstants() throws Exception {
@@ -195,6 +195,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
}
@Test
@TestMetadata("compilerCrashParameterType.kt")
public void testCompilerCrashParameterType() throws Exception {
runTest("compiler/testData/diagnostics/tests/compilerCrashParameterType.kt");
}
@Test
@TestMetadata("Constants.kt")
public void testConstants() throws Exception {
+1 -1
View File
@@ -4,4 +4,4 @@ val y = 2 as Any
val f = fun() = 3 as Any
val g = {}
val h: (String) -> Boolean = { _ -> false }
val hError = { _ -> true }
val hError = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>_<!> -> true }
@@ -195,6 +195,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
}
@Test
@TestMetadata("compilerCrashParameterType.kt")
public void testCompilerCrashParameterType() throws Exception {
runTest("compiler/testData/diagnostics/tests/compilerCrashParameterType.kt");
}
@Test
@TestMetadata("Constants.kt")
public void testConstants() throws Exception {
@@ -195,6 +195,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
}
@Test
@TestMetadata("compilerCrashParameterType.kt")
public void testCompilerCrashParameterType() throws Exception {
runTest("compiler/testData/diagnostics/tests/compilerCrashParameterType.kt");
}
@Test
@TestMetadata("Constants.kt")
public void testConstants() throws Exception {
@@ -118,7 +118,7 @@ private fun ConeDiagnostic.toKtDiagnostic(
is ConeSyntaxDiagnostic -> FirSyntaxErrors.SYNTAX.createOn(callOrAssignmentSource ?: source, reason)
is ConeSimpleDiagnostic -> when {
source?.kind is KtFakeSourceElementKind && source.kind != KtFakeSourceElementKind.ReferenceInAtomicQualifiedAccess -> null
(source?.kind as? KtFakeSourceElementKind)?.canBeIgnored == true -> null
else -> this.getFactory(source).createOn(callOrAssignmentSource ?: source)
}
@@ -155,6 +155,10 @@ private fun ConeDiagnostic.toKtDiagnostic(
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
}
private val KtFakeSourceElementKind.canBeIgnored: Boolean
get() = this != KtFakeSourceElementKind.ReferenceInAtomicQualifiedAccess
&& this != KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter
fun FirBasedSymbol<*>.toInvisibleReferenceDiagnostic(source: KtSourceElement?): KtDiagnostic? = when (val symbol = this) {
is FirCallableSymbol<*> -> FirErrors.INVISIBLE_REFERENCE.createOn(source, symbol, symbol.visibility, symbol.callableId.classId)
is FirClassLikeSymbol<*> -> FirErrors.INVISIBLE_REFERENCE.createOn(source, symbol, symbol.visibility, symbol.classId.outerClassId)
@@ -1077,7 +1077,10 @@ open class FirDeclarationsResolveTransformer(
"No type for parameter",
DiagnosticKind.ValueParameterWithNoTypeAnnotation
)
)
),
fallbackSource = valueParameter.source?.fakeElement(
KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter,
),
)
)
}
@@ -5,7 +5,7 @@ fun test(<!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!>, <!VALUE_PARAMETER_WITH
class A(a<!SYNTAX!><!>)
val bar = fun(a){}
val bar = fun(<!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!>){}
val la = { a -> }
val la = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!> -> }
val las = { a: Int -> }
@@ -0,0 +1,8 @@
// ISSUE: KT-58906
fun someFun(i: Int) = 42
fun someSad(i: () -> String) = 42
fun main(args: Array<String>) {
{ <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>x<!> -> someFun(x) } //here should be CANNOT_INFER_PARAMETER_TYPE
}
@@ -0,0 +1,8 @@
// ISSUE: KT-58906
fun someFun(i: Int) = 42
fun someSad(i: () -> String) = 42
fun main(args: Array<String>) {
{ <!CANNOT_INFER_PARAMETER_TYPE!>x<!> -> someFun(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>) } //here should be CANNOT_INFER_PARAMETER_TYPE
}
@@ -1,7 +1,7 @@
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
val a = fun (x) = x
val a = fun (<!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>x<!>) = x
val b: (Int) -> Int = fun (x) = x + 3
@@ -9,8 +9,8 @@ val returnTypeWithParameter = { <!COMPONENT_FUNCTION_MISSING!>(b: Int): Int<!> -
val receiverWithFunctionType = { ((Int)<!SYNTAX!><!> <!SYNTAX!>-> Int).() -><!> }
val parenthesizedParameters = { <!COMPONENT_FUNCTION_MISSING!>(a: Int)<!> -> }
val parenthesizedParameters2 = { <!COMPONENT_FUNCTION_MISSING!>(b)<!> -> }
val parenthesizedParameters = { <!COMPONENT_FUNCTION_MISSING, VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>(a: Int)<!> -> }
val parenthesizedParameters2 = { <!COMPONENT_FUNCTION_MISSING, VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>(b)<!> -> }
val none = { -> }
@@ -18,7 +18,7 @@ val none = { -> }
val parameterWithFunctionType = { a: ((Int) -> Int) -> <!SYNTAX!><!>} // todo fix parser
val newSyntax = { a: Int -> }
val newSyntax1 = { a, b -> }
val newSyntax1 = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!>, <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>b<!> -> }
val newSyntax2 = { a: Int, b: Int -> }
val newSyntax3 = { a, b: Int -> }
val newSyntax4 = { a: Int, b -> }
val newSyntax3 = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!>, b: Int -> }
val newSyntax4 = { a: Int, <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>b<!> -> }
@@ -24,7 +24,7 @@ fun bar() {
y2 checkType { _<(A) -> Unit>() }
val z = { <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>(a: Int, b: String)<!> ->
val z = { <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING, VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>(a: Int, b: String)<!> ->
a checkType { _<Int>() }
b checkType { _<String>() }
}
@@ -1,6 +1,6 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
val la = { a -> }
val la = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!> -> }
val las = { a: Int -> }
val larg = { a -> }(123)
val twoarg = { a, b: String, c -> }(123, "asdf", 123)
val larg = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!> -> }(123)
val twoarg = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!>, b: String, <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>c<!> -> }(123, "asdf", 123)
@@ -1,7 +1,7 @@
fun test1(i: Int) = { i ->
fun test1(i: Int) = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>i<!> ->
i
}(i)
fun test2() = { i -> i }<!NO_VALUE_FOR_PARAMETER!>()<!>
fun test2() = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>i<!> -> i }<!NO_VALUE_FOR_PARAMETER!>()<!>
fun test3() = { i -> i }(1)
fun test3() = { <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>i<!> -> i }(1)
@@ -1,3 +1,3 @@
fun foo(a: Any) {
foo({ index -> } { })
foo({ <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>index<!> -> } { })
}
@@ -32,5 +32,5 @@ fun testParamCall() {
}
fun testNoContext() {
{ it -> it }
{ <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>it<!> -> it }
}
@@ -195,6 +195,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/comparisonOfGenericInterfaceWithGenericClass.kt");
}
@Test
@TestMetadata("compilerCrashParameterType.kt")
public void testCompilerCrashParameterType() throws Exception {
runTest("compiler/testData/diagnostics/tests/compilerCrashParameterType.kt");
}
@Test
@TestMetadata("Constants.kt")
public void testConstants() throws Exception {