mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
type compatibility constrain: unchecked conversion: return type is inference variable case
This commit is contained in:
+17
-1
@@ -332,7 +332,8 @@ public class InferenceSession {
|
||||
private InferenceVariable shouldResolveAndInstantiate(PsiType returnType, PsiType targetType) {
|
||||
final InferenceVariable inferenceVariable = getInferenceVariable(returnType);
|
||||
if (inferenceVariable != null) {
|
||||
if (targetType instanceof PsiPrimitiveType && hasPrimitiveWrapperBound(inferenceVariable)) {
|
||||
if (targetType instanceof PsiPrimitiveType && hasPrimitiveWrapperBound(inferenceVariable) ||
|
||||
targetType instanceof PsiClassType && hasUncheckedBounds(inferenceVariable, (PsiClassType)targetType)) {
|
||||
return inferenceVariable;
|
||||
}
|
||||
}
|
||||
@@ -351,6 +352,21 @@ public class InferenceSession {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasUncheckedBounds(InferenceVariable inferenceVariable, PsiClassType targetType) {
|
||||
if (!targetType.isRaw()) {
|
||||
final InferenceBound[] boundTypes = {InferenceBound.EQ, InferenceBound.LOWER};
|
||||
for (InferenceBound inferenceBound : boundTypes) {
|
||||
final List<PsiType> bounds = inferenceVariable.getBounds(inferenceBound);
|
||||
for (PsiType bound : bounds) {
|
||||
if (TypeCompatibilityConstraint.isUncheckedConversion(targetType, bound)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private PsiType getTargetType(final PsiExpression context) {
|
||||
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
|
||||
+6
-5
@@ -19,7 +19,6 @@ 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,13 +55,16 @@ public class TypeCompatibilityConstraint implements ConstraintFormula {
|
||||
}
|
||||
}
|
||||
|
||||
if (isUncheckedConversion(session, myT, myS)) return true;
|
||||
if (isUncheckedConversion(myT, myS)) {
|
||||
session.setErased();
|
||||
return true;
|
||||
}
|
||||
|
||||
constraints.add(new SubtypingConstraint(myT, myS, true));
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isUncheckedConversion(InferenceSession session, final PsiType t, final PsiType s) {
|
||||
public static boolean isUncheckedConversion(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();
|
||||
@@ -71,13 +73,12 @@ public class TypeCompatibilityConstraint implements ConstraintFormula {
|
||||
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 isUncheckedConversion(t.getDeepComponentType(), s.getDeepComponentType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
public class Sample {
|
||||
interface G<A> {}
|
||||
interface G1 extends G {}
|
||||
|
||||
<B> B bar(B b) {return null;}
|
||||
|
||||
void f(G1 g1) {
|
||||
G<String> l11 = bar(g1);
|
||||
}
|
||||
}
|
||||
+4
@@ -38,6 +38,10 @@ public class ConstraintsInferenceMiscTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testTypeCompatibilityUncheckedConversionReturnConstraints() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
private void doTest(final boolean checkWarnings) {
|
||||
doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user