type compatibility constrain: unchecked conversion step

This commit is contained in:
Anna Kozlova
2014-01-31 21:41:15 +04:00
parent af8095f8b0
commit 5a9c00a259
5 changed files with 45 additions and 10 deletions
@@ -87,11 +87,6 @@ public class SubtypingConstraint implements ConstraintFormula {
final PsiSubstitutor tSubstitutor = TResult.getSubstitutor();
final PsiSubstitutor sSubstitutor = SClass != null ? TypeConversionUtil.getClassSubstitutor(CClass, SClass, SResult.getSubstitutor()) : null;
if (sSubstitutor != null) {
//18.2.2 Type Compatibility Constraints
if (PsiUtil.isRawSubstitutor(CClass, sSubstitutor)) {
session.setErased();
return true;
}
for (PsiTypeParameter parameter : CClass.getTypeParameters()) {
final PsiType tSubstituted = tSubstitutor.substitute(parameter);
final PsiType sSubstituted = sSubstitutor.substituteWithBoundsPromotion(parameter);
@@ -15,12 +15,11 @@
*/
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiPrimitiveType;
import com.intellij.psi.PsiSubstitutor;
import com.intellij.psi.PsiType;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.psi.util.TypesDistinctProver;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -56,10 +55,33 @@ public class TypeCompatibilityConstraint implements ConstraintFormula {
return true;
}
}
if (isUncheckedConversion(session, myT, myS)) return true;
constraints.add(new SubtypingConstraint(myT, myS, true));
return true;
}
private static boolean isUncheckedConversion(InferenceSession session, final PsiType t, final PsiType s) {
if (t instanceof PsiClassType && !((PsiClassType)t).isRaw() && s instanceof PsiClassType) {
final PsiClassType.ClassResolveResult tResult = ((PsiClassType)t).resolveGenerics();
final PsiClassType.ClassResolveResult sResult = ((PsiClassType)s).resolveGenerics();
final PsiClass tClass = tResult.getElement();
final PsiClass sClass = sResult.getElement();
if (tClass != null && sClass != null) {
final PsiSubstitutor sSubstitutor = TypeConversionUtil.getClassSubstitutor(tClass, sClass, sResult.getSubstitutor());
if (sSubstitutor != null && PsiUtil.isRawSubstitutor(tClass, sSubstitutor)) {
session.setErased();
return true;
}
}
}
else if (t instanceof PsiArrayType && t.getArrayDimensions() == s.getArrayDimensions()) {
return isUncheckedConversion(session, t.getDeepComponentType(), s.getDeepComponentType());
}
return false;
}
@Override
public void apply(PsiSubstitutor substitutor) {
myT = substitutor.substitute(myT);
@@ -10,7 +10,7 @@ class Test {
public void test(Set<MyConsumer> set) {
@SuppressWarnings("unchecked")
Map<Parent, MyConsumer<Parent>> map = <error descr="Inferred type 'T' for type parameter 'T' is not within its bound; should implement 'Test.Consumer<Test.Parent>'">create(set)</error>;
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>;
}
@@ -0,0 +1,14 @@
public class Sample {
interface G<A> {}
interface G1 extends G {}
void foo(G1 g1) {
bar(g1);
}
<B>void bar(G<B> gb) {}
void foo(G1[] g1) {
bar(g1);
}
<B>void bar(G<B>[] gb) {}
}
@@ -34,6 +34,10 @@ public class ConstraintsInferenceMiscTest extends LightDaemonAnalyzerTestCase {
doTest(false);
}
public void testTypeCompatibilityUncheckedConversion() throws Exception {
doTest(false);
}
private void doTest(final boolean checkWarnings) {
doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
}