Bug 482242 - [compiler][null] option to raise problems when unsafely
passing annotated parameterized types into unannotated code

Change-Id: Ifd22f01d180a41fc1e7e9f878bfa6060c354e11f
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index 4bb4689..ecafbcb 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -1020,7 +1020,8 @@
 			"		<option key=\"org.eclipse.jdt.core.compiler.emulateJavacBug8031744\" value=\"enabled\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.generateClassFiles\" value=\"enabled\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.maxProblemPerUnit\" value=\"100\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.APILeak\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.APILeak\" value=\"warning\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated\" value=\"info\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.annotationSuperInterface\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.autoboxing\" value=\"ignore\"/>\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
index 658c2e1..7cbe5d7 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
@@ -8289,7 +8289,7 @@
 		?
 		"	@NonNull MyEnum[] getValues() {\n"
 		:
-		"	MyEnum @NonNull[] getValues() {\n"
+		"	@NonNull MyEnum @NonNull[] getValues() {\n"
 		)+
 		"		return MyEnum.values();\n" +
 		"	}\n" +
@@ -8325,7 +8325,7 @@
 		?
 		"	@NonNull MyEnum[] getValues() {\n"
 		:
-		"	MyEnum @NonNull[] getValues() {\n"
+		"	@NonNull MyEnum @NonNull[] getValues() {\n"
 		)+
 		"		return MyEnum.values();\n" +
 		"	}\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index 1f67c69..19c0690 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2019 GK Software AG and others.
+ * Copyright (c) 2012, 2020 GK Software AG and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -827,6 +827,8 @@
 
 	// issue from https://bugs.eclipse.org/bugs/show_bug.cgi?id=403216#c7
 	public void testBug403216_2() {
+		Map options = getCompilerOptions();
+		options.put(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.IGNORE);
 		runConformTestWithLibs(
 			new String[] {
 				"X.java",
@@ -839,7 +841,7 @@
 				"    }\n" +
 				"}\n"
 			},
-			getCompilerOptions(),
+			options,
 			"");
 	}
 	
@@ -1451,7 +1453,7 @@
 				"3. ERROR in Y1.java (at line 11)\n" + 
 				"	x.wildcard1(new ArrayList<@NonNull X1>()); // incompatible\n" + 
 				"	            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-				"Null type mismatch (type annotations): required \'List<@Nullable ? extends X1>\' but this expression has type \'ArrayList<@NonNull X1>\', corresponding supertype is \'List<@NonNull X1>\'\n" + 
+				"Null type mismatch (type annotations): required \'List<@Nullable ? extends X1>\' but this expression has type \'@NonNull ArrayList<@NonNull X1>\', corresponding supertype is \'List<@NonNull X1>\'\n" + 
 				"----------\n");
 	}
 
@@ -1531,7 +1533,7 @@
 				"3. ERROR in Y1.java (at line 11)\n" + 
 				"	x.wildcard1(new ArrayList<p.@NonNull X1>()); // incompatible\n" + 
 				"	            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-				"Null type mismatch (type annotations): required \'List<@Nullable ? extends X1>\' but this expression has type \'ArrayList<@NonNull X1>\', corresponding supertype is \'List<@NonNull X1>\'\n" + 
+				"Null type mismatch (type annotations): required \'List<@Nullable ? extends X1>\' but this expression has type \'@NonNull ArrayList<@NonNull X1>\', corresponding supertype is \'List<@NonNull X1>\'\n" + 
 				"----------\n");
 	}
 	
@@ -1829,6 +1831,8 @@
 
 	// types with null annotations on details (type parameter) are compatible to types lacking the annotation
 	public void testCompatibility2() {
+		Map options = getCompilerOptions();
+		options.put(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.IGNORE);
 		runConformTestWithLibs(
 			new String[] {
 				"X.java",
@@ -1857,7 +1861,7 @@
 				+ "	void takeAny(List<String> any) {}\n"
 				+ "}\n"
 			},
-			getCompilerOptions(),
+			options,
 			"");
 	}
 
@@ -3124,7 +3128,7 @@
 			"1. WARNING in X.java (at line 8)\n" + 
 			"	List<@NonNull ? extends @NonNull String> ls = new ArrayList<String>();\n" + 
 			"	                                              ^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-			"Null type safety (type annotations): The expression of type \'ArrayList<String>\' needs unchecked conversion to conform to \'List<@NonNull ? extends @NonNull String>\', corresponding supertype is 'List<String>'\n" + 
+			"Null type safety (type annotations): The expression of type \'@NonNull ArrayList<String>\' needs unchecked conversion to conform to \'List<@NonNull ? extends @NonNull String>\', corresponding supertype is 'List<String>'\n" + 
 			"----------\n" + 
 			"2. ERROR in X.java (at line 9)\n" + 
 			"	ls.add(null);\n" + 
@@ -3255,7 +3259,12 @@
 				"}\n"
 			},
 			getCompilerOptions(),
-			"");
+			"----------\n" + 
+			"1. INFO in X.java (at line 9)\n" + 
+			"	X<String> x = new Y();\n" + 
+			"	              ^^^^^^^\n" + 
+			"Null type safety (type annotations): The expression of type '@NonNull Y' needs unchecked conversion to conform to 'X<String>', corresponding supertype is 'X<@NonNull String>'\n" + 
+			"----------\n");
 	}
 
 	public void testBug416181() {
@@ -3317,7 +3326,7 @@
 			"1. WARNING in X.java (at line 9)\n" + 
 			"	X<@Nullable String> xs = new X<String>();\n" + 
 			"	                         ^^^^^^^^^^^^^^^\n" + 
-			"Null type safety (type annotations): The expression of type \'X<String>\' needs unchecked conversion to conform to \'X<@Nullable String>\'\n" + 
+			"Null type safety (type annotations): The expression of type \'@NonNull X<String>\' needs unchecked conversion to conform to \'X<@Nullable String>\'\n" + 
 			"----------\n" + 
 			"2. ERROR in X.java (at line 10)\n" + 
 			"	xs.foo(null);\n" + 
@@ -3363,7 +3372,7 @@
 			"1. WARNING in X.java (at line 10)\n" + 
 			"	X<@Nullable String> xs = new X<String>();\n" + 
 			"	                         ^^^^^^^^^^^^^^^\n" + 
-			"Null type safety (type annotations): The expression of type \'X<String>\' needs unchecked conversion to conform to \'X<@Nullable String>\'\n" + 
+			"Null type safety (type annotations): The expression of type \'@NonNull X<String>\' needs unchecked conversion to conform to \'X<@Nullable String>\'\n" + 
 			"----------\n" + 
 			"2. ERROR in X.java (at line 12)\n" + 
 			"	xs.foo(null);\n" + 
@@ -3466,7 +3475,7 @@
 			"2. WARNING in X.java (at line 10)\n" + 
 			"	s.foo(new ArrayList<String>()); // (1)\n" + 
 			"	      ^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-			"Null type safety (type annotations): The expression of type \'ArrayList<String>\' needs unchecked conversion to conform to \'@NonNull List<@NonNull String>\', corresponding supertype is 'List<String>'\n" + 
+			"Null type safety (type annotations): The expression of type \'@NonNull ArrayList<String>\' needs unchecked conversion to conform to \'@NonNull List<@NonNull String>\', corresponding supertype is 'List<String>'\n" + 
 			"----------\n" + 
 			"3. ERROR in X.java (at line 11)\n" + 
 			"	s.foo(null); // (2)\n" + 
@@ -3667,12 +3676,17 @@
 			"	                                                                               ^^^^\n" + 
 			"Null type mismatch: required \'@NonNull String\' but the provided value is null\n" + 
 			"----------\n" + 
-			"2. ERROR in X.java (at line 7)\n" + 
+			"2. INFO in X.java (at line 7)\n" + 
+			"	@NonNull String @NonNull [][] s2 = new @NonNull String [] @NonNull [] { null, { null} }; // problem at both nulls\n" + 
+			"	                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+			"Null type safety (type annotations): The expression of type \'@NonNull String [] @NonNull[]\' needs unchecked conversion to conform to \'@NonNull String @NonNull[] []\'\n" + 
+			"----------\n" + 
+			"3. ERROR in X.java (at line 7)\n" + 
 			"	@NonNull String @NonNull [][] s2 = new @NonNull String [] @NonNull [] { null, { null} }; // problem at both nulls\n" + 
 			"	                                                                        ^^^^\n" + 
 			"Null type mismatch: required \'@NonNull String @NonNull[]\' but the provided value is null\n" + 
 			"----------\n" + 
-			"3. ERROR in X.java (at line 7)\n" + 
+			"4. ERROR in X.java (at line 7)\n" + 
 			"	@NonNull String @NonNull [][] s2 = new @NonNull String [] @NonNull [] { null, { null} }; // problem at both nulls\n" + 
 			"	                                                                                ^^^^\n" + 
 			"Null type mismatch: required \'@NonNull String\' but the provided value is null\n" + 
@@ -3682,6 +3696,8 @@
 	// https://bugs.eclipse.org/417758 - [1.8][null] Null safety compromise during array creation.
 	// three-dim array with annotations on dimensions, also assignment has a problem
 	public void testArray3() {
+		Map options = getCompilerOptions();
+		options.put(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.WARNING);
 		runNegativeTestWithLibs(
 			new String[] {
 				"X.java",
@@ -3694,7 +3710,7 @@
 				"	}\n" + 
 				"}"
 			},
-			getCompilerOptions(),
+			options,
 			"----------\n" + 
 			"1. WARNING in X.java (at line 6)\n" + 
 			"	@NonNull String [][] @NonNull [] s = new @NonNull String []@NonNull [][] { null, { {null}, null/*ok*/ } };\n" + 
@@ -4710,7 +4726,7 @@
 		"1. ERROR in X.java (at line 5)\n" + 
 		"	List<@NonNull Person> l = new ArrayList<@Nullable Person>();}\n" + 
 		"	                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'List<@NonNull Person>\' but this expression has type \'ArrayList<@Nullable Person>\', corresponding supertype is \'List<@Nullable Person>\'\n" + 
+		"Null type mismatch (type annotations): required \'List<@NonNull Person>\' but this expression has type \'@NonNull ArrayList<@Nullable Person>\', corresponding supertype is \'List<@Nullable Person>\'\n" + 
 		"----------\n");
 }
 public void testBug430219() {
@@ -4777,7 +4793,7 @@
 		"2. ERROR in X.java (at line 7)\n" + 
 		"	return new ArrayList<@Nullable Number>(); // ERR\n" + 
 		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'List<@NonNull Number>\' but this expression has type \'ArrayList<@Nullable Number>\', corresponding supertype is \'List<@Nullable Number>\'\n" + 
+		"Null type mismatch (type annotations): required \'List<@NonNull Number>\' but this expression has type \'@NonNull ArrayList<@Nullable Number>\', corresponding supertype is \'List<@Nullable Number>\'\n" + 
 		"----------\n" + 
 		"3. ERROR in X.java (at line 10)\n" + 
 		"	in.add(null); // ERR\n" + 
@@ -4787,7 +4803,7 @@
 		"4. ERROR in X.java (at line 11)\n" + 
 		"	return new ArrayList<java.lang.@Nullable Number>(); // ERR\n" + 
 		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'List<@NonNull Number>\' but this expression has type \'ArrayList<@Nullable Number>\', corresponding supertype is \'List<@Nullable Number>\'\n" + 
+		"Null type mismatch (type annotations): required \'List<@NonNull Number>\' but this expression has type \'@NonNull ArrayList<@Nullable Number>\', corresponding supertype is \'List<@Nullable Number>\'\n" + 
 		"----------\n");
 }
 
@@ -4823,7 +4839,7 @@
 		"3. ERROR in X.java (at line 8)\n" + 
 		"	return new ArrayList<@Nullable T>(); // NOK, cannot assume nullable for T in List<T>\n" + 
 		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'List<T>\' but this expression has type \'ArrayList<@Nullable T>\', corresponding supertype is \'List<@Nullable T>\'\n" + 
+		"Null type mismatch (type annotations): required \'List<T>\' but this expression has type \'@NonNull ArrayList<@Nullable T>\', corresponding supertype is \'List<@Nullable T>\'\n" + 
 		"----------\n");
 }
 
@@ -5129,7 +5145,7 @@
 		"4. ERROR in X.java (at line 13)\n" + 
 		"	@NonNull Number nnn = inner.process(Integer.valueOf(3), new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" + 
 		"	                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'List<? extends @NonNull Number>\' but this expression has type \'ArrayList<@Nullable Integer>\', corresponding supertype is \'List<@Nullable Integer>\'\n" + 
+		"Null type mismatch (type annotations): required \'List<? extends @NonNull Number>\' but this expression has type \'@NonNull ArrayList<@Nullable Integer>\', corresponding supertype is \'List<@Nullable Integer>\'\n" + 
 		"----------\n");
 }
 
@@ -5170,7 +5186,7 @@
 		"1. ERROR in Y.java (at line 5)\n" + 
 		"	x.test1(new ArrayList<@Nullable Number>()) // ERR at arg\n" + 
 		"	        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'List<@NonNull Number>\' but this expression has type \'ArrayList<@Nullable Number>\', corresponding supertype is \'List<@Nullable Number>\'\n" + 
+		"Null type mismatch (type annotations): required \'List<@NonNull Number>\' but this expression has type \'@NonNull ArrayList<@Nullable Number>\', corresponding supertype is \'List<@Nullable Number>\'\n" + 
 		"----------\n" + 
 		"2. ERROR in Y.java (at line 6)\n" + 
 		"	.add(null); // ERR\n" + 
@@ -5410,7 +5426,7 @@
 		"2. ERROR in Y.java (at line 5)\n" + 
 		"	@NonNull Number nnn = inner.process(Integer.valueOf(3), new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" + 
 		"	                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'List<? extends @NonNull Number>\' but this expression has type \'ArrayList<@Nullable Integer>\', corresponding supertype is \'List<@Nullable Integer>\'\n" + 
+		"Null type mismatch (type annotations): required \'List<? extends @NonNull Number>\' but this expression has type \'@NonNull ArrayList<@Nullable Integer>\', corresponding supertype is \'List<@Nullable Integer>\'\n" + 
 		"----------\n");
 }
 public void testBug431269() {
@@ -6620,7 +6636,12 @@
 			"}\n"
 		},
 		getCompilerOptions(),
-		"");
+		"----------\n" + 
+		"1. INFO in Extract.java (at line 9)\n" + 
+		"	return new R<@NonNull A>(null);\n" + 
+		"	       ^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Null type safety (type annotations): The expression of type '@NonNull R<@NonNull A>' needs unchecked conversion to conform to 'R<A>'\n" + 
+		"----------\n");
 }
 public void testBug439298_comment4() {
 	runConformTestWithLibs(
@@ -8160,7 +8181,7 @@
 		"1. ERROR in X.java (at line 8)\n" + 
 		"	return zork(new FI<>());\n" + 
 		"	            ^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'F0<@NonNull String>\' but this expression has type \'FI<@Nullable String>\', corresponding supertype is \'F0<@Nullable String>\'\n" + 
+		"Null type mismatch (type annotations): required \'F0<@NonNull String>\' but this expression has type \'@NonNull FI<@Nullable String>\', corresponding supertype is \'F0<@Nullable String>\'\n" + 
 		"----------\n");
 }
 public void testBug448709_allocationExpression2() {
@@ -11983,7 +12004,7 @@
 		"12. WARNING in nonnull\\WildcardNonNullTest.java (at line 81)\n" + 
 		"	g(new A<T2>());\n" + 
 		"	  ^^^^^^^^^^^\n" + 
-		"Null type safety (type annotations): The expression of type \'A<T2>\' needs unchecked conversion to conform to \'@NonNull A<@NonNull T2>\'\n" + 
+		"Null type safety (type annotations): The expression of type \'@NonNull A<T2>\' needs unchecked conversion to conform to \'@NonNull A<@NonNull T2>\'\n" + 
 		"----------\n" + 
 		"13. ERROR in nonnull\\WildcardNonNullTest.java (at line 81)\n" + 
 		"	g(new A<T2>());\n" + 
@@ -11998,7 +12019,7 @@
 		"15. ERROR in nonnull\\WildcardNonNullTest.java (at line 87)\n" + 
 		"	g(new A<@Nullable T2>());\n" + 
 		"	  ^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'@NonNull A<@NonNull T2>\' but this expression has type \'A<@Nullable T2>\'\n" + 
+		"Null type mismatch (type annotations): required \'@NonNull A<@NonNull T2>\' but this expression has type \'@NonNull A<@Nullable T2>\'\n" + 
 		"----------\n" + 
 		"16. ERROR in nonnull\\WildcardNonNullTest.java (at line 87)\n" + 
 		"	g(new A<@Nullable T2>());\n" + 
@@ -12162,7 +12183,7 @@
 		"12. WARNING in nullable\\WildcardNullableTest.java (at line 81)\n" + 
 		"	g(new A<T2>());\n" + 
 		"	  ^^^^^^^^^^^\n" + 
-		"Null type safety (type annotations): The expression of type \'A<T2>\' needs unchecked conversion to conform to \'@NonNull A<@Nullable T2>\'\n" + 
+		"Null type safety (type annotations): The expression of type \'@NonNull A<T2>\' needs unchecked conversion to conform to \'@NonNull A<@Nullable T2>\'\n" + 
 		"----------\n" + 
 		"13. ERROR in nullable\\WildcardNullableTest.java (at line 81)\n" + 
 		"	g(new A<T2>());\n" + 
@@ -12177,7 +12198,7 @@
 		"15. ERROR in nullable\\WildcardNullableTest.java (at line 84)\n" + 
 		"	g(new A<@NonNull T2>());\n" + 
 		"	  ^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'@NonNull A<@Nullable T2>\' but this expression has type \'A<@NonNull T2>\'\n" + 
+		"Null type mismatch (type annotations): required \'@NonNull A<@Nullable T2>\' but this expression has type \'@NonNull A<@NonNull T2>\'\n" + 
 		"----------\n" + 
 		"16. ERROR in nullable\\WildcardNullableTest.java (at line 84)\n" + 
 		"	g(new A<@NonNull T2>());\n" + 
@@ -13378,6 +13399,8 @@
 	);
 }
 public void testBug484926locals() {
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.IGNORE);
 	runNegativeTestWithLibs(
 		new String[] {
 			"test/NNBDOnLocalOrField.java",
@@ -13410,12 +13433,12 @@
 			"	}\n" +
 			"}\n" 
 		}, 
-		getCompilerOptions(),
+		options,
 		"----------\n" + 
 		"1. ERROR in test\\NNBDOnLocalOrField.java (at line 16)\n" + 
 		"	AtomicReference<String> x2 = new AtomicReference<@NonNull String>(), x3=new AtomicReference<@Nullable String>();\n" + 
 		"	                                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'AtomicReference<@NonNull String>\' but this expression has type \'AtomicReference<@Nullable String>\'\n" + 
+		"Null type mismatch (type annotations): required \'AtomicReference<@NonNull String>\' but this expression has type \'@NonNull AtomicReference<@Nullable String>\'\n" + 
 		"----------\n" + 
 		"2. ERROR in test\\NNBDOnLocalOrField.java (at line 21)\n" + 
 		"	x1.set(null);\n" + 
@@ -13435,6 +13458,8 @@
 	);
 }
 public void testBug484926fields() {
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.IGNORE);
 	runNegativeTestWithLibs(
 		new String[] {
 			"test/NNBDOnLocalOrField.java",
@@ -13467,12 +13492,12 @@
 			"	}\n" +
 			"}\n" 
 		}, 
-		getCompilerOptions(),
+		options,
 		"----------\n" + 
 		"1. ERROR in test\\NNBDOnLocalOrField.java (at line 15)\n" + 
 		"	AtomicReference<String> x2 = new AtomicReference<@NonNull String>(), x3=new AtomicReference<@Nullable String>();\n" + 
 		"	                                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Null type mismatch (type annotations): required \'@NonNull AtomicReference<@NonNull String>\' but this expression has type \'AtomicReference<@Nullable String>\'\n" + 
+		"Null type mismatch (type annotations): required \'@NonNull AtomicReference<@NonNull String>\' but this expression has type \'@NonNull AtomicReference<@Nullable String>\'\n" + 
 		"----------\n" + 
 		"2. ERROR in test\\NNBDOnLocalOrField.java (at line 21)\n" + 
 		"	x1.set(null);\n" + 
@@ -17818,4 +17843,147 @@
 		"Potential null pointer access: The method get() may return null\n" + 
 		"----------\n");
 }
+public void testBug482242_simple() {
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.ERROR);
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import java.util.*;\n" + 
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"public class Test {\n" + 
+			"    static void dangerous(List<String> list) {\n" + 
+			"        list.add(null);\n" + 
+			"    }\n" + 
+			"    public static void main(String[] args) {\n" + 
+			"        List<@NonNull String> l = new ArrayList<>();\n" + 
+			"        dangerous(l);\n" + 
+			"        for (String string : l)\n" + 
+			"            System.out.println(string.toLowerCase());\n" + 
+			"    }\n" + 
+			"}\n"
+		},
+		options,
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 9)\n" + 
+		"	dangerous(l);\n" + 
+		"	          ^\n" + 
+		"Null type safety (type annotations): The expression of type \'List<@NonNull String>\' needs unchecked conversion to conform to \'List<String>\'\n" + 
+		"----------\n");
+}
+public void testBug482242_intermediate() {
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.ERROR);
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import java.util.*;\n" + 
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"    public static void main(String[] args) {\n" + 
+			"        ArrayList<@NonNull String> list = new ArrayList<>();\n" + 
+			"        collect(list, null);\n" + 
+			"        for (String s : list)\n" + 
+			"            System.out.println(s.toUpperCase());\n" + 
+			"    }\n" + 
+			"    static void collect(List<@NonNull String> list, String string) {\n" + 
+			"        list.add(string);     // (1)\n" + 
+			"        insert(list, string); // (2)\n" + 
+			"    }\n" + 
+			"    static void insert(List<? super String> l, String s) {\n" + 
+			"        l.add(s);\n" + 
+			"    }\n" + 
+			"}\n"
+		},
+		options,
+		"----------\n" + 
+		"1. WARNING in Test.java (at line 12)\n" + 
+		"	list.add(string);     // (1)\n" + 
+		"	         ^^^^^^\n" + 
+		"Null type safety (type annotations): The expression of type \'String\' needs unchecked conversion to conform to \'@NonNull String\'\n" + 
+		"----------\n" + 
+		"2. ERROR in Test.java (at line 13)\n" + 
+		"	insert(list, string); // (2)\n" + 
+		"	       ^^^^\n" + 
+		"Null type safety (type annotations): The expression of type \'List<@NonNull String>\' needs unchecked conversion to conform to \'List<? super String>\'\n" + 
+		"----------\n");
+}
+public void testBug482242_annotatedTypeVariable() {
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.ERROR);
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"\n" +
+			"interface List<T extends @NonNull Object> {\n" +
+			"	void add(T elem);" +
+			"}\n" + 
+			"public class Test {\n" + 
+			"    public static void test(List<@NonNull String> list) {\n" + 
+			"        collect(list, null);\n" + 
+			"    }\n" + 
+			"    static void collect(List<@NonNull String> list, String string) {\n" + 
+			"        insert(list, string);\n" + 
+			"    }\n" + 
+			"    static void insert(List<? super String> l, String s) {\n" + // type error at declaration site, no need to signal at the call site
+			"        l.add(s);\n" + 
+			"    }\n" + 
+			"}\n"
+		},
+		options,
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 12)\n" + 
+		"	static void insert(List<? super String> l, String s) {\n" + 
+		"	                        ^^^^^^^^^^^^^^\n" + 
+		"Null constraint mismatch: The type \'? super String\' is not a valid substitute for the type parameter \'T extends @NonNull Object\'\n" + 
+		"----------\n" + 
+		"2. WARNING in Test.java (at line 13)\n" + 
+		"	l.add(s);\n" + 
+		"	      ^\n" + 
+		"Null type safety (type annotations): The expression of type \'String\' needs unchecked conversion to conform to \'capture#of ? super String\'\n" + 
+		"----------\n");
+}
+public void testBug482242_boundedWildcard() {
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.ERROR);
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"\n" +
+			"interface List<T extends @NonNull Object> {\n" +
+			"	void add(T elem);" +
+			"}\n" + 
+			"public class Test {\n" + 
+			"    public static void test(List<@NonNull String> list) {\n" + 
+			"        collect(list, null);\n" + 
+			"    }\n" + 
+			"    static void collect(List<@NonNull String> list, String string) {\n" + 
+			"        insert(list, string);\n" + 
+			"    }\n" + 
+			"    static void insert(List<? super @Nullable String> l, String s) {\n" +
+			"        l.add(s);\n" + 
+			"    }\n" + 
+			"}\n"
+		},
+		options,
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 10)\n" + 
+		"	insert(list, string);\n" + 
+		"	       ^^^^\n" + 
+		"Null type mismatch (type annotations): required \'List<? super @Nullable String>\' but this expression has type \'List<@NonNull String>\'\n" + 
+		"----------\n" + 
+		"2. ERROR in Test.java (at line 12)\n" + 
+		"	static void insert(List<? super @Nullable String> l, String s) {\n" + 
+		"	                        ^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Null constraint mismatch: The type \'? super @Nullable String\' is not a valid substitute for the type parameter \'T extends @NonNull Object\'\n" + 
+		"----------\n" + 
+		"3. WARNING in Test.java (at line 13)\n" + 
+		"	l.add(s);\n" + 
+		"	      ^\n" + 
+		"Null type safety (type annotations): The expression of type \'String\' needs unchecked conversion to conform to \'capture#of ? super @Nullable String\'\n" + 
+		"----------\n");
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java
index b205d76..4970f51 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java
@@ -2359,7 +2359,7 @@
 		}
 	}
 
-		@SuppressWarnings("deprecation")
+	@SuppressWarnings("deprecation")
 	public void testBug508955() throws CoreException, IOException {
 		myCreateJavaProject("TestLibs");
 		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots",
@@ -2624,4 +2624,40 @@
 		CompilationUnit reconciled = cu.reconcile(getJSL9(), true, null, new NullProgressMonitor());
 		assertNoProblems(reconciled.getProblems());
 	}
+
+	@SuppressWarnings("deprecation")
+	public void testBug482242() throws CoreException, IOException {
+		try {
+			String projectName = "Bug482242";
+			setupJavaProject(projectName, true, true);
+			this .project.setOption(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED, JavaCore.WARNING);
+			addEeaToVariableEntry("JCL18_FULL", "/"+projectName+"/annots");
+			IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("test1", true, null);
+			ICompilationUnit unit = fragment.getCompilationUnit("Test.java").getWorkingCopy(new NullProgressMonitor());
+			CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
+			IProblem[] problems = reconciled.getProblems();
+			assertProblems(problems, 
+					new String[] {
+						"Pb(955) Null type safety (type annotations): The expression of type 'Collector<@NonNull String,capture#of ?,Set<@NonNull String>>' " +
+						"needs unchecked conversion to conform to 'Collector<? super String,Object,Set<@NonNull String>>'",
+					},
+					new int[] {11},
+					new int[] { ProblemSeverities.Warning });
+			
+			this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+			IMarker[] markers = this.project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
+			sortMarkers(markers);
+			assertMarkers("Markers after full build", 
+					"Null type safety (type annotations): The expression of type 'Collector<@NonNull String,capture#of ?,Set<@NonNull String>>' needs unchecked conversion to conform to 'Collector<? super String,Object,Set<@NonNull String>>'",
+					markers);
+			int[] severities = new int[] { IMarker.SEVERITY_WARNING };
+			for (int i = 0; i < markers.length; i++) {
+				IMarker marker = markers[i];
+				assertEquals("severity of "+marker.getAttribute(IMarker.MESSAGE),
+						severities[i], marker.getAttribute(IMarker.SEVERITY));
+			}
+		} finally {
+			deleteProject("Bug500024");
+		}
+	}
 }
diff --git a/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/.classpath b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/.classpath
new file mode 100644
index 0000000..3dfabed
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="var" path="JCL18_LIB">
+		<attributes>
+			<attribute name="annotationpath" value="annots"/>
+		</attributes>
+	</classpathentry> 
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/.project b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/.project
new file mode 100644
index 0000000..1cf4df7
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Bug482242</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/annots/java/util/stream/Stream.eea b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/annots/java/util/stream/Stream.eea
new file mode 100644
index 0000000..d311f09
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/annots/java/util/stream/Stream.eea
@@ -0,0 +1,4 @@
+class java/util/stream/Stream
+collect
+ <R:Ljava/lang/Object;A:Ljava/lang/Object;>(Ljava/util/stream/Collector<-TT;TA;TR;>;)TR;
+ <R:Ljava/lang/Object;A:Ljava/lang/Object;>(Ljava/util/stream/Collector<-TT;TA;TR;>;)T1R;
diff --git a/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/src/test1/Test.java b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/src/test1/Test.java
new file mode 100644
index 0000000..8135abb
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations18/Bug482242/src/test1/Test.java
@@ -0,0 +1,19 @@
+package test1;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.jdt.annotation.NonNull;
+
+public class Test {
+    static Set<@NonNull String> test1(Set<String> args) {
+        @NonNull Set<@NonNull String> mapped = args.stream().collect(Collectors.toSet());
+        return mapped;
+    }
+    public static void main(String[] args) {
+		Set<String> set = Collections.singleton(null);
+		for (@NonNull String s : test1(set))
+			System.out.println(s.toUpperCase());
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
index 3e53cae..250daf1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -517,12 +517,13 @@
  	}
 	if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
 		ImplicitNullAnnotationVerifier.ensureNullnessIsKnown(this.binding, scope);
-		if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
+		if (scope.environment().usesNullTypeAnnotations()) {
 			if (this.binding instanceof ParameterizedGenericMethodBinding && this.typeArguments != null) {
 				TypeVariableBinding[] typeVariables = this.binding.original().typeVariables();
 				for (int i = 0; i < this.typeArguments.length; i++)
 					this.typeArguments[i].checkNullConstraints(scope, (ParameterizedGenericMethodBinding) this.binding, typeVariables, i);
 			}
+			this.resolvedType = scope.environment().createAnnotatedType(this.resolvedType, new AnnotationBinding[] {scope.environment().getNonNullAnnotation()});
 		}
 	}
 	if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 &&
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
index bf66588..2be11ef 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2019 GK Software AG and others.
+ * Copyright (c) 2013, 2020 GK Software AG and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -101,6 +101,8 @@
 		LEGACY_WARNING,
 		/** Need unchecked conversion from unannotated to annotated. */
 		UNCHECKED,
+		/** Need unchecked conversion to pass type with annotated type arguments into unannotated code. */
+		UNCHECKED_TO_UNANNOTATED,
 		/** Definite nullity mismatch. */
 		MISMATCH;
 
@@ -127,10 +129,11 @@
 		this.nullStatus = nullStatus;
 	}
 
-	public boolean isAnyMismatch()      { return this.severity.isAnyMismatch(); }
-	public boolean isUnchecked()        { return this.severity == Severity.UNCHECKED; }
-	public boolean isDefiniteMismatch() { return this.severity == Severity.MISMATCH; }
-	public boolean wantToReport() 		{ return this.severity == Severity.LEGACY_WARNING; }
+	public boolean isAnyMismatch()      		{ return this.severity.isAnyMismatch(); }
+	public boolean isUnchecked()        		{ return this.severity == Severity.UNCHECKED || this.severity == Severity.UNCHECKED_TO_UNANNOTATED; }
+	public boolean isAnnotatedToUnannotated() 	{ return this.severity == Severity.UNCHECKED_TO_UNANNOTATED; }
+	public boolean isDefiniteMismatch() 		{ return this.severity == Severity.MISMATCH; }
+	public boolean wantToReport() 				{ return this.severity == Severity.LEGACY_WARNING; }
 
 	public boolean isPotentiallyNullMismatch() {
 		return !isDefiniteMismatch() && this.nullStatus != -1 && (this.nullStatus & FlowInfo.POTENTIALLY_NULL) != 0;
@@ -228,6 +231,7 @@
 		try {
 			Severity severity = Severity.OK;
 			TypeBinding superTypeHint = null;
+			TypeBinding originalRequiredType = requiredType;
 			NullAnnotationMatching okStatus = NullAnnotationMatching.NULL_ANNOTATIONS_OK;
 			if (areSameTypes(requiredType, providedType, providedSubstitute)) {
 				if ((requiredType.tagBits & TagBits.AnnotationNonNull) != 0)
@@ -288,7 +292,7 @@
 							} else {
 								if (i > 0)
 									currentNullStatus = -1; // don't use beyond the outermost dimension
-								Severity dimSeverity = computeNullProblemSeverity(requiredBits, providedBits, currentNullStatus, i == 0 ? mode : mode.toDetail(), false);
+								Severity dimSeverity = computeNullProblemSeverity(requiredBits, providedBits, currentNullStatus, i == 0 ? mode : mode.toDetail(), null);
 								if (i > 0 && dimSeverity == Severity.UNCHECKED
 										&& providedExpression instanceof ArrayAllocationExpression
 										&& providedBits == 0 && requiredBits != 0)
@@ -322,11 +326,14 @@
 					// at toplevel (having a nullStatus) nullable matches all
 				} else {
 					long providedBits = providedNullTagBits(providedType);
-					Severity s = computeNullProblemSeverity(requiredBits, providedBits, nullStatus, mode, requiredType.isTypeVariable());
+					Severity s = computeNullProblemSeverity(requiredBits, providedBits, nullStatus, mode, originalRequiredType);
 					if (s.isAnyMismatch() && requiredType.isWildcard() && requiredBits != 0) {
 						if (((WildcardBinding) requiredType).determineNullBitsFromDeclaration(null, null) == 0) {
-							// wildcard has its nullBits from the type variable: avoid redundant warning.
-							s = Severity.OK;
+							TypeVariableBinding typeVariable = ((WildcardBinding) requiredType).typeVariable();
+							if ((typeVariable.tagBits & TagBits.AnnotationNullMASK) != 0) {
+								// wildcard has its nullBits from the type variable
+								s = Severity.OK; // is already reported as illegal substitution
+							}
 						}
 					}
 					severity = severity.max(s);
@@ -433,6 +440,19 @@
 			return validNullTagBits(tagBits);
 
 		if (type.isWildcard()) {
+			WildcardBinding wildcardBinding = (WildcardBinding) type;
+			TypeBinding bound = wildcardBinding.bound;
+			tagBits = bound != null ? bound.tagBits & TagBits.AnnotationNullMASK : 0;
+			switch (wildcardBinding.boundKind) {
+				case Wildcard.SUPER:
+					if (tagBits == TagBits.AnnotationNullable)
+						return TagBits.AnnotationNullable; // type cannot require @NonNull
+					break;
+				case Wildcard.EXTENDS:
+					if (tagBits == TagBits.AnnotationNonNull)
+						return tagBits;
+					break;
+			}
 			return TagBits.AnnotationNullMASK;
 		} 
 		
@@ -544,29 +564,44 @@
 	 * @param providedBits null tagBits of the provided type
 	 * @param nullStatus -1 means: don't use, other values see constants in FlowInfo
 	 * @param mode check mode (see {@link CheckMode})
-	 * @param requiredIsTypeVariable is the required type a type variable (possibly: "free type variable")?
+	 * @param requiredType the required type, used, e.g., to check if it is a type variable (possibly: "free type variable")?
 	 * @return see {@link #severity} for interpretation of values
 	 */
-	private static Severity computeNullProblemSeverity(long requiredBits, long providedBits, int nullStatus, CheckMode mode, boolean requiredIsTypeVariable) {
+	private static Severity computeNullProblemSeverity(long requiredBits, long providedBits, int nullStatus, CheckMode mode, TypeBinding requiredType) {
 		if (requiredBits == providedBits)
 			return Severity.OK;
 		if (requiredBits == 0) { 
 			switch (mode) {
+				case EXACT:
+					if (providedBits == TagBits.AnnotationNonNull && !(requiredType instanceof TypeVariableBinding))
+						return Severity.UNCHECKED_TO_UNANNOTATED;
+					return Severity.OK;
 				case COMPATIBLE:
 				case BOUND_CHECK:
 				case BOUND_SUPER_CHECK:
-				case EXACT:
 					return Severity.OK;
 				case OVERRIDE_RETURN:
 					if (providedBits == TagBits.AnnotationNonNull)
 						return Severity.OK; // covariant redefinition to nonnull is good
-					if (!requiredIsTypeVariable)
+					if (!(requiredType instanceof TypeVariableBinding))
 						return Severity.OK; // refining an unconstrained non-TVB return to nullable is also legal
 					return Severity.UNCHECKED;
 				case OVERRIDE:
 					return Severity.UNCHECKED; // warn about dropped annotation
 			}
 		} else if (requiredBits == TagBits.AnnotationNullMASK) {
+			if (mode == CheckMode.EXACT && providedBits == TagBits.AnnotationNonNull) {
+				if (requiredType instanceof WildcardBinding) {
+					WildcardBinding wildcard = (WildcardBinding) requiredType;
+					// passing '@NonNull X' into '? super Y' risks pollution with null
+					if (wildcard.boundKind == Wildcard.SUPER && providedBits == TagBits.AnnotationNonNull) {
+						TypeBinding bound = wildcard.bound;
+						if (bound != null && (bound.tagBits & TagBits.AnnotationNullMASK) != 0)
+							return Severity.OK; // when the wildcard is annotated via its bound, there is not annotated->unannotated conversion
+						return Severity.UNCHECKED_TO_UNANNOTATED;
+					}
+				}
+			}
 			return Severity.OK; // OK since LHS accepts either
 		} else if (requiredBits == TagBits.AnnotationNonNull) {
 			switch (mode) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index 2dd1101..90d434f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -49,6 +49,7 @@
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
@@ -305,12 +306,15 @@
 			final CompilerOptions compilerOptions = scope.compilerOptions();
 			if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
 				ImplicitNullAnnotationVerifier.ensureNullnessIsKnown(this.binding, scope);
-				if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
+				if (scope.environment().usesNullTypeAnnotations()) {
 					if (this.binding instanceof ParameterizedGenericMethodBinding && this.typeArguments != null) {
 						TypeVariableBinding[] typeVariables = this.binding.original().typeVariables();
 						for (int i = 0; i < this.typeArguments.length; i++)
 							this.typeArguments[i].checkNullConstraints(scope, (ParameterizedGenericMethodBinding) this.binding, typeVariables, i);
 					}
+					if (this.resolvedType.isValidBinding()) {
+						this.resolvedType = scope.environment().createAnnotatedType(this.resolvedType, new AnnotationBinding[] {scope.environment().getNonNullAnnotation()});
+					}
 				}
 			}
 			if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 &&
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index d3954df..90008c6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -194,6 +194,7 @@
 	public static final String OPTION_ReportNonnullParameterAnnotationDropped = "org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped";  //$NON-NLS-1$
 	public static final String OPTION_PessimisticNullAnalysisForFreeTypeVariables = "org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables";  //$NON-NLS-1$
 	public static final String OPTION_ReportNonNullTypeVariableFromLegacyInvocation = "org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation"; //$NON-NLS-1$
+	public static final String OPTION_ReportAnnotatedTypeArgumentToUnannotated = "org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated"; //$NON-NLS-1$
 	
 	public static final String OPTION_ReportUnlikelyCollectionMethodArgumentType = "org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType"; //$NON-NLS-1$
 	public static final String OPTION_ReportUnlikelyCollectionMethodArgumentTypeStrict = "org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict"; //$NON-NLS-1$
@@ -347,6 +348,7 @@
 	public static final int UnstableAutoModuleName = IrritantSet.GROUP2 | ASTNode.Bit26;
 	public static final int PreviewFeatureUsed = IrritantSet.GROUP2 | ASTNode.Bit27;
 	public static final int SuppressWarningsNotAnalysed = IrritantSet.GROUP2 | ASTNode.Bit28;
+	public static final int AnnotatedTypeArgumentToUnannotated = IrritantSet.GROUP2 | ASTNode.Bit29;
 
 
 	// Severity level for handlers
@@ -771,6 +773,8 @@
 				return OPTION_PessimisticNullAnalysisForFreeTypeVariables;
 			case NonNullTypeVariableFromLegacyInvocation:
 				return OPTION_ReportNonNullTypeVariableFromLegacyInvocation;
+			case AnnotatedTypeArgumentToUnannotated:
+				return OPTION_ReportAnnotatedTypeArgumentToUnannotated;
 			case UnlikelyCollectionMethodArgumentType:
 				return OPTION_ReportUnlikelyCollectionMethodArgumentType;
 			case UnlikelyEqualsArgumentType:
@@ -1020,6 +1024,7 @@
 			OPTION_ReportUnusedTypeParameter,
 			OPTION_InheritNullAnnotations,
 			OPTION_ReportNonnullParameterAnnotationDropped,
+			OPTION_ReportAnnotatedTypeArgumentToUnannotated,
 			OPTION_ReportUnlikelyCollectionMethodArgumentType,
 			OPTION_ReportUnlikelyEqualsArgumentType,
 			OPTION_ReportAPILeak,
@@ -1101,6 +1106,7 @@
 			case NonnullParameterAnnotationDropped:
 			case PessimisticNullAnalysisForFreeTypeVariables:
 			case NonNullTypeVariableFromLegacyInvocation:
+			case AnnotatedTypeArgumentToUnannotated:
 				return "null"; //$NON-NLS-1$
 			case FallthroughCase :
 				return "fallthrough"; //$NON-NLS-1$
@@ -1372,6 +1378,7 @@
 		optionsMap.put(OPTION_ReportUninternedIdentityComparison, this.complainOnUninternedIdentityComparison ? ENABLED : DISABLED);
 		optionsMap.put(OPTION_PessimisticNullAnalysisForFreeTypeVariables, getSeverityString(PessimisticNullAnalysisForFreeTypeVariables));
 		optionsMap.put(OPTION_ReportNonNullTypeVariableFromLegacyInvocation, getSeverityString(NonNullTypeVariableFromLegacyInvocation));
+		optionsMap.put(OPTION_ReportAnnotatedTypeArgumentToUnannotated, getSeverityString(AnnotatedTypeArgumentToUnannotated));
 		optionsMap.put(OPTION_ReportUnlikelyCollectionMethodArgumentType, getSeverityString(UnlikelyCollectionMethodArgumentType));
 		optionsMap.put(OPTION_ReportUnlikelyCollectionMethodArgumentTypeStrict, this.reportUnlikelyCollectionMethodArgumentTypeStrict ? ENABLED : DISABLED);
 		optionsMap.put(OPTION_ReportUnlikelyEqualsArgumentType, getSeverityString(UnlikelyEqualsArgumentType));
@@ -1949,6 +1956,7 @@
 				this.inheritNullAnnotations = ENABLED.equals(optionValue);
 			}
 			if ((optionValue = optionsMap.get(OPTION_ReportNonnullParameterAnnotationDropped)) != null) updateSeverity(NonnullParameterAnnotationDropped, optionValue);
+			if ((optionValue = optionsMap.get(OPTION_ReportAnnotatedTypeArgumentToUnannotated)) != null) updateSeverity(AnnotatedTypeArgumentToUnannotated, optionValue);
 			if ((optionValue = optionsMap.get(OPTION_PessimisticNullAnalysisForFreeTypeVariables)) != null) updateSeverity(PessimisticNullAnalysisForFreeTypeVariables, optionValue);
 			if (getSeverity(PessimisticNullAnalysisForFreeTypeVariables) == ProblemSeverities.Ignore) {
 				this.pessimisticNullAnalysisForFreeTypeVariablesEnabled = false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
index 72ae67a..69c40b7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
@@ -86,7 +86,8 @@
 		// group-2 infos enabled by default
 		.set(
 			CompilerOptions.UnlikelyEqualsArgumentType
-			| CompilerOptions.SuppressWarningsNotAnalysed);
+			| CompilerOptions.SuppressWarningsNotAnalysed
+			| CompilerOptions.AnnotatedTypeArgumentToUnannotated);
 		
 		COMPILER_DEFAULT_WARNINGS
 			// group-0 warnings enabled by default
@@ -158,7 +159,8 @@
 			.set(CompilerOptions.NonnullParameterAnnotationDropped)
 			.set(CompilerOptions.MissingNonNullByDefaultAnnotation)
 			.set(CompilerOptions.PessimisticNullAnalysisForFreeTypeVariables)
-			.set(CompilerOptions.NonNullTypeVariableFromLegacyInvocation);
+			.set(CompilerOptions.NonNullTypeVariableFromLegacyInvocation)
+			.set(CompilerOptions.AnnotatedTypeArgumentToUnannotated);
 
 		RESTRICTION.set(CompilerOptions.DiscouragedReference);
 		STATIC_ACCESS.set(CompilerOptions.NonStaticAccessToStatic);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 6932f0a..3021f41 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -10592,6 +10592,12 @@
 public void nullityMismatchingTypeAnnotation(Expression expression, TypeBinding providedType, TypeBinding requiredType, NullAnnotationMatching status) 
 {
 	if (providedType == requiredType) return; //$IDENTITY-COMPARISON$
+	int severity = -1;
+	if (status.isAnnotatedToUnannotated()) {
+		severity = this.options.getSeverity(CompilerOptions.AnnotatedTypeArgumentToUnannotated);
+		if (severity == ProblemSeverities.Ignore)
+			return;
+	}
 	// try to improve nonnull vs. null:
 	if (providedType.id == TypeIds.T_null || status.nullStatus == FlowInfo.NULL) {
 		nullityMismatchIsNull(expression, requiredType);
@@ -10655,7 +10661,9 @@
 		arguments 		= new String[] { requiredName, providedName };
 		shortArguments 	= new String[] { requiredNameShort, providedNameShort };
 	}
-	this.handle(problemId, arguments, shortArguments, expression.sourceStart, expression.sourceEnd);
+	if (severity == -1)
+		severity = computeSeverity(problemId);
+	this.handle(problemId, arguments, shortArguments, severity, expression.sourceStart, expression.sourceEnd);
 }
 
 public void nullityMismatchTypeArgument(TypeBinding typeVariable, TypeBinding typeArgument, ASTNode location) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index 3b56560..dc32bf4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -2070,7 +2070,22 @@
 	 * @category CompilerOptionID
 	 */
 	public static final String COMPILER_PB_NONNULL_TYPEVAR_FROM_LEGACY_INVOCATION = JavaCore.PLUGIN_ID+".compiler.problem.nonnullTypeVariableFromLegacyInvocation"; //$NON-NLS-1$
-
+	/**
+	 * Compiler option ID: Reporting Unsafe Conversion To Unannotated Type Argument.
+	 * <p>When enabled, the compiler will issue an error, warning or info when a value of a parameterized type
+	 * with annotated type arguments is assigned to a variable / bound to a method argument, where the corresponding
+	 * type argument is unannotated.</p>
+	 * <p>This situation is problematic because it will enable using the less-annotated type to manipulate the given
+	 * objects in ways that may violate contracts of the more-annotated type.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "info", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"info"</code></dd>
+	 * </dl>
+	 * @since 3.21
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED = JavaCore.PLUGIN_ID+".compiler.problem.annotatedTypeArgumentToUnannotated"; //$NON-NLS-1$
 	/**
 	 * Compiler option ID: Setting Source Compatibility Mode.
 	 * <p>Specify whether which source level compatibility is used. From 1.4 on, <code>'assert'</code> is a keyword