Victor Ermolaev
Victor Ermolaev

Reputation: 791

Annotation on star types

I have a very simple example

@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.TYPE, AnnotationTarget.EXPRESSION)
annotation class Test

data class MyClass(
    val setInt: Set<@Test Int>,
    val setStar: Set<@Test *>,
)

Field setInt is accepted just fine by the compiler, but for the field setStar the compiler produces an error Type expected, although my annotation is extremely generic: it only applies in source and on any expression.

Is this impossible? Is there a way around it?

Update: here is playground

Upvotes: 0

Views: 76

Answers (2)

Sweeper
Sweeper

Reputation: 274566

No, this is simply not allowed by the syntax.

The syntax of a simple user type is:

simpleUserType:
    simpleIdentifier [{NL} typeArguments]
typeArguments:
    '<'
    {NL}
    typeProjection
    {{NL} ',' {NL} typeProjection}
    [{NL} ',']
    {NL}
    '>'
typeProjection:
    ([typeProjectionModifiers] type)
    | '*'
typeProjectionModifiers:
    typeProjectionModifier {typeProjectionModifier}
typeProjectionModifier:
    (varianceModifier {NL})
    | annotation

Specifically, the production rule for typeProjection (which is part of the typeArguments) includes two alternatives: either another type optionally prefixed with some modifiers (e.g. the annotations that you want to add), or the * character by itself.

The * is not a type or an expression. It is a projection, just like how in Int or out String are projections, not types (though Int and String are types). You can't annotate a projection, but you can annotate the type that is used in a projection. It just so happens that * is a projection that doesn't use any types.

As a workaround (for Set at least), you can change the star projection to just Any?, which mean the same thing in the case of Set.

data class MyClass(
    val setInt: Set<@Test Int>,
    val setStar: Set<@Test Any?>,
)

Now you have a type to annotate!

Most of the time, you can rewrite a star projection to another projection that does use a type, see this for more info.

Upvotes: 2

Emanuel Garcia
Emanuel Garcia

Reputation: 335

I see you add an extra , in the end of setStar.

Try to delete that and will work fine.

Upvotes: 0

Related Questions