提交 5f9357eb 编写于 作者: J Jinseong Jeon 提交者: Mikhail Glukhikh

FIR: transform implicit type ref in anonymous function arguments & body

^KT-45010 Fixed
上级 a841a0bb
...@@ -34693,6 +34693,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti ...@@ -34693,6 +34693,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/kt4711.kt"); 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 @Test
@TestMetadata("samAgainstFunctionalType.kt") @TestMetadata("samAgainstFunctionalType.kt")
public void testSamAgainstFunctionalType() throws Exception { public void testSamAgainstFunctionalType() throws Exception {
...@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind ...@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic 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.expressions.*
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
...@@ -436,7 +437,10 @@ class FirCallCompletionResultsWriterTransformer( ...@@ -436,7 +437,10 @@ class FirCallCompletionResultsWriterTransformer(
// Control flow info is necessary prerequisite because we collect return expressions in that function // Control flow info is necessary prerequisite because we collect return expressions in that function
// //
// Example: second lambda in the call like list.filter({}, {}) // 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 -> val expectedType = data?.getExpectedType(anonymousFunction)?.let { expectedArgumentType ->
// From the argument mapping, the expected type of this anonymous function would be: // From the argument mapping, the expected type of this anonymous function would be:
...@@ -509,6 +513,33 @@ class FirCallCompletionResultsWriterTransformer( ...@@ -509,6 +513,33 @@ class FirCallCompletionResultsWriterTransformer(
return result 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( override fun transformReturnExpression(
returnExpression: FirReturnExpression, returnExpression: FirReturnExpression,
data: ExpectedArgumentType? data: ExpectedArgumentType?
......
// KT-45010
fun foo(map: MutableMap<Int, String>) {
map.<!INAPPLICABLE_CANDIDATE!>getOrPut<!>("Not an Int") {
"Hello" + " world"
}
}
// KT-45010
fun foo(map: MutableMap<Int, String>) {
map.getOrPut(<!TYPE_MISMATCH!>"Not an Int"<!>) {
"Hello" + " world"
}
}
package
public fun foo(/*0*/ map: kotlin.collections.MutableMap<kotlin.Int, kotlin.String>): kotlin.Unit
...@@ -34789,6 +34789,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { ...@@ -34789,6 +34789,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/kt4711.kt"); 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 @Test
@TestMetadata("samAgainstFunctionalType.kt") @TestMetadata("samAgainstFunctionalType.kt")
public void testSamAgainstFunctionalType() throws Exception { public void testSamAgainstFunctionalType() throws Exception {
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册