Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
Summary: [1.8][null] Bogus warning for type argument annotated with @NonNull
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.4   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 4.5 M2   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 441338 (view as bug list)
Depends on:
Blocks:
 
Reported: 2014-08-13 09:44 EDT by Clovis Seragiotto CLA
Modified: 2014-09-17 06:00 EDT (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Clovis Seragiotto CLA 2014-08-13 09:44:47 EDT
In the program below, the method requireNonNull is invoked with 

@Nullable Iterable<@NonNull String> 

as argument, and therefore the returned value is 

@NonNull Iterable<@NonNull String>. 

Assigning the returned value to the field iterable is therefore safe.

With Annotation-based null analysis enabled and "Unchecked conversion from non-annotated type to @NonNull type" set to warning, the null analysis issues a bogus warning: "The expression of type '@NonNull Iterable<String>' needs unchecked conversion to conform to '@NonNull Iterable<@NonNull String>'" at the line marked with (*)


package foo.bar;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;

@NonNullByDefault({})
public abstract class Foo {
    
    abstract <T> @NonNull T requireNonNull(@Nullable T obj);
    
    @NonNull Iterable<@NonNull String> iterable;
    
    Foo(@Nullable Iterable<@NonNull String> iterable) {
        this.iterable = requireNonNull(iterable); // (*)
    }
}
Comment 1 Stephan Herrmann CLA 2014-08-14 05:54:29 EDT
Thanks for the report, I'll take a look.
Comment 2 Stephan Herrmann CLA 2014-08-14 06:11:17 EDT
It's what I thought it is:

When creating "the @NonNull variant of T" 
using T=@Nullable Iterable<@NonNull String>
we not only drop the outer @Nullable (OK)
but also the inner @NonNull (NOK).

I'm currently investigating whether all seven sites calling type.unannotated(true) actually require removal only of the toplevel annotation or whether we'll need another parameter in that method...

Depending on the result the fix can be quite simple.
Comment 3 Stephan Herrmann CLA 2014-08-14 11:53:42 EDT
Released for 4.5 M2 via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=8913fe5c78a14de5e97c4d6b801f5ed8424bf8a8

The patch looks bigger than might be expected, but much of it is just due to the divorce of two diverging methods:

- TypeBinding.unannotated()
  with this change basically back to the simple version before bug 438458.

- TypeBinding.withoutToplevelNullAnnotations()
  new method for shallow manipulation of null type annotations


See also bug 441797 for an issue discovered during work on this bug.
Comment 4 Stephan Herrmann CLA 2014-08-14 12:42:52 EDT
*** Bug 441338 has been marked as a duplicate of this bug. ***
Comment 5 shankha banerjee CLA 2014-09-16 11:50:39 EDT
Verified for Mars 4.5M2 using I20140915-2000 build.