From fd5a2056c13cb9286897a7fb44e9ea7cd8f05571 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 27 Aug 2013 16:12:49 +0400 Subject: [PATCH] analyze labeled function literals as usual ones (specially as function literals, not as other expressions) --- .../lang/resolve/calls/ArgumentTypeResolver.java | 11 +++++++---- .../jet/lang/resolve/calls/CandidateResolver.java | 14 ++++++++------ .../functionLiterals/LabeledFunctionLiterals.kt | 15 +++++++++++++++ .../jet/checkers/JetDiagnosticsTestGenerated.java | 5 +++++ 4 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/functionLiterals/LabeledFunctionLiterals.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java index ab64f4b0437..edf03b9f90a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java @@ -166,8 +166,9 @@ public class ArgumentTypeResolver { if (expression == null) { return JetTypeInfo.create(null, context.dataFlowInfo); } - if (expression instanceof JetFunctionLiteralExpression) { - return getFunctionLiteralTypeInfo((JetFunctionLiteralExpression) expression, context, resolveArgumentsMode); + JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesizeWithNoTypeResolution(expression, false); + if (deparenthesizedExpression instanceof JetFunctionLiteralExpression) { + return getFunctionLiteralTypeInfo(expression, (JetFunctionLiteralExpression) deparenthesizedExpression, context, resolveArgumentsMode); } JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext()); if (recordedTypeInfo != null) { @@ -181,6 +182,7 @@ public class ArgumentTypeResolver { @NotNull public JetTypeInfo getFunctionLiteralTypeInfo( + @NotNull JetExpression expression, @NotNull JetFunctionLiteralExpression functionLiteralExpression, @NotNull CallResolutionContext context, @NotNull ResolveArgumentsMode resolveArgumentsMode @@ -189,7 +191,7 @@ public class ArgumentTypeResolver { JetType type = getFunctionLiteralType(functionLiteralExpression, context.scope, context.trace); return JetTypeInfo.create(type, context.dataFlowInfo); } - return expressionTypingServices.getTypeInfo(context.scope, functionLiteralExpression, context.expectedType, context.dataFlowInfo, context.trace); + return expressionTypingServices.getTypeInfo(expression, context); } @Nullable @@ -212,7 +214,8 @@ public class ArgumentTypeResolver { JetType returnType = resolveTypeRefWithDefault(functionLiteral.getReturnTypeRef(), scope, temporaryTrace, DONT_CARE); assert returnType != null; JetType receiverType = resolveTypeRefWithDefault(functionLiteral.getReceiverTypeRef(), scope, temporaryTrace, null); - return KotlinBuiltIns.getInstance().getFunctionType(Collections.emptyList(), receiverType, parameterTypes, returnType); + return KotlinBuiltIns.getInstance().getFunctionType(Collections.emptyList(), receiverType, parameterTypes, + returnType); } @Nullable diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index 6696a5758d6..0ce8343eca1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -217,8 +217,6 @@ public class CandidateResolver { ValueParameterDescriptor valueParameterDescriptor = entry.getKey(); for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) { - if (!(valueArgument.getArgumentExpression() instanceof JetFunctionLiteralExpression)) continue; - addConstraintForFunctionLiteral(valueArgument, valueParameterDescriptor, constraintSystem, context); } } @@ -538,7 +536,11 @@ public class CandidateResolver { @NotNull CallCandidateResolutionContext context ) { JetExpression argumentExpression = valueArgument.getArgumentExpression(); - assert argumentExpression instanceof JetFunctionLiteralExpression; + if (argumentExpression == null) return; + JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesizeWithNoTypeResolution(argumentExpression, false); + if (!(deparenthesizedExpression instanceof JetFunctionLiteralExpression)) return; + JetFunctionLiteralExpression functionLiteralExpression = (JetFunctionLiteralExpression) deparenthesizedExpression; + JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument); JetType expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT); if (expectedType == null || !KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(expectedType) @@ -553,7 +555,7 @@ public class CandidateResolver { TemporaryTraceAndCache temporaryToResolveFunctionLiteral = TemporaryTraceAndCache.create( context, "trace to resolve function literal with expected return type", argumentExpression); - JetElement statementExpression = JetPsiUtil.getLastStatementInABlock(((JetFunctionLiteralExpression) argumentExpression).getBodyExpression()); + JetElement statementExpression = JetPsiUtil.getLastStatementInABlock(functionLiteralExpression.getBodyExpression()); if (statementExpression == null) return; boolean[] mismatch = new boolean[1]; ObservableBindingTrace errorInterceptingTrace = ExpressionTypingUtils.makeTraceInterceptingTypeMismatch( @@ -562,7 +564,7 @@ public class CandidateResolver { .replaceBindingTrace(errorInterceptingTrace).replaceExpectedType(expectedType) .replaceDataFlowInfo(dataFlowInfoForArgument).replaceResolutionResultsCache(temporaryToResolveFunctionLiteral.cache); JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo( - (JetFunctionLiteralExpression) argumentExpression, newContext, RESOLVE_FUNCTION_ARGUMENTS).getType(); + argumentExpression, functionLiteralExpression, newContext, RESOLVE_FUNCTION_ARGUMENTS).getType(); if (!mismatch[0]) { constraintSystem.addSubtypeConstraint( type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex())); @@ -573,7 +575,7 @@ public class CandidateResolver { JetType expectedTypeWithoutReturnType = hasExpectedReturnType ? CallResolverUtil.replaceReturnTypeByUnknown(expectedType) : expectedType; CallCandidateResolutionContext newContext = context.replaceExpectedType(expectedTypeWithoutReturnType).replaceDataFlowInfo(dataFlowInfoForArgument); - JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo((JetFunctionLiteralExpression) argumentExpression, newContext, + JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteralExpression, newContext, RESOLVE_FUNCTION_ARGUMENTS).getType(); constraintSystem.addSubtypeConstraint( type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex())); diff --git a/compiler/testData/diagnostics/tests/functionLiterals/LabeledFunctionLiterals.kt b/compiler/testData/diagnostics/tests/functionLiterals/LabeledFunctionLiterals.kt new file mode 100644 index 00000000000..574ecebe3dc --- /dev/null +++ b/compiler/testData/diagnostics/tests/functionLiterals/LabeledFunctionLiterals.kt @@ -0,0 +1,15 @@ +package h + +//traits to make ambiguity with function literal as an argument +trait A +trait B +trait C: A, B + +fun foo(a: A, f: () -> T): T = f() +fun foo(b: B, f: () -> T): T = f() + +fun test(c: C) { + foo(c) @f { + c!! + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index f56e0c727e6..6bb36aa4d4f 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2416,6 +2416,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/functionLiterals/kt2906.kt"); } + @TestMetadata("LabeledFunctionLiterals.kt") + public void testLabeledFunctionLiterals() throws Exception { + doTest("compiler/testData/diagnostics/tests/functionLiterals/LabeledFunctionLiterals.kt"); + } + @TestMetadata("NoDanglingFunctionLiteralForNestedCalls.kt") public void testNoDanglingFunctionLiteralForNestedCalls() throws Exception { doTest("compiler/testData/diagnostics/tests/functionLiterals/NoDanglingFunctionLiteralForNestedCalls.kt");