Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 513349

Summary: [null][quick fix] Quick Fix does not succeed to make an annotated parameterized type conform to an unconstrained type in the super declaration
Product: [Eclipse Project] JDT Reporter: Matthew DOnofrio <artist>
Component: UIAssignee: JDT-UI-Inbox <jdt-ui-inbox>
Status: CLOSED WONTFIX QA Contact: Stephan Herrmann <stephan.herrmann>
Severity: normal    
Priority: P3 CC: stephan.herrmann
Version: 4.7   
Target Milestone: ---   
Hardware: PC   
OS: Windows NT   
Whiteboard: stalebug

Description Matthew DOnofrio CLA 2017-03-08 22:23:07 EST
public class A {
   public void someMethod(Set<String> a) {
   }
}

@NonNullByDefault
public class B extends A {
   @Override
   // Illegal redefinition of parameter a, inherited method from A does not
   // constrain this parameter
   public void someMethod(
      Set<String> a)
   {
   }
}

Quick Fix provides a solution but there is still an error:

@NonNullByDefault
public class B extends A {
   @Override
   // Illegal redefinition of parameter a, inherited method from A declares
   // this parameter as 'Set<String>' (mismatching null constraints)
   public void someMethod(
      @Nullable Set<String> a)
   {
   }
}

I BELIEVE the correct solution is '@Nullable Set<@Nullable String>' but this still reports an error.
Comment 1 Stephan Herrmann CLA 2017-03-09 06:13:48 EST
The correct solution is:

   @NonNullByDefault({})
   public void someMethod(
      @Nullable Set<String> a)
   {
   }

with or without the @Nullable annotation, as you prefer.

Why? Neither Set<@Nullable String> nor Set<@NonNull String> is two-way-compatible to the unconstrained type Set<String>: we don't know if adding null is OK, and we don't know if we can get a null element when, e.g., iterating over the set.

Since there is no annotation to directly say "no annotation here", we have to disable @NonNullByDefault for this location.

We may consider updating the quick fix accordingly, but it's probably too late for 4.7.
Comment 2 Matthew DOnofrio CLA 2017-03-09 12:42:52 EST
I thought that unconstrained was the same as @Nullable as a null would be possible under an annotationless condition; therefore '@Nullable Set<@Nullable String>' would be expected?
Comment 3 Stephan Herrmann CLA 2017-03-09 13:09:28 EST
(In reply to Matthew DOnofrio from comment #2)
> I thought that unconstrained was the same as @Nullable as a null would be
> possible under an annotationless condition; therefore '@Nullable
> Set<@Nullable String>' would be expected?

Unfortunately not. In unannotated code, "String" implies a little bit of "@Nullable String" (it is possible to assign null) and a little bit of "@NonNull String" (it is allowed to dereference without null check). That's why "legacy" Java code cannot be null-safe.

When combining annotated and unannotated code, at the boundary we have to assume the worst in order to avoid letting the risk of the "legacy" code spill into the new checked code. You can assign  a String to a "@Nullable String", but not a "Set<String>" to a "Set<@Nullable String>". There may be clients of the set that happily extract values and assume non-null. Those would be broken by a set that explicitly allows insertion of null.
Comment 4 Eclipse Genie CLA 2020-02-04 17:03:03 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.
Comment 5 Stephan Herrmann CLA 2020-02-04 17:20:22 EST
If s.o. intends to implement a quickfix that adds @NonNullByDefault({}) where necessary, please feel free to reopen.