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");
|
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 {
|
||||||
|
|||||||
+32
-1
@@ -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(
|
|||||||
// 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(
|
|||||||
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?
|
||||||
|
|||||||
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");
|
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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user