Expected function type used for parameter types inference in function expression
This commit is contained in:
@@ -70,7 +70,7 @@ class FunctionDescriptorResolver(
|
|||||||
CallableMemberDescriptor.Kind.DECLARATION,
|
CallableMemberDescriptor.Kind.DECLARATION,
|
||||||
function.toSourceElement()
|
function.toSourceElement()
|
||||||
)
|
)
|
||||||
initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, null)
|
initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, TypeUtils.NO_EXPECTED_TYPE)
|
||||||
initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo)
|
initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo)
|
||||||
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor)
|
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor)
|
||||||
return functionDescriptor
|
return functionDescriptor
|
||||||
@@ -81,7 +81,8 @@ class FunctionDescriptorResolver(
|
|||||||
scope: JetScope,
|
scope: JetScope,
|
||||||
function: JetNamedFunction,
|
function: JetNamedFunction,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
dataFlowInfo: DataFlowInfo
|
dataFlowInfo: DataFlowInfo,
|
||||||
|
expectedFunctionType: JetType
|
||||||
): SimpleFunctionDescriptor {
|
): SimpleFunctionDescriptor {
|
||||||
val functionDescriptor = FunctionExpressionDescriptor(
|
val functionDescriptor = FunctionExpressionDescriptor(
|
||||||
containingDescriptor,
|
containingDescriptor,
|
||||||
@@ -90,7 +91,7 @@ class FunctionDescriptorResolver(
|
|||||||
CallableMemberDescriptor.Kind.DECLARATION,
|
CallableMemberDescriptor.Kind.DECLARATION,
|
||||||
function.toSourceElement()
|
function.toSourceElement()
|
||||||
)
|
)
|
||||||
initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, null)
|
initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, expectedFunctionType)
|
||||||
initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo)
|
initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo)
|
||||||
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor)
|
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor)
|
||||||
return functionDescriptor
|
return functionDescriptor
|
||||||
@@ -128,7 +129,7 @@ class FunctionDescriptorResolver(
|
|||||||
function: JetFunction,
|
function: JetFunction,
|
||||||
functionDescriptor: SimpleFunctionDescriptorImpl,
|
functionDescriptor: SimpleFunctionDescriptorImpl,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
expectedFunctionType: JetType?
|
expectedFunctionType: JetType
|
||||||
) {
|
) {
|
||||||
val innerScope = WritableScopeImpl(scope, functionDescriptor, TraceBasedRedeclarationHandler(trace), "Function descriptor header scope")
|
val innerScope = WritableScopeImpl(scope, functionDescriptor, TraceBasedRedeclarationHandler(trace), "Function descriptor header scope")
|
||||||
innerScope.addLabeledDeclaration(functionDescriptor)
|
innerScope.addLabeledDeclaration(functionDescriptor)
|
||||||
@@ -170,7 +171,7 @@ class FunctionDescriptorResolver(
|
|||||||
functionDescriptor: SimpleFunctionDescriptorImpl,
|
functionDescriptor: SimpleFunctionDescriptorImpl,
|
||||||
innerScope: WritableScopeImpl,
|
innerScope: WritableScopeImpl,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
expectedFunctionType: JetType?
|
expectedFunctionType: JetType
|
||||||
): List<ValueParameterDescriptor> {
|
): List<ValueParameterDescriptor> {
|
||||||
val expectedValueParameters = expectedFunctionType.getValueParameters(functionDescriptor)
|
val expectedValueParameters = expectedFunctionType.getValueParameters(functionDescriptor)
|
||||||
if (expectedValueParameters != null) {
|
if (expectedValueParameters != null) {
|
||||||
@@ -198,11 +199,11 @@ class FunctionDescriptorResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun JetType.functionTypeExpected() = !TypeUtils.noExpectedType(this) && KotlinBuiltIns.isFunctionOrExtensionFunctionType(this)
|
private fun JetType.functionTypeExpected() = !TypeUtils.noExpectedType(this) && KotlinBuiltIns.isFunctionOrExtensionFunctionType(this)
|
||||||
private fun JetType?.getReceiverType(): JetType? =
|
private fun JetType.getReceiverType(): JetType? =
|
||||||
if (this != null && functionTypeExpected()) getReceiverType(this) else null
|
if (functionTypeExpected()) KotlinBuiltIns.getReceiverType(this) else null
|
||||||
|
|
||||||
private fun JetType?.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? =
|
private fun JetType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? =
|
||||||
if (this != null && functionTypeExpected()) getValueParameters(owner, this) else null
|
if (functionTypeExpected()) KotlinBuiltIns.getValueParameters(owner, this) else null
|
||||||
|
|
||||||
public fun resolvePrimaryConstructorDescriptor(
|
public fun resolvePrimaryConstructorDescriptor(
|
||||||
scope: JetScope,
|
scope: JetScope,
|
||||||
@@ -316,7 +317,8 @@ class FunctionDescriptorResolver(
|
|||||||
else {
|
else {
|
||||||
type = TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE
|
type = TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
trace.report(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.on(valueParameter))
|
trace.report(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.on(valueParameter))
|
||||||
type = ErrorUtils.createErrorType("Type annotation was missing for parameter ${valueParameter.getNameAsSafeName()}")
|
type = ErrorUtils.createErrorType("Type annotation was missing for parameter ${valueParameter.getNameAsSafeName()}")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -83,7 +83,7 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
functionDescriptor = services.getFunctionDescriptorResolver().resolveFunctionExpressionDescriptor(
|
functionDescriptor = services.getFunctionDescriptorResolver().resolveFunctionExpressionDescriptor(
|
||||||
context.scope.getContainingDeclaration(), context.scope, function, context.trace, context.dataFlowInfo)
|
context.scope.getContainingDeclaration(), context.scope, function, context.trace, context.dataFlowInfo, context.expectedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace)
|
val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ fun testParamType() {
|
|||||||
bar.checkType { it : _<(String) -> Unit> }
|
bar.checkType { it : _<(String) -> Unit> }
|
||||||
|
|
||||||
val bas: (String) -> Unit = fun (param: String) {}
|
val bas: (String) -> Unit = fun (param: String) {}
|
||||||
val bag: (Int) -> Unit = <!TYPE_MISMATCH!>fun (param: String) {}<!>
|
val bag: (Int) -> Unit = <!TYPE_MISMATCH!>fun (<!EXPECTED_PARAMETER_TYPE_MISMATCH!>param: String<!>) {}<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testReceiverType() {
|
fun testReceiverType() {
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||||
|
|
||||||
|
val a = fun (<!CANNOT_INFER_PARAMETER_TYPE!>x<!>) = <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>
|
||||||
|
|
||||||
|
val b: (Int) -> Int = fun (x) = x + 3
|
||||||
|
|
||||||
|
val c: (Int, String) -> Int = <!TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(x)<!> = 3<!>
|
||||||
|
|
||||||
|
val d: (Int, String) -> Int = <!TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(x)<!> = 3<!>
|
||||||
|
|
||||||
|
val e: (Int, String) -> Int = <!TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>)<!> = 3<!>
|
||||||
|
|
||||||
|
val f: (Int) -> Int = <!TYPE_MISMATCH!>fun (<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>) = 3<!>
|
||||||
|
|
||||||
|
fun test1(a: (Int) -> Unit) {
|
||||||
|
test1(fun (<!CANNOT_INFER_PARAMETER_TYPE!>x<!>) { <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!> : Int})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test2(a: (Int) -> Unit) {
|
||||||
|
test2(<!TYPE_MISMATCH!>fun (x: String) {}<!>)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test3(a: (Int, String) -> Unit) {
|
||||||
|
test3(<!TYPE_MISMATCH!>fun (x: String) {}<!>)
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal val a: (???) -> [ERROR : Cannot be inferred]
|
||||||
|
internal val b: (kotlin.Int) -> kotlin.Int
|
||||||
|
internal val c: (kotlin.Int, kotlin.String) -> kotlin.Int
|
||||||
|
internal val d: (kotlin.Int, kotlin.String) -> kotlin.Int
|
||||||
|
internal val e: (kotlin.Int, kotlin.String) -> kotlin.Int
|
||||||
|
internal val f: (kotlin.Int) -> kotlin.Int
|
||||||
|
internal fun test1(/*0*/ a: (kotlin.Int) -> kotlin.Unit): kotlin.Unit
|
||||||
|
internal fun test2(/*0*/ a: (kotlin.Int) -> kotlin.Unit): kotlin.Unit
|
||||||
|
internal fun test3(/*0*/ a: (kotlin.Int, kotlin.String) -> kotlin.Unit): kotlin.Unit
|
||||||
@@ -4646,6 +4646,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("MissingParameterTypes.kt")
|
||||||
|
public void testMissingParameterTypes() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/functionAsExpression/MissingParameterTypes.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("NoOverloadError.kt")
|
@TestMetadata("NoOverloadError.kt")
|
||||||
public void testNoOverloadError() throws Exception {
|
public void testNoOverloadError() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/functionAsExpression/NoOverloadError.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/functionAsExpression/NoOverloadError.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user