FIR: transform implicit type ref in anonymous function arguments & body
^KT-45010 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
a841a0bbca
commit
5f9357eb41
+6
@@ -34693,6 +34693,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/kt4711.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaArgumentOfInapplicableCall.kt")
|
||||
public void testLambdaArgumentOfInapplicableCall() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("samAgainstFunctionalType.kt")
|
||||
public void testSamAgainstFunctionalType() throws Exception {
|
||||
|
||||
+32
-1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
|
||||
@@ -436,7 +437,10 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
// Control flow info is necessary prerequisite because we collect return expressions in that function
|
||||
//
|
||||
// Example: second lambda in the call like list.filter({}, {})
|
||||
if (!dataFlowAnalyzer.isThereControlFlowInfoForAnonymousFunction(anonymousFunction)) return anonymousFunction.compose()
|
||||
if (!dataFlowAnalyzer.isThereControlFlowInfoForAnonymousFunction(anonymousFunction)) {
|
||||
// But, don't leave implicit type refs behind
|
||||
return transformImplicitTypeRefInAnonymousFunction(anonymousFunction)
|
||||
}
|
||||
|
||||
val expectedType = data?.getExpectedType(anonymousFunction)?.let { expectedArgumentType ->
|
||||
// From the argument mapping, the expected type of this anonymous function would be:
|
||||
@@ -509,6 +513,33 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun transformImplicitTypeRefInAnonymousFunction(
|
||||
anonymousFunction: FirAnonymousFunction
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
val implicitTypeTransformer = object : FirDefaultTransformer<Nothing?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return (element.transformChildren(this, data) as E).compose()
|
||||
}
|
||||
|
||||
override fun transformImplicitTypeRef(
|
||||
implicitTypeRef: FirImplicitTypeRef,
|
||||
data: Nothing?
|
||||
): CompositeTransformResult<FirTypeRef> =
|
||||
buildErrorTypeRef {
|
||||
source = implicitTypeRef.source
|
||||
// NB: this error message assumes that it is used only if CFG for the anonymous function is not available
|
||||
diagnostic = ConeSimpleDiagnostic("Cannot infer type w/o CFG", DiagnosticKind.InferenceError)
|
||||
}.compose()
|
||||
|
||||
}
|
||||
// NB: if we transform simply all children, there would be too many type error reports.
|
||||
anonymousFunction.transformReturnTypeRef(implicitTypeTransformer, null)
|
||||
anonymousFunction.transformValueParameters(implicitTypeTransformer, null)
|
||||
anonymousFunction.transformBody(implicitTypeTransformer, null)
|
||||
return anonymousFunction.compose()
|
||||
}
|
||||
|
||||
override fun transformReturnExpression(
|
||||
returnExpression: FirReturnExpression,
|
||||
data: ExpectedArgumentType?
|
||||
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
// KT-45010
|
||||
fun foo(map: MutableMap<Int, String>) {
|
||||
map.<!INAPPLICABLE_CANDIDATE!>getOrPut<!>("Not an Int") {
|
||||
"Hello" + " world"
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// KT-45010
|
||||
fun foo(map: MutableMap<Int, String>) {
|
||||
map.getOrPut(<!TYPE_MISMATCH!>"Not an Int"<!>) {
|
||||
"Hello" + " world"
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
public fun foo(/*0*/ map: kotlin.collections.MutableMap<kotlin.Int, kotlin.String>): kotlin.Unit
|
||||
Generated
+6
@@ -34789,6 +34789,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/kt4711.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaArgumentOfInapplicableCall.kt")
|
||||
public void testLambdaArgumentOfInapplicableCall() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("samAgainstFunctionalType.kt")
|
||||
public void testSamAgainstFunctionalType() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user