new inference: avoid one type parameter inference

(cherry picked from commit f764e69e3f7e98e0c94e701706121069f2775586)
This commit is contained in:
anna
2013-11-20 20:15:17 +01:00
parent f3950b702d
commit 5f1db87624
4 changed files with 19 additions and 19 deletions

View File

@@ -582,25 +582,14 @@ public class LambdaUtil {
final Project project) {
if (interfaceMethodReturnType == null) return psiSubstitutor;
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(project).getResolveHelper();
final PsiSubstitutor substitutor =
resolveHelper.inferTypeArguments(typeParameters, new PsiType[]{interfaceMethodReturnType}, new PsiType[]{returnType}, languageLevel);
for (PsiTypeParameter typeParameter : typeParameters) {
final PsiType constraint = resolveHelper.getSubstitutionForTypeParameter(typeParameter, returnType, interfaceMethodReturnType, false, languageLevel);
if (constraint != PsiType.NULL && constraint != null) {
PsiType inferredType = null;
final PsiClassType[] bounds = typeParameter.getExtendsListTypes();
for (PsiClassType classTypeBound : bounds) {
if (TypeConversionUtil.isAssignable(classTypeBound, constraint)) {
inferredType = constraint;
break;
}
}
if (bounds.length == 0) {
inferredType = constraint;
}
if (inferredType != null) {
final PsiType inferredType = substitutor.substitute(typeParameter);
if (PsiUtil.resolveClassInType(inferredType) != typeParameter) {
psiSubstitutor = psiSubstitutor.put(typeParameter, inferredType);
}
}
}
return psiSubstitutor;
}

View File

@@ -65,7 +65,18 @@ public class PsiGraphInferenceHelper implements PsiInferenceHelper {
@NotNull PsiType[] rightTypes,
@NotNull LanguageLevel languageLevel) {
if (typeParameters.length == 0) return PsiSubstitutor.EMPTY;
return new InferenceSession(typeParameters, leftTypes, rightTypes, PsiSubstitutor.EMPTY, myManager).infer();
InferenceSession session = new InferenceSession(typeParameters, leftTypes, rightTypes, PsiSubstitutor.EMPTY, myManager);
for (PsiType leftType : leftTypes) {
if (!session.isProperType(leftType)) {
return session.infer();
}
}
for (PsiType rightType : rightTypes) {
if (!session.isProperType(rightType)) {
return session.infer();
}
}
return PsiSubstitutor.EMPTY;
}
@Override

View File

@@ -21,7 +21,7 @@ class MyTestDefaultConstructor {
private static void <warning descr="Private method 'foo(MyTestDefaultConstructor.I3)' is never used">foo</warning>(I3 i) {System.out.println(i);}
static {
foo<error descr="Cannot resolve method 'foo(<method reference>)'">(Foo::new)</error>;
foo<error descr="Ambiguous method call: both 'MyTestDefaultConstructor.foo(I1)' and 'MyTestDefaultConstructor.foo(I2)' match">(Foo::new)</error>;
}
}

View File

@@ -39,6 +39,6 @@ class MyTest1 {
static void foo(I3 i) {}
static {
foo<error descr="Ambiguous method call: both 'MyTest1.foo(I1)' and 'MyTest1.foo(I2)' match">(Foo::new)</error>;
foo<error descr="Cannot resolve method 'foo(<method reference>)'">(Foo::new)</error>;
}
}