new overload resolution: integrate isPotentiallyCompatible in isApplicable checks
authorAnna Kozlova <anna.kozlova@jetbrains.com>
Wed, 26 Nov 2014 16:35:45 +0000 (17:35 +0100)
committerAnna Kozlova <anna.kozlova@jetbrains.com>
Wed, 26 Nov 2014 16:42:30 +0000 (17:42 +0100)
16 files changed:
java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
java/java-psi-api/src/com/intellij/psi/PsiLambdaExpression.java
java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConflictResolution.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IDEA102800.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/PertinentToApplicabilityOfExplicitlyTypedLambda.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityOfImplicitlyTypedLambda.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/MethodApplicability.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java
platform/util/resources/misc/registry.properties

index 820d9bccd36e91d7722b911169dc35085996ea32..7f707200d6c63194569833a613ad2b04b2502bb7 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.psi;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.registry.Registry;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.infos.MethodCandidateInfo;
 import com.intellij.psi.util.*;
@@ -493,6 +494,31 @@ public class LambdaUtil {
     return expression;
   }
 
+  // http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1
+  // A lambda expression or a method reference expression is potentially compatible with a type variable 
+  // if the type variable is a type parameter of the candidate method.
+  public static boolean isPotentiallyCompatibleWithTypeParameter(PsiFunctionalExpression expression,
+                                                                 PsiExpressionList argsList,
+                                                                 PsiMethod method) {
+    if (!Registry.is("JDK8042508.bug.fixed", false)) {
+      final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(argsList, PsiCallExpression.class);
+      if (callExpression == null || callExpression.getTypeArguments().length > 0) {
+        return false;
+      }
+    }
+
+    final int lambdaIdx = getLambdaIdx(argsList, expression);
+    if (lambdaIdx >= 0) {
+      final PsiParameter[] parameters = method.getParameterList().getParameters();
+      final PsiParameter lambdaParameter = parameters[Math.min(lambdaIdx, parameters.length - 1)];
+      final PsiClass paramClass = PsiUtil.resolveClassInType(lambdaParameter.getType());
+      if (paramClass instanceof PsiTypeParameter && ((PsiTypeParameter)paramClass).getOwner() == method) {
+        return true;
+      }
+    }
+    return false;
+  }
+  
   public static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
     private PsiMethod myMethod;
     private final PsiClass myClass;
index a59d1e50f35ec8f30bb45d995b3ecd2f8f787fbb..459b9d176af9739c778f2d04f985baf6992baa14 100644 (file)
@@ -46,6 +46,4 @@ public interface PsiLambdaExpression extends PsiFunctionalExpression {
    * @return true when lambda declares parameter types explicitly
    */
   boolean hasFormalParameterTypes();
-
-  boolean isAcceptable(PsiType leftType, boolean checkReturnType);
 }
index 1041b9fa1c71ac9746663878bcf0b7f8590beb53..3213970cc2601a3e18149af319c87591a613a462 100644 (file)
@@ -731,7 +731,7 @@ public class TypeConversionUtil {
         final PsiType lType = lLambdaExpression.getFunctionalInterfaceType();
         return Comparing.equal(rType, lType);
       }
-      return !(left instanceof PsiArrayType) && rLambdaExpression.isAcceptable(left, false);
+      return !(left instanceof PsiArrayType) && rLambdaExpression.isAcceptable(left);
     }
 
     if (left instanceof PsiIntersectionType) {
index 738b835a527d2de7f51a6396eb20858784f61bc8..25151190b2f16ad0dd7c2aacc6423d524e87d540 100644 (file)
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java;
 import com.intellij.icons.AllIcons;
 import com.intellij.lang.ASTNode;
 import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.controlFlow.*;
 import com.intellij.psi.impl.PsiImplUtil;
 import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
@@ -34,6 +33,8 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
+import java.util.HashMap;
+import java.util.Map;
 
 public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements PsiLambdaExpression {
 
@@ -168,35 +169,35 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
   }
 
   @Override
-  public boolean isAcceptable(PsiType left) {
-    return isAcceptable(left, false);
-  }
-
-  @Override
-  public boolean isAcceptable(PsiType leftType, boolean checkReturnType) {
+  public boolean isAcceptable(PsiType leftType) {
     if (leftType instanceof PsiIntersectionType) {
       for (PsiType conjunctType : ((PsiIntersectionType)leftType).getConjuncts()) {
-        if (isAcceptable(conjunctType, checkReturnType)) return true;
+        if (isAcceptable(conjunctType)) return true;
       }
       return false;
     }
-    final PsiElement argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
-    if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
-      if (!hasFormalParameterTypes()) {
-        return true;
-      }
-      final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList);
-      if (candidateProperties != null && !InferenceSession.isPertinentToApplicability(this, candidateProperties.getMethod())) {
-        return true;
-      }
-    }
+    final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
 
     leftType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(leftType, this);
 
     final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(leftType);
     final PsiClass psiClass = resolveResult.getElement();
     if (psiClass instanceof PsiAnonymousClass) {
-      return isAcceptable(((PsiAnonymousClass)psiClass).getBaseClassType(), checkReturnType);
+      return isAcceptable(((PsiAnonymousClass)psiClass).getBaseClassType());
+    }
+
+    if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
+      final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList);
+      if (candidateProperties != null) {
+        final PsiMethod method = candidateProperties.getMethod();
+        if (!InferenceSession.isPertinentToApplicability(this, method) && hasFormalParameterTypes()) {
+          return true;
+        }
+
+        if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) {
+          return true;
+        }
+      }
     }
 
     final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
@@ -206,56 +207,77 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
     final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
 
     assert leftType != null;
-    final PsiParameter[] lambdaParameters = getParameterList().getParameters();
-    final PsiType[] parameterTypes = interfaceMethod.getSignature(substitutor).getParameterTypes();
-    if (lambdaParameters.length != parameterTypes.length) return false;
-
-    for (int lambdaParamIdx = 0, length = lambdaParameters.length; lambdaParamIdx < length; lambdaParamIdx++) {
-      PsiParameter parameter = lambdaParameters[lambdaParamIdx];
-      final PsiTypeElement typeElement = parameter.getTypeElement();
-      if (typeElement != null) {
-        final PsiType lambdaFormalType = toArray(typeElement.getType());
-        final PsiType methodParameterType = toArray(parameterTypes[lambdaParamIdx]);
-        if (!lambdaFormalType.equals(methodParameterType)) {
-          return false;
+    if (!isPotentiallyCompatible(leftType)) {
+      return false;
+    }
+
+    if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList) && !hasFormalParameterTypes()) {
+      return true;
+    }
+
+   
+
+    if (hasFormalParameterTypes()) {
+      final PsiParameter[] lambdaParameters = getParameterList().getParameters();
+      final PsiType[] parameterTypes = interfaceMethod.getSignature(substitutor).getParameterTypes();
+      for (int lambdaParamIdx = 0, length = lambdaParameters.length; lambdaParamIdx < length; lambdaParamIdx++) {
+        PsiParameter parameter = lambdaParameters[lambdaParamIdx];
+        final PsiTypeElement typeElement = parameter.getTypeElement();
+        if (typeElement != null) {
+          final PsiType lambdaFormalType = toArray(typeElement.getType());
+          final PsiType methodParameterType = toArray(parameterTypes[lambdaParamIdx]);
+          if (!lambdaFormalType.equals(methodParameterType)) {
+            return false;
+          }
         }
       }
     }
 
-
-    //A lambda expression (§15.27) is potentially compatible with a functional interface type (§9.8) if all of the following are true:
-    //   The arity of the target type's function type is the same as the arity of the lambda expression.
-    //   If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2).
-    //   If the target type's function type has a (non-void) return type, then the lambda body is either an expression or a value-compatible block (§15.27.2).
     PsiType methodReturnType = interfaceMethod.getReturnType();
-    if (checkReturnType) {
-      final String uniqueVarName = JavaCodeStyleManager.getInstance(getProject()).suggestUniqueVariableName("l", this, true);
-      final String canonicalText = toArray(leftType).getCanonicalText();
-      final PsiStatement assignmentFromText = JavaPsiFacade.getElementFactory(getProject())
-        .createStatementFromText(canonicalText + " " + uniqueVarName + " = " + getText(), this);
-      final PsiLocalVariable localVariable = (PsiLocalVariable)((PsiDeclarationStatement)assignmentFromText).getDeclaredElements()[0];
-      if (methodReturnType != null) {
-        return LambdaHighlightingUtil.checkReturnTypeCompatible((PsiLambdaExpression)localVariable.getInitializer(),
-                                                                substitutor.substitute(methodReturnType)) == null;
+    if (methodReturnType != null) {
+      Map<PsiElement, PsiType> map = LambdaUtil.ourFunctionTypes.get();
+      if (map == null) {
+        map = new HashMap<PsiElement, PsiType>();
+        LambdaUtil.ourFunctionTypes.set(map);
       }
-    } else {
-      final PsiElement body = getBody();
-      if (methodReturnType == PsiType.VOID) {
-        if (body instanceof PsiCodeBlock) {
-          return isVoidCompatible();
-        } else {
-          return LambdaUtil.isExpressionStatementExpression(body);
-        }
-      } else {
-        if (body instanceof PsiCodeBlock) {
-          return isValueCompatible();
+      try {
+        if (map.put(this, leftType) != null) {
+          return false;
         }
-        return body instanceof PsiExpression;
+        return LambdaHighlightingUtil.checkReturnTypeCompatible(this, substitutor.substitute(methodReturnType)) == null;
+      }
+      finally {
+        map.remove(this);
       }
     }
     return true;
   }
 
+  //A lambda expression (§15.27) is potentially compatible with a functional interface type (§9.8) if all of the following are true:
+  //   The arity of the target type's function type is the same as the arity of the lambda expression.
+  //   If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2).
+  //   If the target type's function type has a (non-void) return type, then the lambda body is either an expression or a value-compatible block (§15.27.2).
+  private boolean isPotentiallyCompatible(PsiType left) {
+    final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(left);
+    if (interfaceMethod == null) return false;
+
+    if (getParameterList().getParametersCount() != interfaceMethod.getParameterList().getParametersCount()) {
+      return false;
+    }
+    final PsiType methodReturnType = interfaceMethod.getReturnType();
+    final PsiElement body = getBody();
+    if (methodReturnType == PsiType.VOID) {
+      if (body instanceof PsiCodeBlock) {
+        return isVoidCompatible();
+      } else {
+        return LambdaUtil.isExpressionStatementExpression(body);
+      }
+    }
+    else {
+      return body instanceof PsiCodeBlock && isValueCompatible() || body instanceof PsiExpression;
+    }
+  }
+
   private static PsiType toArray(PsiType paramType) {
     if (paramType instanceof PsiEllipsisType) {
       return ((PsiEllipsisType)paramType).toArrayType();
index a9ba1bbaa5b0744f1f8193b84d44a1bd98a0b3f6..32545c51df0df5a1c9d4e54ba7c5e2a8a86ca8fa 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.registry.Registry;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.PsiImplUtil;
 import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
@@ -373,12 +374,19 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
       return false;
     }
 
-    final PsiElement argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
+    final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
     final boolean isExact = isExact();
-    if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList) && isExact) {
+    if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
       final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList);
-      if (candidateProperties != null && !InferenceSession.isPertinentToApplicability(this, candidateProperties.getMethod())) {
-        return true;
+      if (candidateProperties != null) {
+        final PsiMethod method = candidateProperties.getMethod();
+        if (isExact && !InferenceSession.isPertinentToApplicability(this, method)) {
+          return true;
+        }
+
+        if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) {
+          return true;
+        }
       }
     }
 
index f5b690863957d5f809596577cc8f5023a77f8110..99e577b8506c761a07336c014d0b667d1a5dbf87 100644 (file)
@@ -33,6 +33,7 @@ import com.intellij.util.containers.HashSet;
 import gnu.trove.THashMap;
 import gnu.trove.THashSet;
 import gnu.trove.TIntArrayList;
+import gnu.trove.TObjectHashingStrategy;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -91,9 +92,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
     // then noone can be more specific
     if (!atLeastOneMatch) return null;
 
-    checkLambdaApplicable(conflicts, myLanguageLevel);
-    if (conflicts.size() == 1) return conflicts.get(0);
-
     checkSpecifics(conflicts, applicabilityLevel, myLanguageLevel);
     if (conflicts.size() == 1) return conflicts.get(0);
 
@@ -108,63 +106,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
     return null;
   }
 
-  private void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, @NotNull LanguageLevel languageLevel) {
-    if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return;
-    for (int i = 0; i < getActualParametersLength(); i++) {
-
-      PsiExpression expression;
-      if (myArgumentsList instanceof PsiExpressionList) {
-        expression = ((PsiExpressionList)myArgumentsList).getExpressions()[i];
-      }
-      else {
-        final PsiType argType = getActualParameterTypes()[i];
-        expression = argType instanceof PsiLambdaExpressionType ? ((PsiLambdaExpressionType)argType).getExpression() : null;
-      }
-
-      final PsiLambdaExpression lambdaExpression = findNestedLambdaExpression(expression);
-      if (lambdaExpression != null) {
-        checkLambdaApplicable(conflicts, i, lambdaExpression);
-      }
-    }
-  }
-
-  private static PsiLambdaExpression findNestedLambdaExpression(PsiExpression expression) {
-    if (expression instanceof PsiLambdaExpression) {
-      return (PsiLambdaExpression)expression;
-    }
-    else if (expression instanceof PsiParenthesizedExpression) {
-      return findNestedLambdaExpression(((PsiParenthesizedExpression)expression).getExpression());
-    }
-    else if (expression instanceof PsiConditionalExpression) {
-      PsiLambdaExpression lambdaExpression = findNestedLambdaExpression(((PsiConditionalExpression)expression).getThenExpression());
-      if (lambdaExpression != null) {
-        return lambdaExpression;
-      }
-      return findNestedLambdaExpression(((PsiConditionalExpression)expression).getElseExpression());
-    }
-    return null;
-  }
-
-  private static void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, int i, @NotNull PsiLambdaExpression lambdaExpression) {
-    for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
-      ProgressManager.checkCanceled();
-      final CandidateInfo conflict = iterator.next();
-      final PsiMethod method = (PsiMethod)conflict.getElement();
-      final PsiParameter[] methodParameters = method.getParameterList().getParameters();
-      if (methodParameters.length == 0) continue;
-      final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
-      final PsiType paramType = param.getType();
-      // http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1
-      // A lambda expression or a method reference expression is potentially compatible with a type variable if the type variable is a type parameter of the candidate method.
-      final PsiClass paramClass = PsiUtil.resolveClassInType(paramType);
-      if (paramClass instanceof PsiTypeParameter && ((PsiTypeParameter)paramClass).getOwner() == method) continue;
-      if (!lambdaExpression.isAcceptable(((MethodCandidateInfo)conflict).getSubstitutor(false).substitute(paramType),
-                                         InferenceSession.isPertinentToApplicability(lambdaExpression, method))) {
-        iterator.remove();
-      }
-    }
-  }
-
   public void checkSpecifics(@NotNull List<CandidateInfo> conflicts,
                              @MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel,
                              @NotNull LanguageLevel languageLevel) {
index a178b4d970d88bf6a769a8a22d1e6e438c54b801..83db64423f6f00653bb04ecb29069377d7276577 100644 (file)
@@ -20,7 +20,7 @@ public class Test<A, B extends Number>  {
     public static void main(String[] args) {
         Inner<Number, Double> inn = new Inner<>();
         inn.m8<error descr="Ambiguous method call: both 'Inner.m8(IO<? extends Number>)' and 'Inner.m8(IN<? extends Double>)' match">(p -> 1.0)</error>;
-        new Test<Number, Integer>().foo<error descr="Ambiguous method call: both 'Test.foo(IO<? extends Number>)' and 'Test.foo(IN<? extends Integer>)' match">(p -> 1.0)</error>;
+        new Test<Number, Integer>().foo<error descr="Cannot resolve method 'foo(<lambda expression>)'">(p -> 1.0)</error>;
 
     }
 }
index 0cc3741e0f610c4e0b4aedf81f8fd21d8e64652c..6fbdbd116855a203953de33a1d348a69d15975b7 100644 (file)
@@ -1,7 +1,7 @@
 class Demo {
 
     public void f1() {
-        f2(2, <error descr="Target type of a lambda conversion must be an interface">input -> input</error>);
+        f2<error descr="Cannot resolve method 'f2(int, <lambda expression>)'">(2, input -> input)</error>;
     }
 
     public void f2() {
index 10cd3fffeb86c4ba1e250e2a6e6a2baaad06b048..cdddcba60c366832065fa36f26c446061f8d49a3 100644 (file)
@@ -25,7 +25,7 @@ class ReturnTypeIncompatibility {
     }
 
     public static void main(String[] args) {
-        call<error descr="Ambiguous method call: both 'ReturnTypeIncompatibility.call(I1<Integer>)' and 'ReturnTypeIncompatibility.call(I2<P>)' match">(i-> {return i;})</error>;
+        call<error descr="Cannot resolve method 'call(<lambda expression>)'">(i-> {return i;})</error>;
     }
 }
 
@@ -57,7 +57,7 @@ class ReturnTypeCompatibility {
     }
 
     public static void main(String[] args) {
-        call<error descr="Ambiguous method call: both 'ReturnTypeCompatibility.call(I1<Number>)' and 'ReturnTypeCompatibility.call(I2<String>)' match">(i-> {return i;})</error>;
+        call<error descr="Cannot resolve method 'call(<lambda expression>)'">(i-> {return i;})</error>;
     }
 }
 
index d62afb3fdfcdd1599e4a1683f4d365e554e5f7cc..55bf990960efc51f95990c6e0a3e4034c06d9535 100644 (file)
@@ -21,9 +21,9 @@ class Test {
     }
 
     void foo(Foo<String> as, final Foo<Character> ac) {
-        boolean b1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> false)</error>);
-        String s1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>);
-        boolean b2 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>);
+        boolean b1 = as.forAll(s -> ac.forAll<error descr="Cannot resolve method 'forAll(<lambda expression>)'">(c -> false)</error>);
+        String s1 = as.forAll(s -> ac.forAll<error descr="Cannot resolve method 'forAll(<lambda expression>)'">(c -> "")</error>);
+        boolean b2 = as.forAll(s -> ac.forAll<error descr="Cannot resolve method 'forAll(<lambda expression>)'">(c -> "")</error>);
         String s2 = as.forAll2(s -> ac.forAll2(<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
         boolean b3 = as.forAll((I<String, Boolean>)s -> ac.forAll((I<Character, Boolean>)<error descr="Incompatible return type String in lambda expression">c -> ""</error>));
         String s3 = as.forAll((II<String, String>)s -> ac.forAll((II<Character, String>)<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
index 7c2cc7bdae5ebb7edc4c16ae7875b5fb4accfbf0..299c620daeb24fec4a6695a93e8d7016f34dd307 100644 (file)
@@ -14,7 +14,7 @@ class Test {
   }
 
   void fooBar(IntStream1 instr){
-    Supplier<Stream<Integer>> si = () -> instr.map ((i) -> (( <error descr="Operator '%' cannot be applied to '<lambda parameter>', 'int'">i % 2</error>) == 0) ? i : <error descr="Incompatible types. Found: '<lambda parameter>', required: '<lambda parameter>'">-i</error>).boxed();
+    Supplier<Stream<Integer>> si = () -> instr.map ((i) -> (( <error descr="Operator '%' cannot be applied to '<lambda parameter>', 'int'">i % 2</error>) == 0) ? i : -i).boxed();
     System.out.println(si);
     Supplier<Stream<Integer>> si1 = () -> instr.map <error descr="Ambiguous method call: both 'IntStream1.map(IntFunction<Integer>)' and 'IntStream1.map(IntUnaryOperator)' match">(null)</error>.boxed();
     System.out.println(si1);
index 348108fc34434cde6ad798af6ba8a7e500b6fd1a..adaea236cd6210e9ec5b9bebd2d5361608cb9d73 100644 (file)
@@ -12,6 +12,6 @@ abstract class PertinentToApplicabilityOfExplicitlyTypedLambdaTest {
   abstract void foo(B b);
 
   {
-    foo<error descr="Ambiguous method call: both 'PertinentToApplicabilityOfExplicitlyTypedLambdaTest.foo(A)' and 'PertinentToApplicabilityOfExplicitlyTypedLambdaTest.foo(B)' match">(x -> y -> 42)</error>;
+    foo<error descr="Cannot resolve method 'foo(<lambda expression>)'">(x -> y -> 42)</error>;
   }
 }
index 1188a9584dcab7a77bbb5eb19c1cdc17cc276a29..443f6339121d85503acf39438d0f97d06091e857 100644 (file)
@@ -14,10 +14,10 @@ abstract class Test {
     foo(x -> {
       return x += 1;
     });
-    foo(x -> <error descr="Incompatible types. Found: 'int', required: '<lambda parameter>'">x += 1</error>);
+    foo<error descr="Ambiguous method call: both 'Test.foo(A)' and 'Test.foo(B)' match">(x -> x += 1)</error>;
     foo(x -> 1);
     foo(x -> <error descr="Operator '!' cannot be applied to 'int'">!x</error>);
-    foo(x -> <error descr="Operator '++' cannot be applied to '<lambda parameter>'">++x</error>);
+    foo<error descr="Ambiguous method call: both 'Test.foo(A)' and 'Test.foo(B)' match">(x -> ++x)</error>;
     foo(x -> o instanceof String ? 1 : 0);
   }
 }
index 81c52a8cb7e6aa3d11b7358013a9a337ffa446e3..aa18671e3f487745064de4efa362b0c112378158 100644 (file)
@@ -26,9 +26,9 @@ class Foo {
       System.out.println(s);
     });
 
-    <error descr="Cannot resolve method 'foo(<lambda expression>)'">foo</error>((String p, String k) -> {
+    foo<error descr="Cannot resolve method 'foo(<lambda expression>)'">((String p, String k) -> {
       System.out.println(p);
-    });
+    })</error>;
   }
 }
 
@@ -62,7 +62,7 @@ class WithTypeParams {
         System.out.println(p);
       });
   
-      <error descr="Cannot resolve method 'foo(<lambda expression>)'">foo</error>((int k) -> {System.out.println(k);});
+      foo<error descr="Cannot resolve method 'foo(<lambda expression>)'">((int k) -> {System.out.println(k);})</error>;
     }
   }
 }
\ No newline at end of file
index 41559703426b2d9db4daea19d3ea753696076f51..fad2733966230237e319d748b754827835f11ed7 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
 import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
 import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.util.registry.Registry;
 import com.intellij.testFramework.IdeaTestUtil;
 import org.jetbrains.annotations.NonNls;
 
@@ -100,7 +101,9 @@ public class MostSpecificResolutionTest extends LightDaemonAnalyzerTestCase {
   }
 
   public void testJDK8042508() throws Exception {
-    doTest(false);
+    if (Registry.is("JDK8042508.bug.fixed", false)) {
+      doTest(false);
+    }
   }
 
   public void testIDEA125855() throws Exception {
index bfbcb49e83ce9884fecbd1f9a765f09ef68f8ec4..bd09bd415c8bdea8a387c2574cb262a628c02b02 100644 (file)
@@ -495,4 +495,7 @@ editor.xcode.like.scrollbar=false
 editor.xcode.like.scrollbar.description=Enables auto-hideable Xcode-like editor stripes
 
 editor.config.stop.at.project.root=true
-editor.config.stop.at.project.root.description=Stops searching for .editorconfig at project root (requires project reopening)
\ No newline at end of file
+editor.config.stop.at.project.root.description=Stops searching for .editorconfig at project root (requires project reopening)
+
+JDK8042508.bug.fixed=false
+JDK8042508.bug.fixed.description=Disable check for type variable until javac bug is fixed