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

Bug 370930

Summary: NonNull annotation not considered for enhanced for loops
Product: [Eclipse Project] JDT Reporter: Sebastian Zarnekow <sebastian.zarnekow>
Component: CoreAssignee: Stephan Herrmann <stephan.herrmann>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: srikanth_sankaran
Version: 3.8   
Target Milestone: 3.8 M6   
Hardware: PC   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard:

Description Sebastian Zarnekow CLA 2012-02-08 05:37:23 EST
import java.util.Collections;
import java.util.List;

import org.eclipse.jdt.annotation.NonNull;


public class C {

	void loop() {
		List<String> list = Collections.emptyList();
		for(@NonNull String s: list) {
			expectNonNull(s);
		}
	}
	
	void expectNonNull(@NonNull String s) {}
	
}

gives 

Potential type mismatch: required '@NonNull String' but nullness of the provided value is unknown

on

expectNonNull(s);
Comment 1 Srikanth Sankaran CLA 2012-02-08 07:49:33 EST
It would appear the right behavior is for this warning to not show
up. But there should be a warning in the preceding line since there
is no syntax to annotate a collection as containing only @NonNull
elements and so as the cursor advances there is no non null guarantee
that can be enforced by the null annotation processor.
Comment 2 Srikanth Sankaran CLA 2012-02-08 07:51:05 EST
The other construct that allows a local to be declared works alright:

//--------------
import org.eclipse.jdt.annotation.NonNull;


public class X implements AutoCloseable {

	@NonNull X[] x = null;
    public static void main(String[] args) {
		try (@NonNull X x = boo()) {
			goo(x);
		}
	}

    static X boo() {
    	return null;
    }
    static void goo(@NonNull X x) {
    	
    }

	@Override
	public void close()  {
	}
}
Comment 3 Stephan Herrmann CLA 2012-02-08 10:14:18 EST
(In reply to comment #1)
> It would appear the right behavior is for this warning to not show
> up. But there should be a warning in the preceding line since there
> is no syntax to annotate a collection as containing only @NonNull
> elements and so as the cursor advances there is no non null guarantee
> that can be enforced by the null annotation processor.

I agree. 
Should be easy to fix for M6
Comment 4 Stephan Herrmann CLA 2012-02-14 16:50:25 EST
Fixed for 3.8 M6 via commit d137239e9d64b43b4573cdfef965a2c47040a54e

Normally, the annotation on the local variable declaration is analyzed as part of the initialization/assignment.
The bug happened because in this particular case we have no AST representing an assignment to the local variable.

As a side effect of fixing the bug, we now see another warning against "for(@NonNull String s: list)", where list is a 'List<String>':
   Potential type mismatch: required '@NonNull String' but nullness of the provided value is unknown.
Until we have JSR 308 we cannot say 'List<@NonNull String>' so the elements have the legacy type String, which is not safely assignable to '@NonNull String'.
Just mentioning so nobody is surprised about the new outcome.
Comment 5 Srikanth Sankaran CLA 2012-03-12 04:39:29 EDT
Verified for 3.8 M6 using Build id: I20120306-0800