NI: do type checking for anonymous functions not inside a call

^KT-38890 Fixed
^KT-38439 Fixed
This commit is contained in:
Victor Petukhov
2020-05-19 11:31:15 +03:00
parent 425ce8c3ab
commit eff5f3a242
18 changed files with 174 additions and 25 deletions
@@ -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