diamond operator and non-denotable types
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Apr 9 11:46:12 PDT 2010
Neal Gafter wrote:
> Maurizio-
>
> How are these cases handed with static factories? Why should it be handled
> differently between static factories and constructors? It seems that the
> diamond operator should be capable of inferring any type arguments a static
> factory could infer. Is there any reason for the diamond operator to be less
> powerful?
>
The problem is with anonymous inner class creation; consider the
following code:
class Foo<X extends A & B> {}
Foo<?> f = new Foo<>();
The inferred type would be Foo<A&B>. This is problematic, because this
type (Foo<A&B>) will be also the supertype of the anonymous inner class.
Unfortunately, this kind of type cannot be expressed under the current
specification of the classfile Signature attribute, so this code lead to
a code generation failure. The same holds for captured-types.
Intersection types are allowed in the Signature attribute only as a way
for representing type-variable bounds. Generalized intersection types do
not have a corresponding representation in the classfile. The compiler
always erases an intersection type to the most appropriate type needed
in order to preserve the semantics of the program.
Maurizio
> The exceptions are due to restrictions on construction. "new ArrayList<?
> extends Number>()" isn't legal, therefore "new ArrayList<>()" should not be
> capable of inferring "? extends Number" for the type argument.
>
> On Fri, Apr 9, 2010 at 10:14 AM, Maurizio Cimadamore <
> maurizio.cimadamore at oracle.com> wrote:
>
>
>> Despite attribution does not have problems with non-denotable types in
>> instance creation expressions, there are circumstances in which such
>> types cause problems in code generation --- this happens e.g. if a
>> non-denotable type is inferred in an anonymous class creation
>> expression; in this case the compiler will try to emit a classfile
>> Signature attribute for a non-denotable type, which is not allowed.
>>
>>
>
> That suggests that the restriction should be applied only to anonymous class
> creation expressions.
>
> Moreover non-denotable types doesn't seem to comply with the set of
>
>> acceptable types in an instance creation expression (see JLS 15.9);
>> despite there's no explicit statement in the JLS forbidding e.g. an
>> intersection type as part of an instance creation expression, it seems
>> sensible to statically forbid these occurrence, as the semantics of such
>> types is not crystal clear --- these types are introduced as
>> compile-time artifacts in order to enhance the applicability of compiler
>> checks, but it is not clear what their behavior should look like.
>>
>>
>
> All generics are compile-time artifacts in order to enhance the
> applicability of compiler checks. Intersection types are specified,
> representable in the class file, and erased at runtime too. Where's the
> problem?
>
>
>
>> The most straightforward solution (see above) is to issue an error when
>> a non-denotable type is returned as result of the diamond inference
>> scheme. In other words, I propose to change the current spec draft to
>> include a statement like:
>>
>> "If the diamond algorithm infers a non-denotable type, an error must be
>> issued by the compiler".
>>
>>
>
> "It is an error if the inferred class type parameters are not denotable and
> a class body is present."
>
> This requires a formal definition of "denotable". Because it should not
> include wildcards, which can be denoted in source, denotable is probably not
> the right word.
>
> Cheers,
> Neal
>
>
More information about the coin-dev
mailing list