Bug 489492: document new null-related compiler options
- "unsafe interpretation" from bug 461268
diff --git a/bundles/org.eclipse.jdt.doc.user/reference/preferences/java/compiler/ref-preferences-errors-warnings.htm b/bundles/org.eclipse.jdt.doc.user/reference/preferences/java/compiler/ref-preferences-errors-warnings.htm
index ba444c6..d3f79f4 100644
--- a/bundles/org.eclipse.jdt.doc.user/reference/preferences/java/compiler/ref-preferences-errors-warnings.htm
+++ b/bundles/org.eclipse.jdt.doc.user/reference/preferences/java/compiler/ref-preferences-errors-warnings.htm
@@ -1002,6 +1002,25 @@
<p>Warning</p>
</td>
</tr>
+ <tr id="unsafe_interpretation_generic_legacy">
+ <td valign="top" style="padding-left: 2em;">
+ <p>Unsafe '@Nonnull' interpretation of free type variable from library</p>
+ </td>
+ <td valign="top">
+ <p>When enabled, the compiler will issue an error or a warning against a method call if all of the following hold:</p>
+ <ul>
+ <li>The method's declared return type is a type variable without any null annotation.</li>
+ <li>For the given invocation this type variable is substituted with a nonnull type.</li>
+ <li>The type declaring the method is provided by a third-party library.</li>
+ <li>No null annotations exist for this library type, neither in its class file nor using external annotations.</li>
+ </ul>
+ <p>This particular situation leverages the option to consistently substitute all occurrences of a type variable with a nonnull type,
+ but it bears the risk that the library type may not be aware of null annotations thus lacking a necessary @Nullable annotation
+ for a particular occurrence of a type variable.</p>
+ </td>
+ <td valign="top">
+ <p>Warning</p>
+ </td>
<tr>
<td valign="top" style="padding-left: 2em;">
<p>Redundant null annotation</p>
diff --git a/bundles/org.eclipse.jdt.doc.user/tasks/task-using_null_type_annotations.htm b/bundles/org.eclipse.jdt.doc.user/tasks/task-using_null_type_annotations.htm
index 43c1f1a..0cd3753 100644
--- a/bundles/org.eclipse.jdt.doc.user/tasks/task-using_null_type_annotations.htm
+++ b/bundles/org.eclipse.jdt.doc.user/tasks/task-using_null_type_annotations.htm
@@ -240,6 +240,53 @@
return result;
}
</pre>
+<h3 id="substitution">Substitution</h3>
+<p>
+The intention behind combining null type annotations with generics is to propagate a constraint defined for a type argument
+into all occurrences of the corresponding type variable. For example, if you declare a variable of type <code>List<@NonNull String></code>
+and invoke any method from <code>List<T></code> on this variable, all method signatures will see type <code>T</code> substituted by <code>@NonNull String</code>.
+This is how inserting a <code>null</code> value into this list is made impossible, and allows to safely regard elements extracted from this list as nonnull.
+The previous section gave examples of exactly this idea.
+</p>
+<p>
+Unfortunately, this idea introduces a new risk when applied to generic library classes that are <em>not designed with null annotations in mind.</em>
+A prominent example is method <code>java.util.Map.get(K)</code>, which declares to return <code>V</code>.
+In this particular case, the javadoc of said method explicitly states that <code>null</code> is a possible return value,
+which is in conflict with substituting <code>V</code> by any nonnull type.
+So, if this specific method <code>get()</code> is invoked on a variable of type <code>Map<Y,@NonNull X></code>,
+it is <em>unsafe</em> to assume that the return value is nonnull.
+This dilemma is a combination of two factors:
+</p>
+<ol>
+<li>The library lacks null annotations (it should be considered as "legacy" in terms of null annotations)</li>
+<li>The compiler cannot know whether an unannotated type variable is by intention (as to support arbitrary substitution) or an unsafe omission (legacy).
+</ol>
+<p>
+To alert users about this risk, a specific warning is raised by the compiler:
+</p>
+<blockquote>
+Unsafe interpretation of method return type as '@NonNull X' based on the receiver type 'Map<Y,@NonNull X>'. Type 'Map' doesn't seem to be designed with null type annotations in mind
+</blockquote>
+<p>The severity of this problem is controlled by a dedicated <a href="../reference/preferences/java/compiler/ref-preferences-errors-warnings.htm#unsafe_interpretation_generic_legacy">preference option</a>.
+<p>In response to this warning, the resolution of the dilemma is to add null annotations to the generic class in question.
+For the likely case that the current user is not the owner of the legacy library,
+<a href="task-using_external_null_annotations.htm">external null annotations</a> should be used.
+Then there are two options:</p>
+<ol>
+<li>For the given example, method <code>get(K)</code> should be declared to return <code>@Nullable V</code>.
+ </li>
+<li>For the opposite case as exemplified by <code>List.get()</code>, the return type should be left unannotated.
+ In order to signal to the compiler that types are left <em>unannotated by intention</em>,
+ a stub external annotation file (.eea) should be created without inserting actual external annotations.
+ This will tell the compiler that this class is no longer to be considered as legacy,
+ and hence all signatures of this class should be interpreted verbatim according to the rules given above
+ (care must be taken that this is safe for all method in that class).
+ </li>
+</ol>
+<p>If an external annotation file is found, the specific warning about unsafe interpretation is not issued.
+Finally, if a project is not yet configured for using external annotations for the given library,
+the problem is softened to "info" severity.
+</p>
<h2 id="inference">Inference</h2>
<p>
@@ -492,6 +539,9 @@
<dt><font color="SaddleBrown">The field 'f' may not have been initialized, whereas its type 'T' is a free type variable that may represent a '@NonNull' type</font></dt>
<dt><font color="SaddleBrown">Potential null pointer access: this expression has type 'T', a free type variable that may represent a '@Nullable' type</font></dt>
<dd>These problems are specifically detected by <a href="#pessimistic_analysis">pessimistic analysis for free type variables</a>.</dd>
+<dt><font color="SaddleBrown">Unsafe interpretation of method return type as '@NonNull X' based on the receiver type 'Map<Y,@NonNull X>'. Type 'Map' doesn't seem to be designed with null type annotations in mind</font></dt>
+<dt><font color="SaddleBrown">Unsafe interpretation of method return type as '@NonNull X' based on substitution 'V=@NonNull X'. Declaring type 'Map<K,V>' doesn't seem to be designed with null type annotations in mind</font></dt>
+<dd>This signals a particular dilemma regarding <a href="#substitution">substitution of type variables from a legacy library</a>.
</dl>