lambda: stop inference from lambda if return type retrieval leads to second lambda inference; do not cache types during this calculation

This commit is contained in:
anna
2013-02-20 19:52:40 +01:00
parent 3595385432
commit 9634bb390e
4 changed files with 40 additions and 3 deletions

View File

@@ -88,9 +88,10 @@ public class JavaResolveCache {
public <T extends PsiExpression> PsiType getType(@NotNull T expr, @NotNull Function<T, PsiType> f) {
PsiType type = getCachedType(expr);
if (type == null) {
final RecursionGuard.StackStamp stackStamp = PsiDiamondType.ourDiamondGuard.markStack();
final RecursionGuard.StackStamp dStackStamp = PsiDiamondType.ourDiamondGuard.markStack();
final RecursionGuard.StackStamp gStackStamp = PsiResolveHelper.ourGraphGuard.markStack();
type = f.fun(expr);
if (!stackStamp.mayCacheNow()) {
if (!dStackStamp.mayCacheNow() || !gStackStamp.mayCacheNow()) {
return type;
}
if (type == null) type = TypeConversionUtil.NULL_TYPE;

View File

@@ -739,7 +739,12 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
continue;
}
if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() == null) continue;
PsiType exprType = expression.getType();
PsiType exprType = ourGraphGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return expression.getType();
}
});
if (exprType instanceof PsiLambdaParameterType) {
final PsiParameter parameter = ((PsiLambdaParameterType)exprType).getParameter();
final int parameterIndex = lambdaExpression.getParameterList().getParameterIndex(parameter);

View File

@@ -0,0 +1,27 @@
import java.util.*;
public class Main1 {
interface I<T> {
List<T> f();
}
static class Test {
<Z> void m(I<Z> i, I<Z> ii) {
}
<Z> void m(I<Z> s) {
}
{
m(() -> emptyList(), () -> new ArrayList<String>());
m(() -> new ArrayList<String>(), () -> emptyList());
m((I<String>) () -> emptyList(), () -> new ArrayList<String>());
m(() -> Test.<String>emptyList(), () -> new ArrayList<String>());
m(() -> emptyList());
}
static <T> List<T> emptyList() {
return null;
}
}
}

View File

@@ -212,6 +212,10 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testInferenceFromSecondLambda() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest(false);
}