NI: do type checking for anonymous functions not inside a call
^KT-38890 Fixed ^KT-38439 Fixed
This commit is contained in:
+30
-9
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.resolve.BindingContext.EXPECTED_RETURN_TYPE
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.checkers.TrailingCommaChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.TrailingCommaDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope
|
||||
@@ -116,17 +115,35 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
return if (isDeclaration) {
|
||||
createTypeInfo(components.dataFlowAnalyzer.checkStatementType(function, context), context)
|
||||
} else {
|
||||
val expectedType = context.expectedType
|
||||
|
||||
val functionalTypeExpected = expectedType.isBuiltinFunctionalType()
|
||||
val newInferenceEnabled = components.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
|
||||
|
||||
// We forbid anonymous function expressions to suspend type coercion for now, until `suspend fun` syntax is supported
|
||||
val resultType = functionDescriptor.createFunctionType(components.builtIns, suspendFunction = false)
|
||||
val resultType = functionDescriptor.createFunctionType(
|
||||
components.builtIns,
|
||||
suspendFunction = false
|
||||
)
|
||||
|
||||
if (components.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) && functionalTypeExpected && !expectedType.isSuspendFunctionType)
|
||||
if (newInferenceEnabled) {
|
||||
// We should avoid type checking for types containing `NO_EXPECTED_TYPE`, the error will be report later if needed
|
||||
if (!context.expectedType.contains { it === NO_EXPECTED_TYPE }) {
|
||||
/*
|
||||
* We do type checking without converted vararg type as the new inference create expected type with raw vararg type (see KotlinResolutionCallbacksImpl.kt)
|
||||
* Example:
|
||||
* fun foo(x: Any?) {}
|
||||
* val x = foo(fun(vararg p: Int) {})
|
||||
* In NI, context.expectedType = `Function1<Int, Unit>`
|
||||
*/
|
||||
val typeToTypeCheck = functionDescriptor.createFunctionType(
|
||||
components.builtIns,
|
||||
suspendFunction = false,
|
||||
shouldUseVarargType = true
|
||||
)
|
||||
components.dataFlowAnalyzer.checkType(typeToTypeCheck, function, context)
|
||||
}
|
||||
createTypeInfo(resultType, context)
|
||||
else
|
||||
} else {
|
||||
components.dataFlowAnalyzer.createCheckedTypeInfo(resultType, context, function)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,12 +387,16 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
}
|
||||
}
|
||||
|
||||
fun SimpleFunctionDescriptor.createFunctionType(builtIns: KotlinBuiltIns, suspendFunction: Boolean = false): KotlinType? {
|
||||
fun SimpleFunctionDescriptor.createFunctionType(
|
||||
builtIns: KotlinBuiltIns,
|
||||
suspendFunction: Boolean = false,
|
||||
shouldUseVarargType: Boolean = false
|
||||
): KotlinType? {
|
||||
return createFunctionType(
|
||||
builtIns,
|
||||
Annotations.EMPTY,
|
||||
extensionReceiverParameter?.type,
|
||||
valueParameters.map { it.type },
|
||||
if (shouldUseVarargType) valueParameters.map { it.varargElementType ?: it.type } else valueParameters.map { it.type },
|
||||
null,
|
||||
returnType ?: return null,
|
||||
suspendFunction = suspendFunction
|
||||
|
||||
Reference in New Issue
Block a user