analyze labeled function literals as usual ones
(specially as function literals, not as other expressions)
This commit is contained in:
+7
-4
@@ -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.<AnnotationDescriptor>emptyList(), receiverType, parameterTypes, returnType);
|
||||
return KotlinBuiltIns.getInstance().getFunctionType(Collections.<AnnotationDescriptor>emptyList(), receiverType, parameterTypes,
|
||||
returnType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -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<D> 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<D> 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()));
|
||||
|
||||
@@ -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<T>(<!UNUSED_PARAMETER!>a<!>: A, f: () -> T): T = f()
|
||||
fun foo<T>(<!UNUSED_PARAMETER!>b<!>: B, f: () -> T): T = f()
|
||||
|
||||
fun test(c: C) {
|
||||
<!CANNOT_COMPLETE_RESOLVE!>foo<!>(c) @f {
|
||||
c<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user