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) {
|
if (expression == null) {
|
||||||
return JetTypeInfo.create(null, context.dataFlowInfo);
|
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
if (expression instanceof JetFunctionLiteralExpression) {
|
JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesizeWithNoTypeResolution(expression, false);
|
||||||
return getFunctionLiteralTypeInfo((JetFunctionLiteralExpression) expression, context, resolveArgumentsMode);
|
if (deparenthesizedExpression instanceof JetFunctionLiteralExpression) {
|
||||||
|
return getFunctionLiteralTypeInfo(expression, (JetFunctionLiteralExpression) deparenthesizedExpression, context, resolveArgumentsMode);
|
||||||
}
|
}
|
||||||
JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
||||||
if (recordedTypeInfo != null) {
|
if (recordedTypeInfo != null) {
|
||||||
@@ -181,6 +182,7 @@ public class ArgumentTypeResolver {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetTypeInfo getFunctionLiteralTypeInfo(
|
public JetTypeInfo getFunctionLiteralTypeInfo(
|
||||||
|
@NotNull JetExpression expression,
|
||||||
@NotNull JetFunctionLiteralExpression functionLiteralExpression,
|
@NotNull JetFunctionLiteralExpression functionLiteralExpression,
|
||||||
@NotNull CallResolutionContext<?> context,
|
@NotNull CallResolutionContext<?> context,
|
||||||
@NotNull ResolveArgumentsMode resolveArgumentsMode
|
@NotNull ResolveArgumentsMode resolveArgumentsMode
|
||||||
@@ -189,7 +191,7 @@ public class ArgumentTypeResolver {
|
|||||||
JetType type = getFunctionLiteralType(functionLiteralExpression, context.scope, context.trace);
|
JetType type = getFunctionLiteralType(functionLiteralExpression, context.scope, context.trace);
|
||||||
return JetTypeInfo.create(type, context.dataFlowInfo);
|
return JetTypeInfo.create(type, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
return expressionTypingServices.getTypeInfo(context.scope, functionLiteralExpression, context.expectedType, context.dataFlowInfo, context.trace);
|
return expressionTypingServices.getTypeInfo(expression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -212,7 +214,8 @@ public class ArgumentTypeResolver {
|
|||||||
JetType returnType = resolveTypeRefWithDefault(functionLiteral.getReturnTypeRef(), scope, temporaryTrace, DONT_CARE);
|
JetType returnType = resolveTypeRefWithDefault(functionLiteral.getReturnTypeRef(), scope, temporaryTrace, DONT_CARE);
|
||||||
assert returnType != null;
|
assert returnType != null;
|
||||||
JetType receiverType = resolveTypeRefWithDefault(functionLiteral.getReceiverTypeRef(), scope, temporaryTrace, 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
|
@Nullable
|
||||||
|
|||||||
@@ -217,8 +217,6 @@ public class CandidateResolver {
|
|||||||
ValueParameterDescriptor valueParameterDescriptor = entry.getKey();
|
ValueParameterDescriptor valueParameterDescriptor = entry.getKey();
|
||||||
|
|
||||||
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
|
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
|
||||||
if (!(valueArgument.getArgumentExpression() instanceof JetFunctionLiteralExpression)) continue;
|
|
||||||
|
|
||||||
addConstraintForFunctionLiteral(valueArgument, valueParameterDescriptor, constraintSystem, context);
|
addConstraintForFunctionLiteral(valueArgument, valueParameterDescriptor, constraintSystem, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,7 +536,11 @@ public class CandidateResolver {
|
|||||||
@NotNull CallCandidateResolutionContext<D> context
|
@NotNull CallCandidateResolutionContext<D> context
|
||||||
) {
|
) {
|
||||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
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 effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
|
||||||
JetType expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT);
|
JetType expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT);
|
||||||
if (expectedType == null || !KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(expectedType)
|
if (expectedType == null || !KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(expectedType)
|
||||||
@@ -553,7 +555,7 @@ public class CandidateResolver {
|
|||||||
TemporaryTraceAndCache temporaryToResolveFunctionLiteral = TemporaryTraceAndCache.create(
|
TemporaryTraceAndCache temporaryToResolveFunctionLiteral = TemporaryTraceAndCache.create(
|
||||||
context, "trace to resolve function literal with expected return type", argumentExpression);
|
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;
|
if (statementExpression == null) return;
|
||||||
boolean[] mismatch = new boolean[1];
|
boolean[] mismatch = new boolean[1];
|
||||||
ObservableBindingTrace errorInterceptingTrace = ExpressionTypingUtils.makeTraceInterceptingTypeMismatch(
|
ObservableBindingTrace errorInterceptingTrace = ExpressionTypingUtils.makeTraceInterceptingTypeMismatch(
|
||||||
@@ -562,7 +564,7 @@ public class CandidateResolver {
|
|||||||
.replaceBindingTrace(errorInterceptingTrace).replaceExpectedType(expectedType)
|
.replaceBindingTrace(errorInterceptingTrace).replaceExpectedType(expectedType)
|
||||||
.replaceDataFlowInfo(dataFlowInfoForArgument).replaceResolutionResultsCache(temporaryToResolveFunctionLiteral.cache);
|
.replaceDataFlowInfo(dataFlowInfoForArgument).replaceResolutionResultsCache(temporaryToResolveFunctionLiteral.cache);
|
||||||
JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo(
|
JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo(
|
||||||
(JetFunctionLiteralExpression) argumentExpression, newContext, RESOLVE_FUNCTION_ARGUMENTS).getType();
|
argumentExpression, functionLiteralExpression, newContext, RESOLVE_FUNCTION_ARGUMENTS).getType();
|
||||||
if (!mismatch[0]) {
|
if (!mismatch[0]) {
|
||||||
constraintSystem.addSubtypeConstraint(
|
constraintSystem.addSubtypeConstraint(
|
||||||
type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex()));
|
type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex()));
|
||||||
@@ -573,7 +575,7 @@ public class CandidateResolver {
|
|||||||
JetType expectedTypeWithoutReturnType = hasExpectedReturnType ? CallResolverUtil.replaceReturnTypeByUnknown(expectedType) : expectedType;
|
JetType expectedTypeWithoutReturnType = hasExpectedReturnType ? CallResolverUtil.replaceReturnTypeByUnknown(expectedType) : expectedType;
|
||||||
CallCandidateResolutionContext<D> newContext =
|
CallCandidateResolutionContext<D> newContext =
|
||||||
context.replaceExpectedType(expectedTypeWithoutReturnType).replaceDataFlowInfo(dataFlowInfoForArgument);
|
context.replaceExpectedType(expectedTypeWithoutReturnType).replaceDataFlowInfo(dataFlowInfoForArgument);
|
||||||
JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo((JetFunctionLiteralExpression) argumentExpression, newContext,
|
JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteralExpression, newContext,
|
||||||
RESOLVE_FUNCTION_ARGUMENTS).getType();
|
RESOLVE_FUNCTION_ARGUMENTS).getType();
|
||||||
constraintSystem.addSubtypeConstraint(
|
constraintSystem.addSubtypeConstraint(
|
||||||
type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex()));
|
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");
|
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")
|
@TestMetadata("NoDanglingFunctionLiteralForNestedCalls.kt")
|
||||||
public void testNoDanglingFunctionLiteralForNestedCalls() throws Exception {
|
public void testNoDanglingFunctionLiteralForNestedCalls() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/functionLiterals/NoDanglingFunctionLiteralForNestedCalls.kt");
|
doTest("compiler/testData/diagnostics/tests/functionLiterals/NoDanglingFunctionLiteralForNestedCalls.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user