On 02/17/2016 07:25 PM, Palo Marton wrote:
Another option is dissalow using T in static field declaration, but allow use of T.erased, like this:

class Collection<any T> {
   private __SS Collection<T.erased> emptyCollection = …

   private __SS Collection<T> emptyCollection() {
return (Collection<T>)emptyCollection; // warning
   }
}

On Wed, Feb 17, 2016 at 6:48 PM, Brian Goetz <[email protected] <mailto:[email protected]>> wrote:

    Nice catch.  Yes, this would cause heap pollution.  As would the
    following Java 5 code:

        private Collection<?> collection = new ArrayList<?>();
        public <T> Collection<T> c() { return (Collection<T>)
    collection; }

    The trouble is, the unchecked warning is in the library
    implementation, not the user code.  In the case of an immutable
    collection, we happily suppress the warning knowing that
    everything is safe.  If we were returning a mutable collection, it
    would be unsafe to suppress the warning, and doing so would be a
    library bug.

    We have several ways out of this hole; one is to restrict
    invocation, as you suggest.  Another is to add some unchecked
    warnings.  (Another possible path is to treat signatures of erased
    __SS members, when accessed from outside, as if they contained
    capture variables.)



There are other problematic situations, like accessing _SS members from instance members:

public class Foo<any T> {
    private _SS List<T> list = new ArrayList<>();

    public void add(T element) {
        list.add(element);
    }

    public T get(int i) {
        return list.get(i);
    }
}


Foo<String> fooStr = new Foo<>();
Foo<Number> fooNum = new Foo<>();

fooStr.add("abc");
Number n = fooNum.get(0);


...or, by analogy, accessing _SS members from generic methods.


Regards, Peter






    On 2/17/2016 12:03 PM, Peter Levart wrote:

        Hi Brian,

        On 02/15/2016 07:11 PM, Brian Goetz wrote:

            Example:

            class Collection<any T> {
               private __SS Collection<T> emptyCollection = …
               // ACC_SS field emptyCollection : ParamType[Collection,
            TypeVar[T]]

               private __SS Collection<T> emptyCollection() { return
            emptyCollection; }
               ACC_SS emptyCollection()ParamType[Collection, TypeVar[T]] {
                   getstatic ParamType[Collection,
            TypeVar[T]].emptyCollection : ParamType[Collection,
            TypeVar[T]]]
                   areturn
               }

            When we specialize Collection<int>, the field type, method
            return type, etc, will all collapse to Collection<int> by
            the existing mechanisms.


        This would work if the emptyCollection was actually empty and
        immutable, but could you do the following:

        class Collection<any T> {
           private __SS Collection<T>collection = new ArrayList<T>();

           public __SS Collection<T> collection() { return collection; }
        }


        And then in code:

        Collection<String> cs = Collection<String>.collection();
        Collection<Number> cn = Collection<Number>.collection();

        cs.add("abc");
        Number n = cn.iterator().next();

        If cs and cn hold the same instance, we have introduced heap
        corruption without compilation warnings.

        So I suppose in language you could only access the _SS members
        in the following way:

        Collection<?>.collection();
        Collection<int>.collection();
        Collection<long>.collection();
        Collection<ValueType>.collection();
        ...

        but not:

        Collection<Object>.collection();
        Collection<String>.collection();
        ...


        Like .class literals in the prototype.

        Regards, Peter





Reply via email to