changeset 3049:732890c00534

8044196: Incorrect applying of repeatable annotations with incompatible target to type parameter Summary: Additional applicability checks added. Reviewed-by: jlahoda
author alundblad
date Thu, 30 Apr 2015 12:21:50 +0200
parents 1a5121a90ecf
children d63911765771
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties test/tools/javac/annotations/repeatingAnnotations/InvalidClsTypeParamTarget.java test/tools/javac/annotations/repeatingAnnotations/InvalidClsTypeParamTarget.out test/tools/javac/annotations/repeatingAnnotations/InvalidMethodTypeParamTarget.java test/tools/javac/annotations/repeatingAnnotations/InvalidMethodTypeParamTarget.out test/tools/javac/annotations/repeatingAnnotations/InvalidMethodTypeUse.java test/tools/javac/annotations/repeatingAnnotations/InvalidMethodTypeUse.out test/tools/javac/annotations/repeatingAnnotations/InvalidRepAnnoOnCast.java test/tools/javac/annotations/repeatingAnnotations/InvalidRepAnnoOnCast.out test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/BrokenTypeAnnoContainer.java test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/BrokenTypeAnnoContainer.out test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/T.java test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/TC.java test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/TCBroken.java test/tools/javac/diags/examples/InvalidTypeContextRepeatableAnnotation.java
diffstat 18 files changed, 275 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Wed Apr 29 15:05:33 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Thu Apr 30 12:21:50 2015 +0200
@@ -28,11 +28,11 @@
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.type.TypeKind;
-
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.code.Attribute.Array;
 import com.sun.tools.javac.code.Attribute.TypeCompound;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
 import com.sun.tools.javac.code.Type.ArrayType;
 import com.sun.tools.javac.code.Type.CapturedType;
 import com.sun.tools.javac.code.Type.ClassType;
@@ -153,8 +153,8 @@
 
     public enum AnnotationType { DECLARATION, TYPE, NONE, BOTH }
 
-    public List<Attribute> annotationTargets(Attribute.Compound anno) {
-        Attribute.Compound atTarget = anno.type.tsym.getAnnotationTypeMetadata().getTarget();
+    public List<Attribute> annotationTargets(TypeSymbol tsym) {
+        Attribute.Compound atTarget = tsym.getAnnotationTypeMetadata().getTarget();
         if (atTarget == null) {
             return null;
         }
@@ -177,7 +177,7 @@
      * a type annotation, or both.
      */
     public AnnotationType annotationTargetType(Attribute.Compound a, Symbol s) {
-        List<Attribute> targets = annotationTargets(a);
+        List<Attribute> targets = annotationTargets(a.type.tsym);
         return (targets == null) ?
                 AnnotationType.DECLARATION :
                 targets.stream()
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java	Wed Apr 29 15:05:33 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java	Thu Apr 30 12:21:50 2015 +0200
@@ -243,7 +243,10 @@
                         log.error(annotations.head.pos, "already.annotated", Kinds.kindName(s), s);
 
                     Assert.checkNonNull(s, "Symbol argument to actualEnterAnnotations is null");
-                    annotateNow(s, annotations, localEnv, false);
+
+                    // false is passed as fifth parameter since annotateLater is
+                    // never called for a type parameter
+                    annotateNow(s, annotations, localEnv, false, false);
                 } finally {
                     if (prevLint != null)
                         chk.setLint(prevLint);
@@ -327,7 +330,8 @@
      * then continue on with repeating annotations processing.
      */
     private <T extends Attribute.Compound> void annotateNow(Symbol toAnnotate,
-            List<JCAnnotation> withAnnotations, Env<AttrContext> env, boolean typeAnnotations)
+            List<JCAnnotation> withAnnotations, Env<AttrContext> env, boolean typeAnnotations,
+            boolean isTypeParam)
     {
         Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>();
         Map<T, DiagnosticPosition> pos = new HashMap<>();
@@ -377,7 +381,7 @@
                 buf = buf.prepend(lb.first());
             } else {
                 AnnotationContext<T> ctx = new AnnotationContext<>(env, annotated, pos, typeAnnotations);
-                T res = makeContainerAnnotation(lb.toList(), ctx, toAnnotate);
+                T res = makeContainerAnnotation(lb.toList(), ctx, toAnnotate, isTypeParam);
                 if (res != null)
                     buf = buf.prepend(res);
             }
@@ -698,7 +702,7 @@
      * annotation are invalid.  This method reports errors/warnings.
      */
     private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
-            AnnotationContext<T> ctx, Symbol on)
+            AnnotationContext<T> ctx, Symbol on, boolean isTypeParam)
     {
         T firstOccurrence = annotations.head;
         List<Attribute> repeated = List.nil();
@@ -752,7 +756,8 @@
 
         if (!repeated.isEmpty()) {
             repeated = repeated.reverse();
-            TreeMaker m = make.at(ctx.pos.get(firstOccurrence));
+            DiagnosticPosition pos = ctx.pos.get(firstOccurrence);
+            TreeMaker m = make.at(pos);
             Pair<MethodSymbol, Attribute> p =
                     new Pair<MethodSymbol, Attribute>(containerValueSymbol,
                             new Attribute.Array(arrayOfOrigAnnoType, repeated));
@@ -768,7 +773,14 @@
                 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
                         ((Attribute.TypeCompound)annotations.head).position);
 
-                // TODO: annotation applicability checks from below?
+                JCAnnotation annoTree = m.TypeAnnotation(at);
+                if (!chk.validateAnnotationDeferErrors(annoTree))
+                    log.error(annoTree.pos(), Errors.DuplicateAnnotationInvalidRepeated(origAnnoType));
+
+                if (!chk.isTypeAnnotation(annoTree, isTypeParam)) {
+                    log.error(pos, isTypeParam ? Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on)
+                                               : Errors.InvalidRepeatableAnnotationNotApplicableInContext(targetContainerType));
+                }
 
                 at.setSynthesized(true);
 
@@ -925,11 +937,11 @@
     }
 
     private <T extends Attribute.Compound> T makeContainerAnnotation(List<T> toBeReplaced,
-            AnnotationContext<T> ctx, Symbol sym)
+            AnnotationContext<T> ctx, Symbol sym, boolean isTypeParam)
     {
         // Process repeated annotations
         T validRepeated =
-                processRepeatedAnnotations(toBeReplaced, ctx, sym);
+                processRepeatedAnnotations(toBeReplaced, ctx, sym, isTypeParam);
 
         if (validRepeated != null) {
             // Check that the container isn't manually
@@ -955,7 +967,7 @@
      * Attribute the list of annotations and enter them onto s.
      */
     public void enterTypeAnnotations(List<JCAnnotation> annotations, Env<AttrContext> env,
-            Symbol s, DiagnosticPosition deferPos)
+            Symbol s, DiagnosticPosition deferPos, boolean isTypeParam)
     {
         Assert.checkNonNull(s, "Symbol argument to actualEnterTypeAnnotations is nul/");
         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
@@ -965,7 +977,7 @@
             prevLintPos = deferredLintHandler.setPos(deferPos);
         }
         try {
-            annotateNow(s, annotations, env, true);
+            annotateNow(s, annotations, env, true, isTypeParam);
         } finally {
             if (prevLintPos != null)
                 deferredLintHandler.setPos(prevLintPos);
@@ -1048,21 +1060,21 @@
 
         @Override
         public void visitAnnotatedType(JCAnnotatedType tree) {
-            enterTypeAnnotations(tree.annotations, env, sym, deferPos);
+            enterTypeAnnotations(tree.annotations, env, sym, deferPos, false);
             scan(tree.underlyingType);
         }
 
         @Override
         public void visitTypeParameter(JCTypeParameter tree) {
-            enterTypeAnnotations(tree.annotations, env, sym, deferPos);
+            enterTypeAnnotations(tree.annotations, env, sym, deferPos, true);
             scan(tree.bounds);
         }
 
         @Override
         public void visitNewArray(JCNewArray tree) {
-            enterTypeAnnotations(tree.annotations, env, sym, deferPos);
+            enterTypeAnnotations(tree.annotations, env, sym, deferPos, false);
             for (List<JCAnnotation> dimAnnos : tree.dimAnnotations)
-                enterTypeAnnotations(dimAnnos, env, sym, deferPos);
+                enterTypeAnnotations(dimAnnos, env, sym, deferPos, false);
             scan(tree.elemtype);
             scan(tree.elems);
         }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Wed Apr 29 15:05:33 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Thu Apr 30 12:21:50 2015 +0200
@@ -2999,7 +2999,7 @@
 
     /** Is the annotation applicable to types? */
     protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
-        List<Attribute> targets = typeAnnotations.annotationTargets(a.attribute);
+        List<Attribute> targets = typeAnnotations.annotationTargets(a.annotationType.type.tsym);
         return (targets == null) ?
                 false :
                 targets.stream()
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Apr 29 15:05:33 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Apr 30 12:21:50 2015 +0200
@@ -414,6 +414,10 @@
 compiler.err.invalid.repeatable.annotation.not.applicable=\
     container {0} is not applicable to element {1}
 
+# 0: type
+compiler.err.invalid.repeatable.annotation.not.applicable.in.context=\
+    container {0} is not applicable in this type context
+
 # 0: name
 compiler.err.duplicate.class=\
     duplicate class: {0}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/InvalidClsTypeParamTarget.java	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,21 @@
+/**
+ * @test    /nodynamiccopyright/
+ * @bug     8044196
+ * @summary Ensure that containers with target FIELD can't be applied to type parameters.
+ * @compile/fail/ref=InvalidClsTypeParamTarget.out -XDrawDiagnostics InvalidClsTypeParamTarget.java
+ */
+
+import java.lang.annotation.*;
+
+class InvalidClsTypeParamTarget {
+
+    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE, ElementType.FIELD})
+    @Repeatable(TC.class)
+    @interface T { int value(); }
+
+    @Target(ElementType.FIELD)
+    @interface TC { T[] value(); }
+
+    class Test<@T(1) @T(2) N> {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/InvalidClsTypeParamTarget.out	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,2 @@
+InvalidClsTypeParamTarget.java:19:16: compiler.err.invalid.repeatable.annotation.not.applicable: InvalidClsTypeParamTarget.TC, InvalidClsTypeParamTarget.Test
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/InvalidMethodTypeParamTarget.java	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,20 @@
+/**
+ * @test    /nodynamiccopyright/
+ * @bug     8044196
+ * @summary Ensure that containers with target METHOD can't be applied to type parameters.
+ * @compile/fail/ref=InvalidMethodTypeParamTarget.out -XDrawDiagnostics InvalidMethodTypeParamTarget.java
+ */
+
+import java.lang.annotation.*;
+
+class InvalidMethodTypeParamTarget {
+
+    @Target({ElementType.TYPE_PARAMETER, ElementType.METHOD})
+    @Repeatable(TC.class)
+    @interface T { int value(); }
+
+    @Target(ElementType.METHOD)
+    @interface TC { T[] value(); }
+
+    public <@T(1) @T(2) N> void method() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/InvalidMethodTypeParamTarget.out	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,2 @@
+InvalidMethodTypeParamTarget.java:19:13: compiler.err.invalid.repeatable.annotation.not.applicable: InvalidMethodTypeParamTarget.TC, <N>method()
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/InvalidMethodTypeUse.java	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,24 @@
+/**
+ * @test    /nodynamiccopyright/
+ * @bug     8044196
+ * @summary Make sure repeatable annotations can't be erroneously applied to type arguments.
+ * @compile/fail/ref=InvalidMethodTypeUse.out -XDrawDiagnostics InvalidMethodTypeUse.java
+ */
+
+import java.lang.annotation.*;
+
+class InvalidMethodTypeUse {
+
+    @Target({ElementType.TYPE_USE, ElementType.METHOD, ElementType.TYPE_PARAMETER})
+    @Repeatable(TC.class)
+    @interface T { int value(); }
+
+    @Target({ElementType.METHOD, ElementType.TYPE_PARAMETER})
+    @interface TC { T[] value(); }
+
+    void method() {
+        this.<@T(1) @T(2) String>method2();
+    }
+
+    <@T(3) S> void method2() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/InvalidMethodTypeUse.out	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,2 @@
+InvalidMethodTypeUse.java:20:15: compiler.err.invalid.repeatable.annotation.not.applicable.in.context: InvalidMethodTypeUse.TC
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/InvalidRepAnnoOnCast.java	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,20 @@
+/**
+ * @test    /nodynamiccopyright/
+ * @bug     8044196
+ * @summary Make sure repeatable annotations can't be erroneously applied to a cast type
+ * @compile/fail/ref=InvalidRepAnnoOnCast.out -XDrawDiagnostics InvalidRepAnnoOnCast.java
+ */
+
+import java.lang.annotation.*;
+
+class InvalidRepAnnoOnCast {
+
+    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+    @Repeatable(TC.class)
+    @interface T { int value(); }
+
+    @Target(ElementType.TYPE_PARAMETER)
+    @interface TC { T[] value(); }
+
+    String s = (@T(1) @T(2) String) new Object();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/InvalidRepAnnoOnCast.out	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,2 @@
+InvalidRepAnnoOnCast.java:19:17: compiler.err.invalid.repeatable.annotation.not.applicable.in.context: InvalidRepAnnoOnCast.TC
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/BrokenTypeAnnoContainer.java	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,14 @@
+/**
+ * @test    /nodynamiccopyright/
+ * @bug     8044196
+ * @summary Ensure that a broken type annotation container generates a correct error message.
+ * @compile T.java TC.java
+ * @compile TCBroken.java
+ * @compile/fail/ref=BrokenTypeAnnoContainer.out -XDrawDiagnostics BrokenTypeAnnoContainer.java
+ */
+
+class BrokenTypeAnnoContainer {
+    void method() {
+        int ll2 = (@T(1) @T(2) int) 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/BrokenTypeAnnoContainer.out	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,2 @@
+BrokenTypeAnnoContainer.java:12:20: compiler.err.duplicate.annotation.invalid.repeated: T
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/T.java	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE_USE)
+@Repeatable(TC.class)
+@interface T { int value(); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/TC.java	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE_USE)
+@interface TC {
+    T[] value();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/brokenTypeAnnoContainer/TCBroken.java	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE_USE)
+@interface TC {
+    T[] value();
+    int foo();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/InvalidTypeContextRepeatableAnnotation.java	Thu Apr 30 12:21:50 2015 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.not.applicable.in.context
+
+
+import java.lang.annotation.*;
+
+@Target({ElementType.TYPE_USE, ElementType.METHOD, ElementType.TYPE_PARAMETER})
+@Repeatable(TC.class)
+@interface T { int value(); }
+
+@Target({ElementType.METHOD, ElementType.TYPE_PARAMETER})
+@interface TC { T[] value(); }
+
+public class InvalidTypeContextRepeatableAnnotation {
+    void method() {
+        this.<@T(1) @T(2) String>method2();
+    }
+
+    <@T(3) S> void method2() {
+    }
+}