Bug 337093

Summary: [compiler][generics] Javac-warning on vararg missing in Eclipse
Product: [Eclipse Project] JDT Reporter: Holger Klene <h.klene>
Component: CoreAssignee: Srikanth Sankaran <srikanth_sankaran>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: amj87.iitr, jarthana, Olivier_Thomann
Version: 3.7Flags: srikanth_sankaran: review? (amj87.iitr)
Target Milestone: 3.7 M6   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Patch under test none

Description Holger Klene CLA 2011-02-14 04:16:25 EST
Build Identifier: 20100218-1602

Eclipse has only 1 Warning on the given Code, while javac results to 2 Warnings:

D:\holger\wba-Performance\JavaPlayGround\src>\holger\jdk1.6.0_21\bin\javac Gener
icsWarning.java -Xlint:unchecked
GenericsWarning.java:42: warning: [unchecked] unchecked generic array creation o
f type java.util.Collection<? extends java.lang.Number>[] for varargs parameter
        for (Iterator<Number> iter = new IteratorChain<Number>(a, b, c); iter.ha
sNext(); ) {
                                     ^
GenericsWarning.java:48: warning: [unchecked] unchecked generic array creation o
f type java.util.Collection<? extends java.lang.Number>[] for varargs parameter
        new IteratorChain<Number>(a, b);
        ^
2 warnings

Reproducible: Always

Steps to Reproduce:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;


public class GenericsWarning {

    public static class IteratorChain<T> implements Iterator<T> {

        /**
         * Minimum of two Collections, eventually more
         */
        public IteratorChain(Collection<? extends T> a, Collection<? extends T> b,
            Collection<? extends T> ... collections) {
            // implementation skipped for simplicity
        }

        @Override
        public boolean hasNext() {
            return false;
        }

        @Override
        public T next() {
            return null;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

    }

    public static void main(String[] args) {
        List<Integer> a = new ArrayList<Integer>();
        List<Long> b = new ArrayList<Long>();
        List<Double> c = new ArrayList<Double>();

        // Eclipse and javac both issue a warning for creating an Array of a generic type
        for (Iterator<Number> iter = new IteratorChain<Number>(a, b, c); iter.hasNext(); ) {
            Number n = iter.next();
            System.out.println(n.intValue());
        }

        // Eclipse does not complain about this, while javac does!
        new IteratorChain<Number>(a, b);
    }

}
Comment 1 Olivier Thomann CLA 2011-02-14 10:29:24 EST
We don't blame the second one, because this is not really using the varargs argument of the constructor.
This might be debatable.
Srikanth, your call. I don't think this is actually a problem.
Comment 2 Holger Klene CLA 2011-02-14 11:07:17 EST
Our problem was, that the automatic build (using javac) was set to fail, in case of any warnings. As Eclipse didn't show warnings, we were quite surprised to find the build failed next morning.

The first fix was to add a @SuppressWarnings("unchecked") ... but now Eclipse was complaining about the superfluous annotation :-(

Actually the varargs parameter won't be null ... therefore it really creates an array of length 0.

I've posted this report, as I rate the compatibility with the javac compiler higher. But as you say: It can be seen differently.
Comment 3 Srikanth Sankaran CLA 2011-02-15 03:43:31 EST
(In reply to comment #2)

> Actually the varargs parameter won't be null ... therefore it really creates an
> array of length 0.

Yes, Also see that in the following program we do emit a warning - so to be
consistent I'll see what it would take to fix this.

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class GenericsWarning {
    public static class IteratorChain<T> implements Iterator<T> {
        public IteratorChain(Collection<? extends T> ... collections) {}

        public boolean hasNext() { return false; }

        public T next() { return null; }

        public void remove() { throw new UnsupportedOperationException(); }

        public static void main(String[] args) {
	        List<Integer> a = new ArrayList<Integer>();
	        List<Long> b = new ArrayList<Long>();
	        List<Double> c = new ArrayList<Double>();
	
	        for (Iterator<Number> iter = new IteratorChain<Number>(); iter.hasNext(); ) {
	            Number n = iter.next();
	            System.out.println(n.intValue());
	        }
        }
    }
}
Comment 4 Srikanth Sankaran CLA 2011-02-15 04:41:32 EST
Created attachment 188982 [details]
Patch under test

This patch makes eclipse behavior self consistent as well
as consistent with javac.
Comment 5 Srikanth Sankaran CLA 2011-02-15 06:10:18 EST
Passes all tests, Ayush, please review, TIA
Comment 6 Srikanth Sankaran CLA 2011-02-16 03:25:46 EST
Released in HEAD for 3.7 M6
Comment 7 Jay Arthanareeswaran CLA 2011-03-07 06:32:29 EST
Verified for 3.7M6 using build I20110301-1537.