diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
index f1d0858eb5a5..5eca81ab6e23 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
@@ -25,6 +25,7 @@ import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
import com.intellij.codeInspection.dataFlow.Nullness;
+import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.WriteExternalException;
@@ -158,6 +159,51 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo
}
return false;
}
+
+ @Override
+ public void visitAssignmentExpression(PsiAssignmentExpression expression) {
+ checkCollectionNullityOnAssignment(expression.getOperationSign(), expression.getLExpression().getType(), expression.getRExpression());
+ }
+
+ @Override
+ public void visitLocalVariable(PsiLocalVariable variable) {
+ PsiIdentifier identifier = variable.getNameIdentifier();
+ if (identifier != null) {
+ checkCollectionNullityOnAssignment(identifier, variable.getType(), variable.getInitializer());
+ }
+ }
+
+ @Override
+ public void visitCallExpression(PsiCallExpression callExpression) {
+ PsiExpressionList argList = callExpression.getArgumentList();
+ JavaResolveResult result = callExpression.resolveMethodGenerics();
+ PsiMethod method = (PsiMethod)result.getElement();
+ if (method == null || argList == null) return;
+
+ PsiSubstitutor substitutor = result.getSubstitutor();
+ PsiParameter[] parameters = method.getParameterList().getParameters();
+ PsiExpression[] arguments = argList.getExpressions();
+ for (int i = 0; i < arguments.length; i++) {
+ PsiExpression argument = arguments[i];
+ if (i < parameters.length &&
+ (i < parameters.length - 1 || !MethodCallInstruction.isVarArgCall(method, substitutor, arguments, parameters))) {
+ checkCollectionNullityOnAssignment(argument, substitutor.substitute(parameters[i].getType()), argument);
+ }
+ }
+ }
+
+ private void checkCollectionNullityOnAssignment(@NotNull PsiElement errorElement, PsiType expectedType, PsiExpression assignedExpression) {
+ PsiType lItemType = JavaGenericsUtil.getCollectionItemType(expectedType, errorElement.getResolveScope());
+ PsiType rItemType = assignedExpression == null ? null : JavaGenericsUtil.getCollectionItemType(assignedExpression);
+
+ if (DfaPsiUtil.getTypeNullability(lItemType) == Nullness.NOT_NULL &&
+ DfaPsiUtil.getTypeNullability(rItemType) == Nullness.NULLABLE) {
+ holder.registerProblem(errorElement,
+ "Assigning a collection of nullable elements into a collection of non-null elements",
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+
+ }
+ }
};
}
diff --git a/java/java-tests/testData/inspection/nullableProblems/PassingNullableCollectionWhereNotNullIsExpected.java b/java/java-tests/testData/inspection/nullableProblems/PassingNullableCollectionWhereNotNullIsExpected.java
new file mode 100644
index 000000000000..fecc38e39a94
--- /dev/null
+++ b/java/java-tests/testData/inspection/nullableProblems/PassingNullableCollectionWhereNotNullIsExpected.java
@@ -0,0 +1,21 @@
+import typeUse.*;
+import java.util.*;
+
+class JC {
+
+ public static void main(String[] args) {
+ List<@Nullable String> list = new ArrayList<>();
+ print(list);
+
+ List<@NotNull String> list2 = list;
+
+ List<@NotNull String> list3;
+ list2 = list;
+ }
+
+ private static void print(List<@NotNull String> list) {
+ for (String s : list) {
+ System.out.println(s.length());
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java
index 4f95f5cd5494..7303709d892f 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java
@@ -207,4 +207,9 @@ public class NullableStuffInspectionTest extends LightCodeInsightFixtureTestCase
doTest();
}
+ public void testPassingNullableCollectionWhereNotNullIsExpected() {
+ DataFlowInspection8Test.setupTypeUseAnnotations("typeUse", myFixture);
+ doTest();
+ }
+
}
\ No newline at end of file