diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 327a486d8d79..5b8b49eb51b9 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -424,6 +424,12 @@ public class LambdaUtil { return typeByExpression instanceof PsiMethodReferenceType || typeByExpression instanceof PsiLambdaExpressionType || typeByExpression instanceof PsiLambdaParameterType; } + public static boolean isLambdaReturnExpression(PsiElement element) { + final PsiElement parent = element.getParent(); + return parent instanceof PsiLambdaExpression || + parent instanceof PsiReturnStatement && PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class, true, PsiMethod.class) != null; + } + public static PsiReturnStatement[] getReturnStatements(PsiLambdaExpression lambdaExpression) { final PsiElement body = lambdaExpression.getBody(); return body instanceof PsiCodeBlock ? PsiUtil.findReturnStatements((PsiCodeBlock)body) : PsiReturnStatement.EMPTY_ARRAY; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java index 90203fc59f66..4b9c20fc45fa 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java @@ -415,6 +415,9 @@ public class PsiImplUtil { private static PsiType doNormalizeWildcardByPosition(final PsiType type, @NotNull PsiExpression expression, final PsiExpression toplevel) { if (type instanceof PsiCapturedWildcardType) { final PsiWildcardType wildcardType = ((PsiCapturedWildcardType)type).getWildcard(); + if (expression instanceof PsiReferenceExpression && LambdaUtil.isLambdaReturnExpression(expression)) { + return type; + } if (PsiUtil.isAccessedForWriting(toplevel)) { return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType, expression); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/CaptureInReturnStatementOfLambdaExpression.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/CaptureInReturnStatementOfLambdaExpression.java new file mode 100644 index 000000000000..cb6d86c92432 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/CaptureInReturnStatementOfLambdaExpression.java @@ -0,0 +1,14 @@ +import java.util.function.Function; + +interface I{ + void foo(Function f); +} + +class C { + void bar(I x) { + x.foo(a -> { + x.foo(y -> a); + return a; + }); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 7afe53b19d15..07a7b0930d83 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -195,6 +195,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testCaptureInReturnStatementOfLambdaExpression() throws Exception { + doTest(); + } + private void doTest() { doTest(false); }