inference errors: make applicability error thread safe so multiple threads can perform overload resolution of parent method calls independently, save presentable error when substitutor cached only

This commit is contained in:
Anna Kozlova
2017-05-08 12:12:13 +03:00
parent fa07225451
commit 77f4894aae
36 changed files with 145 additions and 136 deletions
@@ -930,7 +930,7 @@ public class HighlightMethodUtil {
@Language("HTML")
@NonNls String parensizedName = methodName + (parameters.length == 0 ? "( ) " : "");
String errorMessage = info != null ? info.getParentInferenceErrorMessage(list) : null;
String errorMessage = info != null ? info.getInferenceErrorMessage() : null;
return JavaErrorMessages.message(
"argument.mismatch.html.tooltip",
cols - parameters.length + 1,
@@ -1043,7 +1043,7 @@ public class HighlightMethodUtil {
}
s+= "</table>";
final String errorMessage = info != null ? info.getParentInferenceErrorMessage(list) : null;
final String errorMessage = info != null ? info.getInferenceErrorMessage() : null;
if (errorMessage != null) {
s+= "reason: ";
s += XmlStringUtil.escapeString(errorMessage).replaceAll("\n", "<br/>");
@@ -354,7 +354,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
(PsiCallExpression)parent.getParent() : null;
final JavaResolveResult containingCallResolveResult = callExpression != null ? callExpression.resolveMethodGenerics() : null;
if (containingCallResolveResult instanceof MethodCandidateInfo) {
parentInferenceErrorMessage = ((MethodCandidateInfo)containingCallResolveResult).getParentInferenceErrorMessage((PsiExpressionList)parent);
parentInferenceErrorMessage = ((MethodCandidateInfo)containingCallResolveResult).getInferenceErrorMessage();
}
final Map<PsiElement, String> returnErrors = LambdaUtil.checkReturnTypeCompatible(expression, LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType));
if (parentInferenceErrorMessage != null && (returnErrors == null || !returnErrors.containsValue(parentInferenceErrorMessage))) {
@@ -25,7 +25,6 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.ContainerUtil;
@@ -49,6 +48,8 @@ public class MethodCandidateInfo extends CandidateInfo{
private PsiSubstitutor myCalcedSubstitutor;
private volatile String myInferenceError;
private ThreadLocal<String> myApplicabilityError = new ThreadLocal<>();
private final LanguageLevel myLanguageLevel;
public MethodCandidateInfo(@NotNull PsiElement candidate,
@@ -113,7 +114,7 @@ public class MethodCandidateInfo extends CandidateInfo{
public int getPertinentApplicabilityLevel() {
int result = myPertinentApplicabilityLevel;
if (result == 0) {
myPertinentApplicabilityLevel = result = pullInferenceErrorMessagesFromSubexpressions(getPertinentApplicabilityLevelInner());
myPertinentApplicabilityLevel = result = getPertinentApplicabilityLevelInner();
}
return result;
}
@@ -136,7 +137,7 @@ public class MethodCandidateInfo extends CandidateInfo{
}
//already performed checks, so if inference failed, error message should be saved
if (myInferenceError != null || isPotentiallyCompatible() != ThreeState.YES) {
if (myApplicabilityError.get() != null || isPotentiallyCompatible() != ThreeState.YES) {
return ApplicabilityLevel.NOT_APPLICABLE;
}
return isVarargs() ? ApplicabilityLevel.VARARGS : ApplicabilityLevel.FIXED_ARITY;
@@ -305,18 +306,33 @@ public class MethodCandidateInfo extends CandidateInfo{
if (myTypeArguments == null) {
final RecursionGuard.StackStamp stackStamp = PsiDiamondType.ourDiamondGuard.markStack();
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
myApplicabilityError.set(null);
try {
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
if (!stackStamp.mayCacheNow() ||
isOverloadCheck() ||
!includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ||
getMarkerList() != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(getMarkerList().getParent()) ||
LambdaUtil.isLambdaParameterCheck()
) {
return inferredSubstitutor;
if (!stackStamp.mayCacheNow() ||
isOverloadCheck() ||
!includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ||
getMarkerList() != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(getMarkerList().getParent()) ||
LambdaUtil.isLambdaParameterCheck()
) {
return inferredSubstitutor;
}
myInferenceError = myApplicabilityError.get();
myCalcedSubstitutor = substitutor = inferredSubstitutor;
}
finally {
//includeReturnConstraint == true, means that it's not an applicability check and it won't be used
//Case when clear of error is required:
//for foo(bar()) where foo is overloaded but doesn't have type parameters, start from {bar()}.getSubstitutor()
//1. perform overload resolution for foo : evaluate {bar()}.getType() under overload lock -
// at least one applicability error for {bar()} candidate, when the last overloaded method leads to error but first was ok:
//2. {bar()}.getSubstitutor() would preserve error from wrong {foo} candidate => when the error was cleared - everything ok
if (includeReturnConstraint) {
myApplicabilityError.set(null);
}
}
myCalcedSubstitutor = substitutor = inferredSubstitutor;
}
else {
PsiTypeParameter[] typeParams = method.getTypeParameters();
@@ -451,69 +467,20 @@ public class MethodCandidateInfo extends CandidateInfo{
return 31 * super.hashCode() + (isVarargs() ? 1 : 0);
}
public void setInferenceError(String inferenceError) {
myInferenceError = inferenceError;
/**
* Should be invoked on the top level call expression candidate only
*/
public void setApplicabilityError(String applicabilityError) {
myApplicabilityError.set(applicabilityError);
}
public String getInferenceErrorMessage() {
getSubstitutor();
return myInferenceError;
}
public String getParentInferenceErrorMessage(PsiExpressionList list) {
String errorMessage = getInferenceErrorMessage();
while (errorMessage == null) {
list = PsiTreeUtil.getParentOfType(list, PsiExpressionList.class, true, PsiCodeBlock.class);
if (list == null) {
break;
}
final PsiElement parent = list.getParent();
if (!(parent instanceof PsiCallExpression)) {
break;
}
final JavaResolveResult resolveResult = ((PsiCallExpression)parent).resolveMethodGenerics();
if (resolveResult instanceof MethodCandidateInfo) {
errorMessage = ((MethodCandidateInfo)resolveResult).getInferenceErrorMessage();
}
}
return errorMessage;
}
@ApplicabilityLevelConstant
private int pullInferenceErrorMessagesFromSubexpressions(@ApplicabilityLevelConstant int level) {
if (myArgumentList instanceof PsiExpressionList && level == ApplicabilityLevel.NOT_APPLICABLE) {
String errorMessage = null;
for (PsiExpression expression : ((PsiExpressionList)myArgumentList).getExpressions()) {
final String message = clearErrorMessageInSubexpressions(expression);
if (message != null) {
errorMessage = message;
}
}
if (errorMessage != null) {
setInferenceError(errorMessage);
}
}
return level;
}
private static String clearErrorMessageInSubexpressions(PsiExpression expression) {
expression = PsiUtil.skipParenthesizedExprDown(expression);
if (expression instanceof PsiConditionalExpression) {
String thenErrorMessage = clearErrorMessageInSubexpressions(((PsiConditionalExpression)expression).getThenExpression());
String elseErrorMessage = clearErrorMessageInSubexpressions(((PsiConditionalExpression)expression).getElseExpression());
if (thenErrorMessage != null) {
return thenErrorMessage;
}
return elseErrorMessage;
}
else if (expression instanceof PsiCallExpression) {
final JavaResolveResult result = PsiDiamondType.getDiamondsAwareResolveResult((PsiCall)expression);
if (result instanceof MethodCandidateInfo) {
final String message = ((MethodCandidateInfo)result).getInferenceErrorMessage();
((MethodCandidateInfo)result).setInferenceError(null);
return message;
}
}
return null;
public String getInferenceErrorMessageAssumeAlreadyComputed() {
return myInferenceError;
}
public CurrentCandidateProperties createProperties() {
@@ -19,6 +19,7 @@ import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
@@ -167,7 +168,14 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
if (staticFactoryCandidateInfo == null) {
return DiamondInferenceResult.NULL_RESULT;
}
final PsiSubstitutor inferredSubstitutor = ourDiamondGuard.doPreventingRecursion(context, false, () -> staticFactoryCandidateInfo.getSubstitutor());
final Ref<String> refError = new Ref<>();
final PsiSubstitutor inferredSubstitutor = ourDiamondGuard.doPreventingRecursion(context, false, () -> {
PsiSubstitutor substitutor = staticFactoryCandidateInfo.getSubstitutor();
if (staticFactoryCandidateInfo instanceof MethodCandidateInfo) {
refError.set(((MethodCandidateInfo)staticFactoryCandidateInfo).getInferenceErrorMessageAssumeAlreadyComputed());
}
return substitutor;
});
if (inferredSubstitutor == null) {
return DiamondInferenceResult.NULL_RESULT;
}
@@ -176,7 +184,7 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
return DiamondInferenceResult.UNRESOLVED_CONSTRUCTOR;
}
final String errorMessage = ((MethodCandidateInfo)staticFactoryCandidateInfo).getInferenceErrorMessage();
final String errorMessage = refError.get();
//15.9.3 Choosing the Constructor and its Arguments
//The return type and throws clause of cj are the same as the return type and throws clause determined for mj (p15.12.2.6)
@@ -363,7 +363,7 @@ public class InferenceSession {
}
if (properties != null && myErrorMessages != null) {
properties.getInfo().setInferenceError(StringUtil.join(myErrorMessages, "\n"));
properties.getInfo().setApplicabilityError(StringUtil.join(myErrorMessages, "\n"));
}
}
}
@@ -16,7 +16,6 @@
package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ExpressionCompatibilityConstraint;
@@ -138,7 +137,6 @@ public class InferenceSessionContainer {
final InferenceSession childSession = new InferenceSession(initialInferenceState);
final List<String> errorMessages = parentSession.getIncompatibleErrorMessages();
if (errorMessages != null) {
properties.getInfo().setInferenceError(StringUtil.join(errorMessages, "\n"));
return childSession.prepareSubstitution();
}
return childSession.collectAdditionalAndInfer(parameters, arguments, properties, compoundInitialState.getInitialSubstitutor());
@@ -344,9 +344,9 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
PsiType argType,
PsiType parameterType) {
if (conflict instanceof MethodCandidateInfo) {
((MethodCandidateInfo)conflict).setInferenceError("Invalid " +
(referenceExpression.isConstructor() ? "constructor" :"method") +
" reference: " + argType.getPresentableText() + " cannot be converted to " + parameterType.getPresentableText());
((MethodCandidateInfo)conflict).setApplicabilityError("Invalid " +
(referenceExpression.isConstructor() ? "constructor" :"method") +
" reference: " + argType.getPresentableText() + " cannot be converted to " + parameterType.getPresentableText());
}
}
@@ -1,5 +1,6 @@
class Foo<T extends Enum> {
public T bar(Class<? extends T> type, String str) {
return Enum.valueOf(<error descr="'valueOf(java.lang.Class<T>, java.lang.String)' in 'java.lang.Enum' cannot be applied to '(java.lang.Class<capture<? extends T>>, java.lang.String)'">type</error>, str);
return <error descr="Incompatible types. Required T but 'valueOf' was inferred to T:
Incompatible types: Enum is not convertible to T">Enum.valueOf(type, str);</error>
}
}
@@ -10,7 +10,8 @@ class Test {
public void test(Set<MyConsumer> set) {
@SuppressWarnings("unchecked")
Map<Parent, MyConsumer<Parent>> map = create<error descr="'create(java.util.Set<T>)' in 'Test' cannot be applied to '(java.util.Set<Test.MyConsumer>)'">(set)</error>;
Map<Parent, MyConsumer<Parent>> map = <error descr="Incompatible types. Required Map<Parent, MyConsumer<Parent>> but 'create' was inferred to Map<S, T>:
Incompatible equality constraint: MyConsumer<Test.Parent> and MyConsumer">create(set);</error>
}
@@ -4,7 +4,8 @@ abstract class Group {
}
public <T extends Category> T get(Key<T> key) {
return getCategory<error descr="'getCategory(Key<R>)' in 'Group' cannot be applied to '(Key<T>)'">(key)</error>;
return <error descr="Incompatible types. Required T but 'getCategory' was inferred to R:
Incompatible types: Category is not convertible to T">getCategory(key);</error>
}
public abstract <R extends Category<R>> R getCategory(Key<R> key);
@@ -10,7 +10,8 @@ class NachCollections<K,V> {
Collection<? super Map.Entry<K,V>> c2,
Consumer<Map.Entry<K, V>> a) {
c1.forEach(consumer(a));
c2.forEach(consumer<error descr="'consumer(java.util.function.Consumer<java.util.Map.Entry<K1,V1>>)' in 'NachCollections' cannot be applied to '(java.util.function.Consumer<java.util.Map.Entry<K,V>>)'">(a)</error>);
c2.forEach(<error descr="Incompatible types. Required Consumer<? super capture of ? super Entry<K, V>> but 'consumer' was inferred to Consumer<Entry<K1, V1>>:
no instance(s) of type variable(s) K1, V1 exist so that capture of ? super Entry<K, V> conforms to Entry<K1, V1>">consumer(a)</error>);
}
}
@@ -7,8 +7,10 @@ public class Sample {
<B> B bar(G<B> gb) {return null;}
void f(G1 g1) {
G<String> l11 = bar<error descr="'bar(Sample.G<B>)' in 'Sample' cannot be applied to '(Sample.G1)'">(g1)</error>;
String l1 = bar<error descr="'bar(Sample.G<B>)' in 'Sample' cannot be applied to '(Sample.G1)'">(g1)</error>;
G<String> l11 = <error descr="Incompatible types. Required G<String> but 'bar' was inferred to B:
Incompatible types: Object is not convertible to G<String>">bar(g1);</error>
String l1 = <error descr="Incompatible types. Required String but 'bar' was inferred to B:
Incompatible types: Object is not convertible to String">bar(g1);</error>
Object o = bar(g1);
}
}
@@ -2,14 +2,27 @@ class Test {
{
Holder h = null;
Result<String> r1 = new Result<error descr="Cannot infer arguments"><></error>(h);
Result<String> r2 = Result.create<error descr="'create(K)' in 'Result' cannot be applied to '(Holder)'">(h)</error>;
Result<String> r2 = <error descr="Incompatible types. Required Result<String> but 'create' was inferred to Result<K>:
no instance(s) of type variable(s) exist so that Holder conforms to String
inference variable K has incompatible bounds:
equality constraints: String
lower bounds: Holder">Result.create(h);</error>
Holder dataHolder = null;
Result<String> r3 = new Result<error descr="Cannot infer arguments"><></error>(new Holder<error descr="Cannot infer arguments"><></error>(dataHolder));
Result<String> r4 = Result.create(new Holder<error descr="Cannot infer arguments"><></error>(dataHolder));
Result<String> r4 = <error descr="Incompatible types. Required Result<String> but 'create' was inferred to Result<K>:
no instance(s) of type variable(s) exist so that Holder conforms to String
inference variable K has incompatible bounds:
equality constraints: String
lower bounds: Holder">Result.create(new Holder<>(dataHolder));</error>
Result<String> r5 = new Result<error descr="Cannot infer arguments"><></error>(Holder.create<error descr="'create(Holder<M>)' in 'Holder' cannot be applied to '(Holder)'">(dataHolder)</error>);
Result<String> r6 = Result.create(Holder.create<error descr="'create(Holder<M>)' in 'Holder' cannot be applied to '(Holder)'">(dataHolder)</error>);
Result<String> r5 = new Result<error descr="Cannot infer arguments"><></error>(<error descr="Incompatible types. Required D but 'create' was inferred to Holder<M>:
Incompatible types: Holder is not convertible to D">Holder.create(dataHolder)</error>);
Result<String> r6 = <error descr="Incompatible types. Required Result<String> but 'create' was inferred to Result<K>:
no instance(s) of type variable(s) exist so that Holder conforms to String
inference variable K has incompatible bounds:
equality constraints: String
lower bounds: Holder">Result.create(Holder.create(dataHolder));</error>
}
}
@@ -7,6 +7,6 @@ class Test2 {
}
{
foo (bar<error descr="'bar(java.lang.Class<T>)' in 'Test2' cannot be applied to '(java.lang.Class<java.lang.String>)'">(String.class)</error>, "");
foo (bar(String.class), <error descr="'foo(java.lang.String, java.lang.Integer)' in 'Test2' cannot be applied to '(T, java.lang.String)'">""</error>);
}
}
@@ -20,10 +20,10 @@ class TestIDEA128101 {
public static void test() {
construct(String.class, createPath(integerAttribute), createPath(stringAttribute));
construct1(String.class, createPath<error descr="'createPath(TestIDEA128101.Attribute<Y>)' in 'TestIDEA128101' cannot be applied to '(TestIDEA128101.Attribute<java.lang.Integer>)'">(integerAttribute)</error>, createPath(stringAttribute));
construct1<error descr="'construct1(java.lang.Class<T>, TestIDEA128101.Path<K>...)' in 'TestIDEA128101' cannot be applied to '(java.lang.Class<java.lang.String>, TestIDEA128101.Path<Y>, TestIDEA128101.Path<java.lang.String>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
construct2(String.class, createPath(integerAttribute), createPath(stringAttribute));
construct3(String.class, createPath<error descr="'createPath(TestIDEA128101.Attribute<Y>)' in 'TestIDEA128101' cannot be applied to '(TestIDEA128101.Attribute<java.lang.Integer>)'">(integerAttribute)</error>, createPath<error descr="'createPath(TestIDEA128101.Attribute<Y>)' in 'TestIDEA128101' cannot be applied to '(TestIDEA128101.Attribute<java.lang.String>)'">(stringAttribute)</error>);
construct4(String.class, createPath<error descr="'createPath(TestIDEA128101.Attribute<Y>)' in 'TestIDEA128101' cannot be applied to '(TestIDEA128101.Attribute<java.lang.Integer>)'">(integerAttribute)</error>, createPath<error descr="'createPath(TestIDEA128101.Attribute<Y>)' in 'TestIDEA128101' cannot be applied to '(TestIDEA128101.Attribute<java.lang.String>)'">(stringAttribute)</error>);
construct3<error descr="'construct3(java.lang.Class<java.lang.String>, TestIDEA128101.Path<? super K>...)' in 'TestIDEA128101' cannot be applied to '(java.lang.Class<java.lang.String>, TestIDEA128101.Path<Y>, TestIDEA128101.Path<Y>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
construct4<error descr="'construct4(java.lang.Class<java.lang.String>, TestIDEA128101.Path<? super K>, TestIDEA128101.Path<? super K>)' in 'TestIDEA128101' cannot be applied to '(java.lang.Class<java.lang.String>, TestIDEA128101.Path<Y>, TestIDEA128101.Path<Y>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
}
}
@@ -3,10 +3,14 @@ import java.util.Map;
class Test {
public static void main(String[] args) {
Map<Object, Object> b = newMapTrie<error descr="'newMapTrie()' in 'Test' cannot be applied to '()'">()</error>;
Map<Object, Map<Object, Object>> c = newMapTrie<error descr="'newMapTrie()' in 'Test' cannot be applied to '()'">()</error>;
Map<Object, Map<Object, Map<Object, Object>>> d = newMapTrie<error descr="'newMapTrie()' in 'Test' cannot be applied to '()'">()</error>;
Map<Object, Map<Object, Map<Object, Map<Object, Object>>>> e = newMapTrie<error descr="'newMapTrie()' in 'Test' cannot be applied to '()'">()</error>;
Map<Object, Object> b = <error descr="Incompatible types. Required Map<Object, Object> but 'newMapTrie' was inferred to T:
Incompatible equality constraint: Byte and Object">newMapTrie();</error>
Map<Object, Map<Object, Object>> c = <error descr="Incompatible types. Required Map<Object, Map<Object, Object>> but 'newMapTrie' was inferred to T:
Incompatible equality constraint: Byte and Object">newMapTrie();</error>
Map<Object, Map<Object, Map<Object, Object>>> d = <error descr="Incompatible types. Required Map<Object, Map<Object, Map<Object, Object>>> but 'newMapTrie' was inferred to T:
Incompatible equality constraint: Byte and Object">newMapTrie();</error>
Map<Object, Map<Object, Map<Object, Map<Object, Object>>>> e = <error descr="Incompatible types. Required Map<Object, Map<Object, Map<Object, Map<Object, Object>>>> but 'newMapTrie' was inferred to T:
Incompatible equality constraint: Byte and Object">newMapTrie();</error>
}
public static <T extends Map<Byte, T>> T newMapTrie() {
@@ -6,7 +6,11 @@ class Test {
Factory factory = new Factory();
final Class<? extends ClassB> bClass = null;
ClassB b = factory.create(bClass);
String str = factory.create<error descr="'create(java.lang.Class<T>)' in 'Test.Factory' cannot be applied to '(java.lang.Class<capture<? extends Test.ClassB>>)'">(bClass)</error>;
String str = <error descr="Incompatible types. Required String but 'create' was inferred to T:
no instance(s) of type variable(s) exist so that capture of ? extends ClassB conforms to String
inference variable T has incompatible bounds:
equality constraints: capture of ? extends ClassB
upper bounds: ClassA<I>, Object, String">factory.create(bClass);</error>
}
public static class Factory {
@@ -29,7 +29,8 @@ public class ConcurrentCollectors {
static <T, K, D, M1 extends Map<K, D>> C<T, M1> groupingBy(F<M1> f,
C<T, D> c,
BiConsumer<M1, T> consumer) {
return new CImpl<error descr="Cannot infer arguments"><></error>(f, consumer, arg<error descr="'arg(ConcurrentCollectors.BiOp<V>)' in 'ConcurrentCollectors.Test3' cannot be applied to '(ConcurrentCollectors.BiOp<D>)'">(c.getOp())</error>);
return new CImpl<error descr="Cannot infer arguments"><></error>(f, consumer, <error descr="Incompatible types. Required BiOp<R> but 'arg' was inferred to BiOp<M2>:
no instance(s) of type variable(s) K, V exist so that R conforms to ConcurrentMap<K, V>">arg(c.getOp())</error>);
}
static <K, V, M2 extends ConcurrentMap<K, V>> BiOp<M2> arg(BiOp<V> op) {
@@ -6,7 +6,9 @@ class Test {
}
void m(List l){
boolean foo = foo<error descr="'foo(java.util.List<T>)' in 'Test' cannot be applied to '(java.util.List)'">(l)</error>;
String s = foo<error descr="'foo(java.util.List<T>)' in 'Test' cannot be applied to '(java.util.List)'">(l)</error>;
boolean foo = <error descr="Incompatible types. Required boolean but 'foo' was inferred to T:
Incompatible types: Object is not convertible to boolean">foo(l);</error>
String s = <error descr="Incompatible types. Required String but 'foo' was inferred to T:
Incompatible types: Object is not convertible to String">foo(l);</error>
}
}
@@ -37,7 +37,11 @@ class Test1 {
if (s.equals("1")) {
return Option.option(1);
} else {
return Option.option<error descr="'option(T)' in 'Test1.Option' cannot be applied to '(java.lang.String)'">("2")</error>;
return <error descr="Incompatible types. Required Option<Integer> but 'option' was inferred to Option<T>:
no instance(s) of type variable(s) exist so that String conforms to Integer
inference variable T has incompatible bounds:
equality constraints: Integer
lower bounds: String">Option.option("2");</error>
}
};
}
@@ -24,7 +24,7 @@ class AlienTest {
static {
IInt i1 = MyTest::<error descr="Cannot resolve method 'abracadabra'">abracadabra</error>;
IInt i2 = MyTest::<error descr="Invalid method reference: int cannot be converted to String">foo</error>;
IInt i2 = MyTest::<error descr="Cannot resolve method 'foo'">foo</error>;
IInt i3 = MyTest::<error descr="Cannot resolve method 'bar'">bar</error>;
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IIntInt'">IIntInt i4 = MyTest::bar;</error>
IInt i5 = <error descr="Non-static method cannot be referenced from a static context">MyTest::baz</error>;
@@ -47,7 +47,7 @@ class MyTest1 {
}
{
Bar1 b1 = MyTest2 :: <error descr="Invalid method reference: String cannot be converted to int">foo</error>;
Bar1 b1 = MyTest2 :: <error descr="Cannot resolve method 'foo'">foo</error>;
bar(MyTest1 :: foo);
}
}
@@ -73,7 +73,7 @@ class MyTest2 {
}*/
{
Bar1 b1 = MyTest2 :: <error descr="Invalid method reference: String cannot be converted to int">foo</error>;
Bar1 b1 = MyTest2 :: <error descr="Cannot resolve method 'foo'">foo</error>;
bar(MyTest2 :: foo);
}
}
@@ -99,8 +99,8 @@ class MyTest3 {
}
{
Bar1 b1 = MyTest2 :: <error descr="Invalid method reference: String cannot be converted to int">foo</error>;
bar(MyTest3 :: <error descr="Invalid method reference: int cannot be converted to String">foo</error>);
Bar1 b1 = MyTest2 :: <error descr="Cannot resolve method 'foo'">foo</error>;
bar(MyTest3 :: <error descr="Cannot resolve method 'foo'">foo</error>);
}
}
@@ -2,7 +2,7 @@ class Test {
{
Runnable b = Test :: <error descr="Cannot resolve method 'length'">length</error>;
Comparable<String> c = Test :: length;
Comparable<Integer> c1 = Test :: <error descr="Invalid method reference: Integer cannot be converted to String">length</error>;
Comparable<Integer> c1 = Test :: <error descr="Cannot resolve method 'length'">length</error>;
}
public static Integer length(String s) {
@@ -49,7 +49,7 @@ class MyTest {
static {
I1 i1 = MyTest::static_1;
I1 i2 = MyTest::<error descr="Cannot resolve method 'static_2'">static_2</error>;
I1 i3 = MyTest::<error descr="Invalid method reference: int cannot be converted to String">static_3</error>;
I1 i3 = MyTest::<error descr="Cannot resolve method 'static_3'">static_3</error>;
I1 i4 = MyTest::<error descr="Cannot resolve method 'static_4'">static_4</error>;
}
@@ -62,7 +62,7 @@ class MyTest {
I1 i1 = this::_1;
I1 i2 = this::<error descr="Cannot resolve method '_2'">_2</error>;
I1 i3 = this::<error descr="Invalid method reference: int cannot be converted to String">_3</error>;
I1 i3 = this::<error descr="Cannot resolve method '_3'">_3</error>;
I1 i4 = this::<error descr="Cannot resolve method '_4'">_4</error>;
I2 i21 = MyTest::<error descr="Cannot resolve method 'm1'">m1</error>;
@@ -32,7 +32,7 @@ class Test1 {
}
{
bar(l -> baz<error descr="'baz(T)' in 'Test1' cannot be applied to '(java.lang.Object)'">(l)</error>);
bar(l -> <error descr="Unhandled exception: Test1.MyEx">baz(l)</error>);
bar(<error descr="Unhandled exception: Test1.MyEx">this::baz</error>);
}
}
@@ -22,10 +22,14 @@ abstract class FooBar<M> {
}
class Test {
<T> List<List<Object>> foo(List<T> objects, Function<T, ?>... functions) {
return objects.stream()
return <error descr="Incompatible types. Required List<List<Object>> but 'collect' was inferred to R:
no instance(s) of type variable(s) exist so that List<capture of ?> conforms to List<Object>
inference variable T has incompatible bounds:
equality constraints: List<Object>
lower bounds: List<capture of ?>">objects.stream()
.map(object -> Arrays.stream(functions)
.map(fn -> fn.apply(object))
.collect(toList()))
.collect(toList<error descr="'toList()' in 'java.util.stream.Collectors' cannot be applied to '()'">()</error>);
.collect(toList());</error>
}
}
@@ -9,7 +9,11 @@ class Test {
<R> SuperFoo<R> foo(I<R> ax) { return null; }
SuperFoo<String> ls = foo(() -> new Foo<error descr="Cannot infer arguments"><></error>());
SuperFoo<String> ls = foo(<error descr="Incompatible types. Required SuperFoo<String> but 'foo' was inferred to SuperFoo<R>:
no instance(s) of type variable(s) exist so that String conforms to Number
inference variable R has incompatible bounds:
equality constraints: String
upper bounds: Object, Number">() -> new Foo<>()</error>);
SuperFoo<Integer> li = foo(() -> new Foo<>());
SuperFoo<?> lw = foo(() -> new Foo<>());
}
@@ -26,10 +26,7 @@ abstract class NoFormalParamTypeInferenceNeeded {
{
map(a -> zip(text -> text));
zip(a -> zip(text -> text));
Integer zip = zip(a -> zip(<error descr="no instance(s) of type variable(s) exist so that Object conforms to Integer
inference variable R has incompatible bounds:
lower bounds: Object
upper bounds: Object, Integer">text -> text</error>));
Integer zip = zip(a -> zip(text -> <error descr="Bad return type in lambda expression: Object cannot be converted to R">text</error>));
}
}
@@ -5,7 +5,7 @@ class A {
public static void main(String[] args) {
B<? extends CharSequence> q = new B<>();
Func x = q::<error descr="Invalid method reference: CharSequence cannot be converted to capture of ? extends CharSequence">foo</error>;
Func x = q::<error descr="Cannot resolve method 'foo'">foo</error>;
x.invoke("");
}
@@ -7,7 +7,7 @@ interface B<BT> {
class Test {
public static void test() {
method1(Test::<error descr="Invalid method reference: A<capture of ? super M> cannot be converted to A<? super String>">method2</error>);
method1(Test::<error descr="Cannot resolve method 'method2'">method2</error>);
}
static <M> void method1(B<A<? super M>> arg) { }
@@ -4,7 +4,7 @@ import java.util.function.Predicate;
class MyTest {
{
BiConsumer<Predicate<? extends Runnable>, Predicate<? extends Runnable>> or = MyTest::<error descr="Invalid method reference: Predicate<capture of ? extends Runnable> cannot be converted to Predicate<E>">or</error>;
BiConsumer<Predicate<? extends Runnable>, Predicate<? extends Runnable>> or = MyTest::<error descr="Cannot resolve method 'or'">or</error>;
}
private static <E extends Runnable> void or(Predicate<E> left, Predicate<E> right) {}
@@ -29,14 +29,14 @@ class Test {
static void meth4(I3 s) { }
static {
meth1(Foo::<error descr="Invalid constructor reference: String cannot be converted to Number">new</error>);
meth1(Foo::<error descr="Cannot resolve constructor 'Foo'">new</error>);
meth2(Foo::new);
meth3(Foo::<error descr="Invalid constructor reference: Object cannot be converted to Number">new</error>);
meth3(Foo::<error descr="Cannot resolve constructor 'Foo'">new</error>);
meth4<error descr="Ambiguous method call: both 'Test.meth4(I1)' and 'Test.meth4(I2)' match">(Foo::new)</error>;
meth1(Test::<error descr="Invalid method reference: String cannot be converted to X">foo</error>);
meth1(Test::<error descr="Cannot resolve method 'foo'">foo</error>);
meth2(Test::foo);
meth3(Test::<error descr="Invalid method reference: Object cannot be converted to X">foo</error>);
meth3(Test::<error descr="Cannot resolve method 'foo'">foo</error>);
meth4<error descr="Ambiguous method call: both 'Test.meth4(I1)' and 'Test.meth4(I2)' match">(Test::foo)</error>;
}
@@ -55,8 +55,8 @@ class Test {
}
void test() {
II1 i1 = this::<error descr="Invalid method reference: X cannot be converted to X">fooInstance</error>;
II1 i1 = this::<error descr="Cannot resolve method 'fooInstance'">fooInstance</error>;
II2 i2 = this::fooInstance;
II3 i3 = this::<error descr="Invalid method reference: X cannot be converted to X">fooInstance</error>;
II3 i3 = this::<error descr="Cannot resolve method 'fooInstance'">fooInstance</error>;
}
}
@@ -17,7 +17,7 @@ abstract class Test {
{
I i = Test::<String>foo;
I i1 = Test::<Integer><error descr="Invalid method reference: String cannot be converted to Integer">foo</error>;
I i1 = Test::<Integer><error descr="Cannot resolve method 'foo'">foo</error>;
I i2 = Test::foo;
}
@@ -4,7 +4,7 @@ class InlineRef {
<K> void foo(Consumer<K> f) {}
void bar(){
foo(Descriptor::<error descr="Invalid method reference: Object cannot be converted to Descriptor">getName</error>);
foo(Descriptor::<error descr="Cannot resolve method 'getName'">getName</error>);
}
}
@@ -4,6 +4,6 @@ import java.util.Comparator;
class Main {
public void test() {
Collections.sort(new ArrayList<error descr="Cannot infer arguments"><></error>(), <error descr="Non-static method cannot be referenced from a static context">Comparator::reversed</error>);
Collections.sort(new ArrayList<>(), <error descr="Non-static method cannot be referenced from a static context">Comparator::reversed</error>);
}
}
@@ -12,10 +12,7 @@ import java.util.function.Function;
class Test {
{
valueOf(processFirst(<error descr="no instance(s) of type variable(s) exist so that Integer conforms to char[]
inference variable V has incompatible bounds:
lower bounds: Integer
upper bounds: Object, char[]">x -> x</error>));
valueOf(processFirst(x -> <error descr="Bad return type in lambda expression: Integer cannot be converted to V">x</error>));
}
public static <V> V processFirst(Function<Integer,V> f){