8040327: Eliminate AnnotatedType
authoremc
Fri, 09 May 2014 09:28:47 -0400
changeset 24396 3c36c6afcbca
parent 24395 5c541aef1350
child 24397 32aef69ee177
8040327: Eliminate AnnotatedType Summary: Replace AnnotatedType with type annotations being stored in the Type class as metadata Reviewed-by: jjg, jfranck, wmdietl, jlahoda
langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
langtools/src/share/classes/com/sun/tools/javac/code/Type.java
langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
langtools/src/share/classes/com/sun/tools/javac/code/Types.java
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java
langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java
langtools/src/share/classes/com/sun/tools/javac/jvm/UninitializedType.java
langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java
langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java
langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java
langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java
langtools/test/tools/javac/types/TypeHarness.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java	Fri May 09 09:28:47 2014 -0400
@@ -118,7 +118,8 @@
                 : types.erasure(type);
             return new Type.ClassType(types.syms.classType.getEnclosingType(),
                                       List.of(arg),
-                                      types.syms.classType.tsym);
+                                      types.syms.classType.tsym,
+                                      Type.noAnnotations);
         }
         public String toString() {
             return classType + ".class";
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java	Fri May 09 09:28:47 2014 -0400
@@ -28,7 +28,6 @@
 import java.util.Locale;
 
 import com.sun.tools.javac.api.Messages;
-import com.sun.tools.javac.code.Type.AnnotatedType;
 import com.sun.tools.javac.code.Type.ArrayType;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
@@ -150,14 +149,16 @@
     @Override
     public String visitCapturedType(CapturedType t, Locale locale) {
         if (seenCaptured.contains(t))
-            return localize(locale, "compiler.misc.type.captureof.1",
-                capturedVarId(t, locale));
+            return printAnnotations(t) +
+                localize(locale, "compiler.misc.type.captureof.1",
+                         capturedVarId(t, locale));
         else {
             try {
                 seenCaptured = seenCaptured.prepend(t);
-                return localize(locale, "compiler.misc.type.captureof",
-                    capturedVarId(t, locale),
-                    visit(t.wildcard, locale));
+                return printAnnotations(t) +
+                    localize(locale, "compiler.misc.type.captureof",
+                             capturedVarId(t, locale),
+                             visit(t.wildcard, locale));
             }
             finally {
                 seenCaptured = seenCaptured.tail;
@@ -167,15 +168,16 @@
 
     @Override
     public String visitForAll(ForAll t, Locale locale) {
-        return "<" + visitTypes(t.tvars, locale) + ">" + visit(t.qtype, locale);
+        return printAnnotations(t) + "<" + visitTypes(t.tvars, locale) +
+            ">" + visit(t.qtype, locale);
     }
 
     @Override
     public String visitUndetVar(UndetVar t, Locale locale) {
         if (t.inst != null) {
-            return visit(t.inst, locale);
+            return printAnnotations(t) + visit(t.inst, locale);
         } else {
-            return visit(t.qtype, locale) + "?";
+            return printAnnotations(t) + visit(t.qtype, locale) + "?";
         }
     }
 
@@ -187,25 +189,34 @@
         return res.toString();
     }
 
-    void printBaseElementType(Type t, StringBuilder sb, Locale locale) {
+    private String printAnnotations(Type t) {
+        return printAnnotations(t, false);
+    }
+
+    private String printAnnotations(Type t, boolean prefix) {
+        StringBuilder sb = new StringBuilder();
+        List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
+        if (!annos.isEmpty()) {
+            if (prefix) sb.append(' ');
+            sb.append(annos);
+            sb.append(' ');
+        }
+        return sb.toString();
+    }
+
+    private void printBaseElementType(Type t, StringBuilder sb, Locale locale) {
         Type arrel = t;
         while (arrel.hasTag(TypeTag.ARRAY)) {
-            arrel = arrel.unannotatedType();
             arrel = ((ArrayType) arrel).elemtype;
         }
         sb.append(visit(arrel, locale));
     }
 
-    void printBrackets(Type t, StringBuilder sb, Locale locale) {
+    private void printBrackets(Type t, StringBuilder sb, Locale locale) {
         Type arrel = t;
         while (arrel.hasTag(TypeTag.ARRAY)) {
-            if (arrel.isAnnotated()) {
-                sb.append(' ');
-                sb.append(arrel.getAnnotationMirrors());
-                sb.append(' ');
-            }
+            sb.append(printAnnotations(arrel, true));
             sb.append("[]");
-            arrel = arrel.unannotatedType();
             arrel = ((ArrayType) arrel).elemtype;
         }
     }
@@ -216,8 +227,10 @@
         if (t.getEnclosingType().hasTag(CLASS) && t.tsym.owner.kind == Kinds.TYP) {
             buf.append(visit(t.getEnclosingType(), locale));
             buf.append('.');
+            buf.append(printAnnotations(t));
             buf.append(className(t, false, locale));
         } else {
+            buf.append(printAnnotations(t));
             buf.append(className(t, true, locale));
         }
         if (t.getTypeArguments().nonEmpty()) {
@@ -230,7 +243,8 @@
 
     @Override
     public String visitMethodType(MethodType t, Locale locale) {
-        return "(" + printMethodArgs(t.argtypes, false, locale) + ")" + visit(t.restype, locale);
+        return "(" + printMethodArgs(t.argtypes, false, locale) + ")" +
+            visit(t.restype, locale);
     }
 
     @Override
@@ -243,6 +257,7 @@
         StringBuilder s = new StringBuilder();
         s.append(t.kind);
         if (t.kind != UNBOUND) {
+            s.append(printAnnotations(t));
             s.append(visit(t.type, locale));
         }
         return s.toString();
@@ -258,28 +273,6 @@
         return visitType(t, locale);
     }
 
-    @Override
-    public String visitAnnotatedType(AnnotatedType t, Locale locale) {
-        if (t.getAnnotationMirrors().nonEmpty()) {
-            if (t.unannotatedType().hasTag(TypeTag.ARRAY)) {
-                StringBuilder res = new StringBuilder();
-                printBaseElementType(t, res, locale);
-                printBrackets(t, res, locale);
-                return res.toString();
-            } else if (t.unannotatedType().hasTag(TypeTag.CLASS) &&
-                    t.unannotatedType().getEnclosingType() != Type.noType) {
-                return visit(t.unannotatedType().getEnclosingType(), locale) +
-                        ". " +
-                        t.getAnnotationMirrors() +
-                        " " + className((ClassType)t.unannotatedType(), false, locale);
-            } else {
-                return t.getAnnotationMirrors() + " " + visit(t.unannotatedType(), locale);
-            }
-        } else {
-            return visit(t.unannotatedType(), locale);
-        }
-    }
-
     public String visitType(Type t, Locale locale) {
         String s = (t.tsym == null || t.tsym.name == null)
                 ? localize(locale, "compiler.misc.type.none")
@@ -345,8 +338,8 @@
                 args = args.tail;
                 buf.append(',');
             }
-            if (args.head.unannotatedType().hasTag(TypeTag.ARRAY)) {
-                buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale));
+            if (args.head.hasTag(TypeTag.ARRAY)) {
+                buf.append(visit(((ArrayType) args.head).elemtype, locale));
                 if (args.head.getAnnotationMirrors().nonEmpty()) {
                     buf.append(' ');
                     buf.append(args.head.getAnnotationMirrors());
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri May 09 09:28:47 2014 -0400
@@ -956,7 +956,7 @@
             this(
                 flags,
                 name,
-                new ClassType(Type.noType, null, null),
+                new ClassType(Type.noType, null, null, Type.noAnnotations),
                 owner);
             this.type.tsym = this;
         }
@@ -992,7 +992,8 @@
         public Type erasure(Types types) {
             if (erasure_field == null)
                 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
-                                              List.<Type>nil(), this);
+                                              List.<Type>nil(), this,
+                                              type.getAnnotationMirrors());
             return erasure_field;
         }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Fri May 09 09:28:47 2014 -0400
@@ -80,6 +80,9 @@
     /** Constant type: special type to be used for marking stuck trees. */
     public static final JCNoType stuckType = new JCNoType();
 
+    public static final List<Attribute.TypeCompound> noAnnotations =
+        List.nil();
+
     /** If this switch is turned on, the names of type variables
      *  and anonymous classes are printed with hashcodes appended.
      */
@@ -89,6 +92,10 @@
      */
     public TypeSymbol tsym;
 
+    /** The type annotations on this type.
+     */
+    protected final List<Attribute.TypeCompound> annos;
+
     /**
      * Checks if the current type tag is equal to the given tag.
      * @return true if tag is equal to the current type tag.
@@ -173,10 +180,15 @@
 
     public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
 
-    /** Define a type given its tag and type symbol
+    /** Define a type given its tag, type symbol, and type annotations
      */
-    public Type(TypeSymbol tsym) {
+    public Type(TypeSymbol tsym, List<Attribute.TypeCompound> annos) {
+        if(annos == null) {
+            Assert.error("Attempting to create type " + tsym + " with null type annotations");
+        }
+
         this.tsym = tsym;
+        this.annos = annos;
     }
 
     /** An abstract class for mappings from types to types
@@ -225,25 +237,15 @@
         return this;
     }
 
-    public Type annotatedType(List<Attribute.TypeCompound> annos) {
-        return new AnnotatedType(annos, this);
-    }
+    public abstract Type annotatedType(List<Attribute.TypeCompound> annos);
 
     public boolean isAnnotated() {
-        return false;
-    }
-
-    /**
-     * If this is an annotated type, return the underlying type.
-     * Otherwise, return the type itself.
-     */
-    public Type unannotatedType() {
-        return this;
+        return !annos.isEmpty();
     }
 
     @Override
     public List<Attribute.TypeCompound> getAnnotationMirrors() {
-        return List.nil();
+        return annos;
     }
 
 
@@ -272,16 +274,35 @@
         return ts;
     }
 
+    protected void appendAnnotationsString(StringBuilder sb,
+                                         boolean prefix) {
+        if (isAnnotated()) {
+            if (prefix) {
+                sb.append(" ");
+            }
+            sb.append(annos);
+            sb.append(" ");
+        }
+    }
+
+    protected void appendAnnotationsString(StringBuilder sb) {
+        appendAnnotationsString(sb, false);
+    }
+
     /** The Java source which this type represents.
      */
     public String toString() {
-        String s = (tsym == null || tsym.name == null)
-            ? "<none>"
-            : tsym.name.toString();
+        StringBuilder sb = new StringBuilder();
+        appendAnnotationsString(sb);
+        if (tsym == null || tsym.name == null) {
+            sb.append("<none>");
+        } else {
+            sb.append(tsym.name);
+        }
         if (moreInfo && hasTag(TYPEVAR)) {
-            s = s + hashCode();
+            sb.append(hashCode());
         }
-        return s;
+        return sb.toString();
     }
 
     /**
@@ -333,8 +354,8 @@
             args = args.tail;
             buf.append(',');
         }
-        if (args.head.unannotatedType().hasTag(ARRAY)) {
-            buf.append(((ArrayType)args.head.unannotatedType()).elemtype);
+        if (args.head.hasTag(ARRAY)) {
+            buf.append(((ArrayType)args.head).elemtype);
             if (args.head.getAnnotationMirrors().nonEmpty()) {
                 buf.append(args.head.getAnnotationMirrors());
             }
@@ -486,12 +507,22 @@
         TypeTag tag;
 
         public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
-            super(tsym);
+            this(tag, tsym, noAnnotations);
+        }
+
+        public JCPrimitiveType(TypeTag tag, TypeSymbol tsym,
+                               List<Attribute.TypeCompound> annos) {
+            super(tsym, annos);
             this.tag = tag;
             Assert.check(tag.isPrimitive);
         }
 
         @Override
+        public Type annotatedType(List<Attribute.TypeCompound> annos) {
+            return new JCPrimitiveType(tag, tsym, annos);
+        }
+
+        @Override
         public boolean isNumeric() {
             return tag != BOOLEAN;
         }
@@ -517,7 +548,7 @@
         @Override
         public Type constType(Object constValue) {
             final Object value = constValue;
-            return new JCPrimitiveType(tag, tsym) {
+            return new JCPrimitiveType(tag, tsym, annos) {
                     @Override
                     public Object constValue() {
                         return value;
@@ -601,17 +632,35 @@
         }
 
         public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
-            super(tsym);
+            this(type, kind, tsym, null, noAnnotations);
+        }
+
+        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
+                            List<Attribute.TypeCompound> annos) {
+            this(type, kind, tsym, null, annos);
+        }
+
+        public WildcardType(WildcardType t, TypeVar bound,
+                            List<Attribute.TypeCompound> annos) {
+            this(t.type, t.kind, t.tsym, bound, annos);
+        }
+
+        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
+                            TypeVar bound) {
+            this(type, kind, tsym, noAnnotations);
+        }
+
+        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
+                            TypeVar bound, List<Attribute.TypeCompound> annos) {
+            super(tsym, annos);
             this.type = Assert.checkNonNull(type);
             this.kind = kind;
-        }
-        public WildcardType(WildcardType t, TypeVar bound) {
-            this(t.type, t.kind, t.tsym, bound);
+            this.bound = bound;
         }
 
-        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, TypeVar bound) {
-            this(type, kind, tsym);
-            this.bound = bound;
+        @Override
+        public WildcardType annotatedType(List<Attribute.TypeCompound> annos) {
+            return new WildcardType(type, kind, tsym, bound, annos);
         }
 
         @Override
@@ -658,6 +707,7 @@
         boolean isPrintingBound = false;
         public String toString() {
             StringBuilder s = new StringBuilder();
+            appendAnnotationsString(s);
             s.append(kind.toString());
             if (kind != UNBOUND)
                 s.append(type);
@@ -679,7 +729,7 @@
             if (t == type)
                 return this;
             else
-                return new WildcardType(t, kind, tsym, bound);
+                return new WildcardType(t, kind, tsym, bound, annos);
         }
 
         public Type getExtendsBound() {
@@ -736,7 +786,12 @@
         public List<Type> all_interfaces_field;
 
         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
-            super(tsym);
+            this(outer, typarams, tsym, noAnnotations);
+        }
+
+        public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
+                         List<Attribute.TypeCompound> annos) {
+            super(tsym, annos);
             this.outer_field = outer;
             this.typarams_field = typarams;
             this.allparams_field = null;
@@ -754,6 +809,15 @@
         }
 
         @Override
+        public ClassType annotatedType(List<Attribute.TypeCompound> annos) {
+            final ClassType out = new ClassType(outer_field, typarams_field, tsym, annos);
+            out.allparams_field = allparams_field;
+            out.supertype_field = supertype_field;
+            out.interfaces_field = interfaces_field;
+            return out;
+        }
+
+        @Override
         public TypeTag getTag() {
             return CLASS;
         }
@@ -765,7 +829,7 @@
 
         public Type constType(Object constValue) {
             final Object value = constValue;
-            return new ClassType(getEnclosingType(), typarams_field, tsym) {
+            return new ClassType(getEnclosingType(), typarams_field, tsym, annos) {
                     @Override
                     public Object constValue() {
                         return value;
@@ -781,6 +845,7 @@
          */
         public String toString() {
             StringBuilder buf = new StringBuilder();
+            appendAnnotationsString(buf);
             if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
                 buf.append(getEnclosingType().toString());
                 buf.append(".");
@@ -806,7 +871,7 @@
                     return s.toString();
                 } else if (sym.name.isEmpty()) {
                     String s;
-                    ClassType norm = (ClassType) tsym.type.unannotatedType();
+                    ClassType norm = (ClassType) tsym.type;
                     if (norm == null) {
                         s = Log.getLocalizedString("anonymous.class", (Object)null);
                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
@@ -858,7 +923,7 @@
             return
                 getEnclosingType().isErroneous() ||
                 isErroneous(getTypeArguments()) ||
-                this != tsym.type.unannotatedType() && tsym.type.isErroneous();
+                this != tsym.type && tsym.type.isErroneous();
         }
 
         public boolean isParameterized() {
@@ -897,7 +962,7 @@
             List<Type> typarams = getTypeArguments();
             List<Type> typarams1 = map(typarams, f);
             if (outer1 == outer && typarams1 == typarams) return this;
-            else return new ClassType(outer1, typarams1, tsym);
+            else return new ClassType(outer1, typarams1, tsym, annos);
         }
 
         public boolean contains(Type elem) {
@@ -924,7 +989,12 @@
 
     public static class ErasedClassType extends ClassType {
         public ErasedClassType(Type outer, TypeSymbol tsym) {
-            super(outer, List.<Type>nil(), tsym);
+            this(outer, tsym, noAnnotations);
+        }
+
+        public ErasedClassType(Type outer, TypeSymbol tsym,
+                               List<Attribute.TypeCompound> annos) {
+            super(outer, List.<Type>nil(), tsym, annos);
         }
 
         @Override
@@ -938,7 +1008,9 @@
         final List<? extends Type> alternatives_field;
 
         public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
-            super(ct.outer_field, ct.typarams_field, ct.tsym);
+            // Presently no way to refer to this type directly, so we
+            // cannot put annotations directly on it.
+            super(ct.outer_field, ct.typarams_field, ct.tsym, noAnnotations);
             allparams_field = ct.allparams_field;
             supertype_field = ct.supertype_field;
             interfaces_field = ct.interfaces_field;
@@ -971,7 +1043,9 @@
         public boolean allInterfaces;
 
         public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) {
-            super(Type.noType, List.<Type>nil(), csym);
+            // Presently no way to refer to this type directly, so we
+            // cannot put annotations directly on it.
+            super(Type.noType, List.<Type>nil(), csym, noAnnotations);
             this.allInterfaces = allInterfaces;
             Assert.check((csym.flags() & COMPOUND) != 0);
             supertype_field = bounds.head;
@@ -1011,11 +1085,21 @@
         public Type elemtype;
 
         public ArrayType(Type elemtype, TypeSymbol arrayClass) {
-            super(arrayClass);
+            this(elemtype, arrayClass, noAnnotations);
+        }
+
+        public ArrayType(Type elemtype, TypeSymbol arrayClass,
+                         List<Attribute.TypeCompound> annos) {
+            super(arrayClass, annos);
             this.elemtype = elemtype;
         }
 
         @Override
+        public ArrayType annotatedType(List<Attribute.TypeCompound> annos) {
+            return new ArrayType(elemtype, tsym, annos);
+        }
+
+        @Override
         public TypeTag getTag() {
             return ARRAY;
         }
@@ -1025,7 +1109,11 @@
         }
 
         public String toString() {
-            return elemtype + "[]";
+            StringBuilder sb = new StringBuilder();
+            sb.append(elemtype);
+            appendAnnotationsString(sb, true);
+            sb.append("[]");
+            return sb.toString();
         }
 
         public boolean equals(Object obj) {
@@ -1068,7 +1156,7 @@
         }
 
         public ArrayType makeVarargs() {
-            return new ArrayType(elemtype, tsym) {
+            return new ArrayType(elemtype, tsym, annos) {
                 @Override
                 public boolean isVarargs() {
                     return true;
@@ -1079,7 +1167,7 @@
         public Type map(Mapping f) {
             Type elemtype1 = f.apply(elemtype);
             if (elemtype1 == elemtype) return this;
-            else return new ArrayType(elemtype1, tsym);
+            else return new ArrayType(elemtype1, tsym, annos);
         }
 
         public boolean contains(Type elem) {
@@ -1117,13 +1205,20 @@
                           Type restype,
                           List<Type> thrown,
                           TypeSymbol methodClass) {
-            super(methodClass);
+            // Presently no way to refer to a method type directly, so
+            // we cannot put type annotations on it.
+            super(methodClass, noAnnotations);
             this.argtypes = argtypes;
             this.restype = restype;
             this.thrown = thrown;
         }
 
         @Override
+        public MethodType annotatedType(List<Attribute.TypeCompound> annos) {
+            throw new AssertionError("Cannot annotate a method type");
+        }
+
+        @Override
         public TypeTag getTag() {
             return METHOD;
         }
@@ -1138,7 +1233,13 @@
          *  should be.
          */
         public String toString() {
-            return "(" + argtypes + ")" + restype;
+            StringBuilder sb = new StringBuilder();
+            appendAnnotationsString(sb);
+            sb.append('(');
+            sb.append(argtypes);
+            sb.append(')');
+            sb.append(restype);
+            return sb.toString();
         }
 
         public List<Type>        getParameterTypes() { return argtypes; }
@@ -1197,7 +1298,13 @@
     public static class PackageType extends Type implements NoType {
 
         PackageType(TypeSymbol tsym) {
-            super(tsym);
+            // Package types cannot be annotated
+            super(tsym, noAnnotations);
+        }
+
+        @Override
+        public PackageType annotatedType(List<Attribute.TypeCompound> annos) {
+            throw new AssertionError("Cannot annotate a package type");
         }
 
         @Override
@@ -1245,18 +1352,29 @@
         public Type lower;
 
         public TypeVar(Name name, Symbol owner, Type lower) {
-            super(null);
+            this(name, owner, lower, noAnnotations);
+        }
+
+        public TypeVar(Name name, Symbol owner, Type lower,
+                       List<Attribute.TypeCompound> annos) {
+            super(null, annos);
             tsym = new TypeVariableSymbol(0, name, this, owner);
             this.lower = lower;
         }
 
-        public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
-            super(tsym);
+        public TypeVar(TypeSymbol tsym, Type bound, Type lower,
+                       List<Attribute.TypeCompound> annos) {
+            super(tsym, annos);
             this.bound = bound;
             this.lower = lower;
         }
 
         @Override
+        public TypeVar annotatedType(List<Attribute.TypeCompound> annos) {
+            return new TypeVar(tsym, bound, lower, annos);
+        }
+
+        @Override
         public TypeTag getTag() {
             return TYPEVAR;
         }
@@ -1317,13 +1435,29 @@
                             Symbol owner,
                             Type upper,
                             Type lower,
-                            WildcardType wildcard) {
-            super(name, owner, lower);
+                            WildcardType wildcard,
+                            List<Attribute.TypeCompound> annos) {
+            super(name, owner, lower, annos);
             this.lower = Assert.checkNonNull(lower);
             this.bound = upper;
             this.wildcard = wildcard;
         }
 
+        public CapturedType(TypeSymbol tsym,
+                            Type bound,
+                            Type upper,
+                            Type lower,
+                            WildcardType wildcard,
+                            List<Attribute.TypeCompound> annos) {
+            super(tsym, bound, lower, annos);
+            this.wildcard = wildcard;
+        }
+
+        @Override
+        public CapturedType annotatedType(List<Attribute.TypeCompound> annos) {
+            return new CapturedType(tsym, bound, bound, lower, wildcard, annos);
+        }
+
         @Override
         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
             return v.visitCapturedType(this, s);
@@ -1336,18 +1470,22 @@
 
         @Override
         public String toString() {
-            return "capture#"
-                + (hashCode() & 0xFFFFFFFFL) % Printer.PRIME
-                + " of "
-                + wildcard;
+            StringBuilder sb = new StringBuilder();
+            appendAnnotationsString(sb);
+            sb.append("capture#");
+            sb.append((hashCode() & 0xFFFFFFFFL) % Printer.PRIME);
+            sb.append(" of ");
+            sb.append(wildcard);
+            return sb.toString();
         }
     }
 
     public static abstract class DelegatedType extends Type {
         public Type qtype;
         public TypeTag tag;
-        public DelegatedType(TypeTag tag, Type qtype) {
-            super(qtype.tsym);
+        public DelegatedType(TypeTag tag, Type qtype,
+                             List<Attribute.TypeCompound> annos) {
+            super(qtype.tsym, annos);
             this.tag = tag;
             this.qtype = qtype;
         }
@@ -1373,17 +1511,28 @@
         public List<Type> tvars;
 
         public ForAll(List<Type> tvars, Type qtype) {
-            super(FORALL, (MethodType)qtype);
+            super(FORALL, (MethodType)qtype, noAnnotations);
             this.tvars = tvars;
         }
 
         @Override
+        public ForAll annotatedType(List<Attribute.TypeCompound> annos) {
+            throw new AssertionError("Cannot annotate forall type");
+        }
+
+        @Override
         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
             return v.visitForAll(this, s);
         }
 
         public String toString() {
-            return "<" + tvars + ">" + qtype;
+            StringBuilder sb = new StringBuilder();
+            appendAnnotationsString(sb);
+            sb.append('<');
+            sb.append(tvars);
+            sb.append('>');
+            sb.append(qtype);
+            return sb.toString();
         }
 
         public List<Type> getTypeArguments()   { return tvars; }
@@ -1479,7 +1628,8 @@
         }
 
         public UndetVar(TypeVar origin, Types types) {
-            super(UNDETVAR, origin);
+            // This is a synthesized internal type, so we cannot annotate it.
+            super(UNDETVAR, origin, noAnnotations);
             bounds = new EnumMap<>(InferenceBound.class);
             List<Type> declaredBounds = types.getBounds(origin);
             declaredCount = declaredBounds.length();
@@ -1489,7 +1639,15 @@
         }
 
         public String toString() {
-            return (inst == null) ? qtype + "?" : inst.toString();
+            StringBuilder sb = new StringBuilder();
+            appendAnnotationsString(sb);
+            if (inst == null) {
+                sb.append(qtype);
+                sb.append('?');
+            } else {
+                sb.append(inst);
+            }
+            return sb.toString();
         }
 
         public String debugString() {
@@ -1507,6 +1665,11 @@
         }
 
         @Override
+        public UndetVar annotatedType(List<Attribute.TypeCompound> annos) {
+            throw new AssertionError("Cannot annotate an UndetVar type");
+        }
+
+        @Override
         public boolean isPartial() {
             return true;
         }
@@ -1659,7 +1822,15 @@
      */
     public static class JCNoType extends Type implements NoType {
         public JCNoType() {
-            super(null);
+            // Need to use List.nil(), because JCNoType constructor
+            // gets called in static initializers in Type, where
+            // noAnnotations is also defined.
+            super(null, List.<Attribute.TypeCompound>nil());
+        }
+
+        @Override
+        public JCNoType annotatedType(List<Attribute.TypeCompound> annos) {
+            throw new AssertionError("Cannot annotate JCNoType");
         }
 
         @Override
@@ -1686,7 +1857,13 @@
     public static class JCVoidType extends Type implements NoType {
 
         public JCVoidType() {
-            super(null);
+            // Void cannot be annotated
+            super(null, noAnnotations);
+        }
+
+        @Override
+        public JCVoidType annotatedType(List<Attribute.TypeCompound> annos) {
+            throw new AssertionError("Cannot annotate void type");
         }
 
         @Override
@@ -1715,7 +1892,13 @@
 
     static class BottomType extends Type implements NullType {
         public BottomType() {
-            super(null);
+            // Bottom is a synthesized internal type, so it cannot be annotated
+            super(null, noAnnotations);
+        }
+
+        @Override
+        public BottomType annotatedType(List<Attribute.TypeCompound> annos) {
+            throw new AssertionError("Cannot annotate bottom type");
         }
 
         @Override
@@ -1759,7 +1942,12 @@
         private Type originalType = null;
 
         public ErrorType(Type originalType, TypeSymbol tsym) {
-            super(noType, List.<Type>nil(), null);
+            this(originalType, tsym, noAnnotations);
+        }
+
+        public ErrorType(Type originalType, TypeSymbol tsym,
+                         List<Attribute.TypeCompound> typeAnnotations) {
+            super(noType, List.<Type>nil(), null, typeAnnotations);
             this.tsym = tsym;
             this.originalType = (originalType == null ? noType : originalType);
         }
@@ -1772,6 +1960,11 @@
         }
 
         @Override
+        public ErrorType annotatedType(List<Attribute.TypeCompound> annos) {
+            return new ErrorType(originalType, tsym, annos);
+        }
+
+        @Override
         public TypeTag getTag() {
             return ERROR;
         }
@@ -1827,182 +2020,17 @@
         }
     }
 
-    public static class AnnotatedType extends Type
-            implements
-                javax.lang.model.type.ArrayType,
-                javax.lang.model.type.DeclaredType,
-                javax.lang.model.type.PrimitiveType,
-                javax.lang.model.type.TypeVariable,
-                javax.lang.model.type.WildcardType {
-        /** The type annotations on this type.
-         */
-        private List<Attribute.TypeCompound> typeAnnotations;
-
-        /** The underlying type that is annotated.
-         */
-        private Type underlyingType;
-
-        protected AnnotatedType(List<Attribute.TypeCompound> typeAnnotations,
-                Type underlyingType) {
-            super(underlyingType.tsym);
-            this.typeAnnotations = typeAnnotations;
-            this.underlyingType = underlyingType;
-            Assert.check(typeAnnotations != null && typeAnnotations.nonEmpty(),
-                    "Can't create AnnotatedType without annotations: " + underlyingType);
-            Assert.check(!underlyingType.isAnnotated(),
-                    "Can't annotate already annotated type: " + underlyingType +
-                    "; adding: " + typeAnnotations);
-        }
-
-        @Override
-        public TypeTag getTag() {
-            return underlyingType.getTag();
-        }
+    public static class UnknownType extends Type {
 
-        @Override
-        public boolean isAnnotated() {
-            return true;
-        }
-
-        @Override
-        public List<Attribute.TypeCompound> getAnnotationMirrors() {
-            return typeAnnotations;
-        }
-
-
-        @Override
-        public TypeKind getKind() {
-            return underlyingType.getKind();
-        }
-
-        @Override
-        public Type unannotatedType() {
-            return underlyingType;
-        }
-
-        @Override
-        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
-            return v.visitAnnotatedType(this, s);
-        }
-
-        @Override
-        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
-            return underlyingType.accept(v, p);
-        }
-
-        @Override
-        public Type map(Mapping f) {
-            underlyingType.map(f);
-            return this;
+        public UnknownType() {
+            // Unknown is a synthesized internal type, so it cannot be
+            // annotated.
+            super(null, noAnnotations);
         }
 
         @Override
-        public Type constType(Object constValue) { return underlyingType.constType(constValue); }
-        @Override
-        public Type getEnclosingType()           { return underlyingType.getEnclosingType(); }
-
-        @Override
-        public Type getReturnType()              { return underlyingType.getReturnType(); }
-        @Override
-        public List<Type> getTypeArguments()     { return underlyingType.getTypeArguments(); }
-        @Override
-        public List<Type> getParameterTypes()    { return underlyingType.getParameterTypes(); }
-        @Override
-        public Type getReceiverType()            { return underlyingType.getReceiverType(); }
-        @Override
-        public List<Type> getThrownTypes()       { return underlyingType.getThrownTypes(); }
-        @Override
-        public Type getUpperBound()              { return underlyingType.getUpperBound(); }
-        @Override
-        public Type getLowerBound()              { return underlyingType.getLowerBound(); }
-
-        @Override
-        public boolean isErroneous()             { return underlyingType.isErroneous(); }
-        @Override
-        public boolean isCompound()              { return underlyingType.isCompound(); }
-        @Override
-        public boolean isInterface()             { return underlyingType.isInterface(); }
-        @Override
-        public List<Type> allparams()            { return underlyingType.allparams(); }
-        @Override
-        public boolean isPrimitive()             { return underlyingType.isPrimitive(); }
-        @Override
-        public boolean isPrimitiveOrVoid()       { return underlyingType.isPrimitiveOrVoid(); }
-        @Override
-        public boolean isNumeric()               { return underlyingType.isNumeric(); }
-        @Override
-        public boolean isReference()             { return underlyingType.isReference(); }
-        @Override
-        public boolean isNullOrReference()       { return underlyingType.isNullOrReference(); }
-        @Override
-        public boolean isPartial()               { return underlyingType.isPartial(); }
-        @Override
-        public boolean isParameterized()         { return underlyingType.isParameterized(); }
-        @Override
-        public boolean isRaw()                   { return underlyingType.isRaw(); }
-        @Override
-        public boolean isFinal()                 { return underlyingType.isFinal(); }
-        @Override
-        public boolean isSuperBound()            { return underlyingType.isSuperBound(); }
-        @Override
-        public boolean isExtendsBound()          { return underlyingType.isExtendsBound(); }
-        @Override
-        public boolean isUnbound()               { return underlyingType.isUnbound(); }
-
-        @Override
-        public String toString() {
-            // This method is only used for internal debugging output.
-            // See
-            // com.sun.tools.javac.code.Printer.visitAnnotatedType(AnnotatedType, Locale)
-            // for the user-visible logic.
-            if (typeAnnotations != null &&
-                    !typeAnnotations.isEmpty()) {
-                return "(" + typeAnnotations.toString() + " :: " + underlyingType.toString() + ")";
-            } else {
-                return "({} :: " + underlyingType.toString() +")";
-            }
-        }
-
-        @Override
-        public boolean contains(Type t)          { return underlyingType.contains(t); }
-
-        @Override
-        public Type withTypeVar(Type t) {
-            // Don't create a new AnnotatedType, as 'this' will
-            // get its annotations set later.
-            underlyingType = underlyingType.withTypeVar(t);
-            return this;
-        }
-
-        // TODO: attach annotations?
-        @Override
-        public TypeSymbol asElement()            { return underlyingType.asElement(); }
-
-        // TODO: attach annotations?
-        @Override
-        public MethodType asMethodType()         { return underlyingType.asMethodType(); }
-
-        @Override
-        public void complete()                   { underlyingType.complete(); }
-
-        @Override
-        public TypeMirror getComponentType()     { return ((ArrayType)underlyingType).getComponentType(); }
-
-        // The result is an ArrayType, but only in the model sense, not the Type sense.
-        public Type makeVarargs() {
-            return ((ArrayType) underlyingType).makeVarargs().annotatedType(typeAnnotations);
-        }
-
-        @Override
-        public TypeMirror getExtendsBound()      { return ((WildcardType)underlyingType).getExtendsBound(); }
-        @Override
-        public TypeMirror getSuperBound()        { return ((WildcardType)underlyingType).getSuperBound(); }
-    }
-
-    public static class UnknownType extends Type {
-
-        public UnknownType() {
-            super(null);
+        public UnknownType annotatedType(List<Attribute.TypeCompound> annos) {
+            throw new AssertionError("Cannot annotate unknown type");
         }
 
         @Override
@@ -2046,7 +2074,6 @@
         R visitForAll(ForAll t, S s);
         R visitUndetVar(UndetVar t, S s);
         R visitErrorType(ErrorType t, S s);
-        R visitAnnotatedType(AnnotatedType t, S s);
         R visitType(Type t, S s);
     }
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Fri May 09 09:28:47 2014 -0400
@@ -326,15 +326,21 @@
 
     public int getCatchType() {
         Assert.check(hasCatchType(),
-                     "exception_index does not contain a valid catch type");
-        return (-this.exception_index) - 1 ;
+                     "exception_index does not contain valid catch info");
+        return ((-this.exception_index) - 1) & 0xff ;
     }
 
-    public void setCatchType(final int catchType) {
+    public int getStartPos() {
+        Assert.check(hasCatchType(),
+                     "exception_index does not contain valid catch info");
+        return ((-this.exception_index) - 1) >> 8 ;
+    }
+
+    public void setCatchInfo(final int catchType, final int startPos) {
         Assert.check(this.exception_index < 0,
                      "exception_index already contains a bytecode index");
         Assert.check(catchType >= 0, "Expected a valid catch type");
-        this.exception_index = -(catchType + 1);
+        this.exception_index = -((catchType | startPos << 8) + 1);
     }
 
     /**
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Fri May 09 09:28:47 2014 -0400
@@ -32,7 +32,6 @@
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.code.Attribute.TypeCompound;
-import com.sun.tools.javac.code.Type.AnnotatedType;
 import com.sun.tools.javac.code.Type.ArrayType;
 import com.sun.tools.javac.code.Type.CapturedType;
 import com.sun.tools.javac.code.Type.ClassType;
@@ -331,7 +330,6 @@
                 // Note that we don't use the result, the call to
                 // typeWithAnnotations side-effects the type annotation positions.
                 // This is important for constructors of nested classes.
-
                 sym.appendUniqueTypeAttributes(typeAnnotations);
                 return;
             }
@@ -391,14 +389,15 @@
         private Type typeWithAnnotations(final JCTree typetree, final Type type,
                 final List<Attribute.TypeCompound> annotations,
                 final List<Attribute.TypeCompound> onlyTypeAnnotations) {
-            // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s, onlyTypeAnnotations: %s)%n",
+            //System.err.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s, onlyTypeAnnotations: %s)%n",
             //         typetree, type, annotations, onlyTypeAnnotations);
             if (annotations.isEmpty()) {
                 return type;
             }
             if (type.hasTag(TypeTag.ARRAY)) {
-                Type.ArrayType arType = (Type.ArrayType) type.unannotatedType();
-                Type.ArrayType tomodify = new Type.ArrayType(null, arType.tsym);
+                Type.ArrayType arType = (Type.ArrayType) type;
+                Type.ArrayType tomodify = new Type.ArrayType(null, arType.tsym,
+                                                             Type.noAnnotations);
                 Type toreturn;
                 if (type.isAnnotated()) {
                     toreturn = tomodify.annotatedType(type.getAnnotationMirrors());
@@ -413,13 +412,15 @@
                 while (arType.elemtype.hasTag(TypeTag.ARRAY)) {
                     if (arType.elemtype.isAnnotated()) {
                         Type aelemtype = arType.elemtype;
-                        arType = (Type.ArrayType) aelemtype.unannotatedType();
+                        arType = (Type.ArrayType) aelemtype;
                         ArrayType prevToMod = tomodify;
-                        tomodify = new Type.ArrayType(null, arType.tsym);
+                        tomodify = new Type.ArrayType(null, arType.tsym,
+                                                      Type.noAnnotations);
                         prevToMod.elemtype = tomodify.annotatedType(arType.elemtype.getAnnotationMirrors());
                     } else {
                         arType = (Type.ArrayType) arType.elemtype;
-                        tomodify.elemtype = new Type.ArrayType(null, arType.tsym);
+                        tomodify.elemtype = new Type.ArrayType(null, arType.tsym,
+                                                               Type.noAnnotations);
                         tomodify = (Type.ArrayType) tomodify.elemtype;
                     }
                     arTree = arrayTypeTree(arTree.elemtype);
@@ -569,6 +570,7 @@
         private Type typeWithAnnotations(final Type type,
                 final Type stopAt,
                 final List<Attribute.TypeCompound> annotations) {
+            //System.err.println("typeWithAnnotations " + type + " " + annotations + " stopAt " + stopAt);
             Visitor<Type, List<TypeCompound>> visitor =
                     new Type.Visitor<Type, List<Attribute.TypeCompound>>() {
                 @Override
@@ -579,7 +581,8 @@
                         return t.annotatedType(s);
                     } else {
                         ClassType ret = new ClassType(t.getEnclosingType().accept(this, s),
-                                t.typarams_field, t.tsym);
+                                                      t.typarams_field, t.tsym,
+                                                      t.getAnnotationMirrors());
                         ret.all_interfaces_field = t.all_interfaces_field;
                         ret.allparams_field = t.allparams_field;
                         ret.interfaces_field = t.interfaces_field;
@@ -590,18 +593,14 @@
                 }
 
                 @Override
-                public Type visitAnnotatedType(AnnotatedType t, List<TypeCompound> s) {
-                    return t.unannotatedType().accept(this, s).annotatedType(t.getAnnotationMirrors());
-                }
-
-                @Override
                 public Type visitWildcardType(WildcardType t, List<TypeCompound> s) {
                     return t.annotatedType(s);
                 }
 
                 @Override
                 public Type visitArrayType(ArrayType t, List<TypeCompound> s) {
-                    ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym);
+                    ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym,
+                                                  t.getAnnotationMirrors());
                     return ret;
                 }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Fri May 09 09:28:47 2014 -0400
@@ -131,7 +131,7 @@
      * @return the upper bound of the given type
      */
     public Type upperBound(Type t) {
-        return upperBound.visit(t).unannotatedType();
+        return upperBound.visit(t);
     }
     // where
         private final MapVisitor<Void> upperBound = new MapVisitor<Void>() {
@@ -205,7 +205,7 @@
                     WildcardType unb = new WildcardType(syms.objectType,
                                                         BoundKind.UNBOUND,
                                                         syms.boundClass,
-                                                        (TypeVar)parms.head.unannotatedType());
+                                                        (TypeVar)parms.head);
                     if (!containsType(args.head, unb))
                         return false;
                     parms = parms.tail;
@@ -269,7 +269,9 @@
                         List<Type> opens = openVars.toList();
                         ListBuffer<Type> qs = new ListBuffer<>();
                         for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
-                            qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head.unannotatedType()));
+                            qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND,
+                                                       syms.boundClass, (TypeVar) iter.head,
+                                                       Type.noAnnotations));
                         }
                         res = subst(res, opens, qs.toList());
                     }
@@ -599,12 +601,12 @@
             //simply replace the wildcards with its bound
             for (Type t : formalInterface.getTypeArguments()) {
                 if (actualTypeargs.head.hasTag(WILDCARD)) {
-                    WildcardType wt = (WildcardType)actualTypeargs.head.unannotatedType();
+                    WildcardType wt = (WildcardType)actualTypeargs.head;
                     Type bound;
                     switch (wt.kind) {
                         case EXTENDS:
                         case UNBOUND:
-                            CapturedType capVar = (CapturedType)capturedTypeargs.head.unannotatedType();
+                            CapturedType capVar = (CapturedType)capturedTypeargs.head;
                             //use declared bound if it doesn't depend on formal type-args
                             bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ?
                                     wt.type : capVar.bound;
@@ -642,7 +644,8 @@
         csym.members_field = new Scope(csym);
         MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym);
         csym.members_field.enter(instDescSym);
-        Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym);
+        Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym,
+                                                  Type.noAnnotations);
         ctype.supertype_field = syms.objectType;
         ctype.interfaces_field = targets;
         csym.type = ctype;
@@ -747,8 +750,6 @@
     //where
         private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) {
             if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
-                t = t.unannotatedType();
-                s = s.unannotatedType();
                 if (((ArrayType)t).elemtype.isPrimitive()) {
                     return isSameType(elemtype(t), elemtype(s));
                 } else {
@@ -776,8 +777,6 @@
             if (!t.hasTag(ARRAY) || isReifiable(t)) {
                 return;
             }
-            t = t.unannotatedType();
-            s = s.unannotatedType();
             ArrayType from = (ArrayType)t;
             boolean shouldWarn = false;
             switch (s.getTag()) {
@@ -810,12 +809,6 @@
         if (t == s)
             return true;
 
-        t = t.unannotatedType();
-        s = s.unannotatedType();
-
-        if (t == s)
-            return true;
-
         if (s.isPartial())
             return isSuperType(s, t);
 
@@ -899,12 +892,14 @@
                     if (s.isSuperBound() && !s.isExtendsBound()) {
                         s = new WildcardType(syms.objectType,
                                              BoundKind.UNBOUND,
-                                             syms.boundClass);
+                                             syms.boundClass,
+                                             s.getAnnotationMirrors());
                         changed = true;
                     } else if (s != orig) {
                         s = new WildcardType(upperBound(s),
                                              BoundKind.EXTENDS,
-                                             syms.boundClass);
+                                             syms.boundClass,
+                                             s.getAnnotationMirrors());
                         changed = true;
                     }
                     rewrite.append(s);
@@ -1107,7 +1102,7 @@
                     if (s.hasTag(TYPEVAR)) {
                         //type-substitution does not preserve type-var types
                         //check that type var symbols and bounds are indeed the same
-                        return sameTypeVars((TypeVar)t.unannotatedType(), (TypeVar)s.unannotatedType());
+                        return sameTypeVars((TypeVar)t, (TypeVar)s);
                     }
                     else {
                         //special case for s == ? super X, where upper(s) = u
@@ -1149,9 +1144,9 @@
 
                     HashSet<UniqueType> set = new HashSet<>();
                     for (Type x : interfaces(t))
-                        set.add(new UniqueType(x.unannotatedType(), Types.this));
+                        set.add(new UniqueType(x, Types.this));
                     for (Type x : interfaces(s)) {
-                        if (!set.remove(new UniqueType(x.unannotatedType(), Types.this)))
+                        if (!set.remove(new UniqueType(x, Types.this)))
                             return false;
                     }
                     return (set.isEmpty());
@@ -1256,30 +1251,47 @@
                 if (!s.hasTag(WILDCARD)) {
                     return false;
                 } else {
-                    WildcardType t2 = (WildcardType)s.unannotatedType();
+                    WildcardType t2 = (WildcardType)s;
                     return t.kind == t2.kind &&
                             isSameType(t.type, t2.type, true);
                 }
             }
         };
 
-        /**
-         * A version of LooseSameTypeVisitor that takes AnnotatedTypes
-         * into account.
-         */
-        TypeRelation isSameAnnotatedType = new LooseSameTypeVisitor() {
+    // </editor-fold>
+
+    TypeRelation isSameAnnotatedType = new LooseSameTypeVisitor() {
+            private Boolean compareAnnotations(Type t1, Type t2) {
+                List<Attribute.TypeCompound> annos1 = t1.getAnnotationMirrors();
+                List<Attribute.TypeCompound> annos2 = t2.getAnnotationMirrors();
+                return annos1.containsAll(annos2) && annos2.containsAll(annos1);
+            }
+
+            @Override
+            public Boolean visitType(Type t, Type s) {
+                return compareAnnotations(t, s) && super.visitType(t, s);
+            }
+
             @Override
-            public Boolean visitAnnotatedType(AnnotatedType t, Type s) {
-                if (!s.isAnnotated())
-                    return false;
-                if (!t.getAnnotationMirrors().containsAll(s.getAnnotationMirrors()))
-                    return false;
-                if (!s.getAnnotationMirrors().containsAll(t.getAnnotationMirrors()))
-                    return false;
-                return visit(t.unannotatedType(), s);
+            public Boolean visitWildcardType(WildcardType t, Type s) {
+                return compareAnnotations(t, s) && super.visitWildcardType(t, s);
+            }
+
+            @Override
+            public Boolean visitClassType(ClassType t, Type s) {
+                return compareAnnotations(t, s) && super.visitClassType(t, s);
+            }
+
+            @Override
+            public Boolean visitArrayType(ArrayType t, Type s) {
+                return compareAnnotations(t, s) && super.visitArrayType(t, s);
+            }
+
+            @Override
+            public Boolean visitForAll(ForAll t, Type s) {
+                return compareAnnotations(t, s) && super.visitForAll(t, s);
             }
         };
-    // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="Contains Type">
     public boolean containedBy(Type t, Type s) {
@@ -1287,7 +1299,7 @@
         case UNDETVAR:
             if (s.hasTag(WILDCARD)) {
                 UndetVar undetvar = (UndetVar)t;
-                WildcardType wt = (WildcardType)s.unannotatedType();
+                WildcardType wt = (WildcardType)s;
                 switch(wt.kind) {
                     case UNBOUND: //similar to ? extends Object
                     case EXTENDS: {
@@ -1354,7 +1366,7 @@
 
             private Type U(Type t) {
                 while (t.hasTag(WILDCARD)) {
-                    WildcardType w = (WildcardType)t.unannotatedType();
+                    WildcardType w = (WildcardType)t;
                     if (w.isSuperBound())
                         return w.bound == null ? syms.objectType : w.bound.bound;
                     else
@@ -1365,7 +1377,7 @@
 
             private Type L(Type t) {
                 while (t.hasTag(WILDCARD)) {
-                    WildcardType w = (WildcardType)t.unannotatedType();
+                    WildcardType w = (WildcardType)t;
                     if (w.isExtendsBound())
                         return syms.botType;
                     else
@@ -1424,15 +1436,15 @@
         };
 
     public boolean isCaptureOf(Type s, WildcardType t) {
-        if (!s.hasTag(TYPEVAR) || !((TypeVar)s.unannotatedType()).isCaptured())
+        if (!s.hasTag(TYPEVAR) || !((TypeVar)s).isCaptured())
             return false;
-        return isSameWildcard(t, ((CapturedType)s.unannotatedType()).wildcard);
+        return isSameWildcard(t, ((CapturedType)s).wildcard);
     }
 
     public boolean isSameWildcard(WildcardType t, Type s) {
         if (!s.hasTag(WILDCARD))
             return false;
-        WildcardType w = (WildcardType)s.unannotatedType();
+        WildcardType w = (WildcardType)s;
         return w.kind == t.kind && w.type == t.type;
     }
 
@@ -1541,8 +1553,8 @@
 
                 if (t.isCompound() || s.isCompound()) {
                     return !t.isCompound() ?
-                            visitIntersectionType((IntersectionClassType)s.unannotatedType(), t, true) :
-                            visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false);
+                            visitIntersectionType((IntersectionClassType)s, t, true) :
+                            visitIntersectionType((IntersectionClassType)t, s, false);
                 }
 
                 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
@@ -1873,7 +1885,6 @@
         case WILDCARD:
             return elemtype(upperBound(t));
         case ARRAY:
-            t = t.unannotatedType();
             return ((ArrayType)t).elemtype;
         case FORALL:
             return elemtype(((ForAll)t).qtype);
@@ -1920,7 +1931,7 @@
         if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
             Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
         }
-        return new ArrayType(t, syms.arrayClass);
+        return new ArrayType(t, syms.arrayClass, Type.noAnnotations);
     }
     // </editor-fold>
 
@@ -2175,56 +2186,65 @@
     }
 
     private Type erasure(Type t, boolean recurse) {
-        if (t.isPrimitive())
+        if (t.isPrimitive()) {
             return t; /* fast special case */
-        else
-            return erasure.visit(t, recurse);
+        } else {
+            Type out = erasure.visit(t, recurse);
+            return out;
+        }
         }
     // where
         private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
             public Type visitType(Type t, Boolean recurse) {
                 if (t.isPrimitive())
                     return t; /*fast special case*/
-                else
-                    return t.map(recurse ? erasureRecFun : erasureFun);
+                else {
+                    final List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
+                    Type erased = t.map(recurse ? erasureRecFun : erasureFun);
+                    if (!annos.isEmpty()) {
+                        erased = erased.annotatedType(annos);
+                    }
+                    return erased;
+                }
             }
 
             @Override
             public Type visitWildcardType(WildcardType t, Boolean recurse) {
-                return erasure(upperBound(t), recurse);
+                final List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
+                Type erased = erasure(upperBound(t), recurse);
+                if (!annos.isEmpty()) {
+                    erased = erased.annotatedType(annos);
+                }
+                return erased;
             }
 
             @Override
             public Type visitClassType(ClassType t, Boolean recurse) {
                 Type erased = t.tsym.erasure(Types.this);
+                List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
                 if (recurse) {
                     erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym);
                 }
+                if (!annos.isEmpty()) {
+                    erased = erased.annotatedType(annos);
+                }
                 return erased;
             }
 
             @Override
             public Type visitTypeVar(TypeVar t, Boolean recurse) {
-                return erasure(t.bound, recurse);
+                final List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
+                Type erased = erasure(t.bound, recurse);
+                if (!annos.isEmpty()) {
+                    erased = erased.annotatedType(annos);
+                }
+                return erased;
             }
 
             @Override
             public Type visitErrorType(ErrorType t, Boolean recurse) {
                 return t;
             }
-
-            @Override
-            public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) {
-                Type erased = erasure(t.unannotatedType(), recurse);
-                if (erased.isAnnotated()) {
-                    // This can only happen when the underlying type is a
-                    // type variable and the upper bound of it is annotated.
-                    // The annotation on the type variable overrides the one
-                    // on the bound.
-                    erased = ((AnnotatedType)erased).unannotatedType();
-                }
-                return erased.annotatedType(t.getAnnotationMirrors());
-            }
         };
 
     private Mapping erasureFun = new Mapping ("erasure") {
@@ -2550,7 +2570,8 @@
             public Type visitClassType(ClassType t, Void ignored) {
                 Type outer1 = classBound(t.getEnclosingType());
                 if (outer1 != t.getEnclosingType())
-                    return new ClassType(outer1, t.getTypeArguments(), t.tsym);
+                    return new ClassType(outer1, t.getTypeArguments(), t.tsym,
+                                         t.getAnnotationMirrors());
                 else
                     return t;
             }
@@ -2965,7 +2986,8 @@
                 if (typarams1 == typarams && outer1 == outer)
                     return t;
                 else
-                    return new ClassType(outer1, typarams1, t.tsym);
+                    return new ClassType(outer1, typarams1, t.tsym,
+                                         t.getAnnotationMirrors());
             } else {
                 Type st = subst(supertype(t));
                 List<Type> is = upperBounds(subst(interfaces(t)));
@@ -2986,7 +3008,8 @@
             } else {
                 if (t.isExtendsBound() && bound.isExtendsBound())
                     bound = upperBound(bound);
-                return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
+                return new WildcardType(bound, t.kind, syms.boundClass,
+                                        t.bound, t.getAnnotationMirrors());
             }
         }
 
@@ -2996,7 +3019,7 @@
             if (elemtype == t.elemtype)
                 return t;
             else
-                return new ArrayType(elemtype, t.tsym);
+                return new ArrayType(elemtype, t.tsym, t.getAnnotationMirrors());
         }
 
         @Override
@@ -3006,7 +3029,7 @@
                 //if 'to' types contain variables that are free in 't'
                 List<Type> freevars = newInstances(t.tvars);
                 t = new ForAll(freevars,
-                        Types.this.subst(t.qtype, t.tvars, freevars));
+                               Types.this.subst(t.qtype, t.tvars, freevars));
             }
             List<Type> tvars1 = substBounds(t.tvars, from, to);
             Type qtype1 = subst(t.qtype);
@@ -3015,7 +3038,8 @@
             } else if (tvars1 == t.tvars) {
                 return new ForAll(tvars1, qtype1);
             } else {
-                return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
+                return new ForAll(tvars1,
+                                  Types.this.subst(qtype1, t.tvars, tvars1));
             }
         }
 
@@ -3045,7 +3069,8 @@
         ListBuffer<Type> newTvars = new ListBuffer<>();
         // create new type variables without bounds
         for (Type t : tvars) {
-            newTvars.append(new TypeVar(t.tsym, null, syms.botType));
+            newTvars.append(new TypeVar(t.tsym, null, syms.botType,
+                                        t.getAnnotationMirrors()));
         }
         // the new bounds should use the new type variables in place
         // of the old
@@ -3071,7 +3096,8 @@
             return t;
         else {
             // create new type variable without bounds
-            TypeVar tv = new TypeVar(t.tsym, null, syms.botType);
+            TypeVar tv = new TypeVar(t.tsym, null, syms.botType,
+                                     t.getAnnotationMirrors());
             // the new bound should use the new type variable in place
             // of the old
             tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv));
@@ -3112,7 +3138,7 @@
         return tvars1;
     }
     private static final Mapping newInstanceFun = new Mapping("newInstanceFun") {
-            public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
+            public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getAnnotationMirrors()); }
         };
     // </editor-fold>
 
@@ -3185,7 +3211,6 @@
      * graph. Undefined for all but reference types.
      */
     public int rank(Type t) {
-        t = t.unannotatedType();
         switch(t.getTag()) {
         case CLASS: {
             ClassType cls = (ClassType)t;
@@ -3267,7 +3292,7 @@
             for (Type t : tvars) {
                 if (!first) s.append(", ");
                 first = false;
-                appendTyparamString(((TypeVar)t.unannotatedType()), s);
+                appendTyparamString(((TypeVar)t), s);
             }
             s.append('>');
             return s.toString();
@@ -3439,12 +3464,14 @@
                         m = new WildcardType(lub(upperBound(act1.head),
                                                  upperBound(act2.head)),
                                              BoundKind.EXTENDS,
-                                             syms.boundClass);
+                                             syms.boundClass,
+                                             Type.noAnnotations);
                         mergeCache.remove(pair);
                     } else {
                         m = new WildcardType(syms.objectType,
                                              BoundKind.UNBOUND,
-                                             syms.boundClass);
+                                             syms.boundClass,
+                                             Type.noAnnotations);
                     }
                     merged.append(m.withTypeVar(typarams.head));
                 }
@@ -3453,7 +3480,10 @@
                 typarams = typarams.tail;
             }
             Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
-            return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
+            // There is no spec detailing how type annotations are to
+            // be inherited.  So set it to noAnnotations for now
+            return new ClassType(class1.getEnclosingType(), merged.toList(),
+                                 class1.tsym, Type.noAnnotations);
         }
 
     /**
@@ -3571,7 +3601,8 @@
                 }
             }
             // lub(A[], B[]) is lub(A, B)[]
-            return new ArrayType(lub(elements), syms.arrayClass);
+            return new ArrayType(lub(elements), syms.arrayClass,
+                                 Type.noAnnotations);
 
         case CLASS_BOUND:
             // calculate lub(A, B)
@@ -3932,7 +3963,6 @@
                 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments());
             }
         }
-        t = t.unannotatedType();
         ClassType cls = (ClassType)t;
         if (cls.isRaw() || !cls.isParameterized())
             return cls;
@@ -3951,9 +3981,9 @@
                !currentS.isEmpty()) {
             if (currentS.head != currentT.head) {
                 captured = true;
-                WildcardType Ti = (WildcardType)currentT.head.unannotatedType();
+                WildcardType Ti = (WildcardType)currentT.head;
                 Type Ui = currentA.head.getUpperBound();
-                CapturedType Si = (CapturedType)currentS.head.unannotatedType();
+                CapturedType Si = (CapturedType)currentS.head;
                 if (Ui == null)
                     Ui = syms.objectType;
                 switch (Ti.kind) {
@@ -3986,7 +4016,8 @@
             return erasure(t); // some "rare" type involved
 
         if (captured)
-            return new ClassType(cls.getEnclosingType(), S, cls.tsym);
+            return new ClassType(cls.getEnclosingType(), S, cls.tsym,
+                                 cls.getAnnotationMirrors());
         else
             return t;
     }
@@ -3995,7 +4026,6 @@
             ListBuffer<Type> result = new ListBuffer<>();
             for (Type t : types) {
                 if (t.hasTag(WILDCARD)) {
-                    t = t.unannotatedType();
                     Type bound = ((WildcardType)t).getExtendsBound();
                     if (bound == null)
                         bound = syms.objectType;
@@ -4003,7 +4033,8 @@
                                                    syms.noSymbol,
                                                    bound,
                                                    syms.botType,
-                                                   (WildcardType)t));
+                                                   (WildcardType)t,
+                                                   Type.noAnnotations));
                 } else {
                     result.append(t);
                 }
@@ -4089,7 +4120,7 @@
 
     private boolean giveWarning(Type from, Type to) {
         List<Type> bounds = to.isCompound() ?
-                ((IntersectionClassType)to.unannotatedType()).getComponents() : List.of(to);
+                ((IntersectionClassType)to).getComponents() : List.of(to);
         for (Type b : bounds) {
             Type subFrom = asSub(from, b.tsym);
             if (b.isParameterized() &&
@@ -4354,7 +4385,7 @@
 
         Type B(Type t) {
             while (t.hasTag(WILDCARD)) {
-                WildcardType w = (WildcardType)t.unannotatedType();
+                WildcardType w = (WildcardType)t;
                 t = high ?
                     w.getExtendsBound() :
                     w.getSuperBound();
@@ -4380,12 +4411,14 @@
             return new WildcardType(syms.objectType,
                                     BoundKind.UNBOUND,
                                     syms.boundClass,
-                                    formal);
+                                    formal,
+                                    Type.noAnnotations);
         } else {
             return new WildcardType(bound,
                                     BoundKind.EXTENDS,
                                     syms.boundClass,
-                                    formal);
+                                    formal,
+                                    Type.noAnnotations);
         }
     }
 
@@ -4402,12 +4435,14 @@
             return new WildcardType(syms.objectType,
                                     BoundKind.UNBOUND,
                                     syms.boundClass,
-                                    formal);
+                                    formal,
+                                    Type.noAnnotations);
         } else {
             return new WildcardType(bound,
                                     BoundKind.SUPER,
                                     syms.boundClass,
-                                    formal);
+                                    formal,
+                                    Type.noAnnotations);
         }
     }
 
@@ -4429,7 +4464,7 @@
 
         public boolean equals(Object obj) {
             return (obj instanceof UniqueType) &&
-                types.isSameAnnotatedType(type, ((UniqueType)obj).type);
+                types.isSameType(type, ((UniqueType)obj).type);
         }
 
         public String toString() {
@@ -4464,8 +4499,6 @@
         public R visitForAll(ForAll t, S s)             { return visitType(t, s); }
         public R visitUndetVar(UndetVar t, S s)         { return visitType(t, s); }
         public R visitErrorType(ErrorType t, S s)       { return visitType(t, s); }
-        // Pretend annotations don't exist
-        public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.unannotatedType(), s); }
     }
 
     /**
@@ -4596,7 +4629,6 @@
          * Assemble signature of given type in string buffer.
          */
         public void assembleSig(Type type) {
-            type = type.unannotatedType();
             switch (type.getTag()) {
                 case BYTE:
                     append('B');
@@ -4693,7 +4725,6 @@
         }
 
         public void assembleClassSig(Type type) {
-            type = type.unannotatedType();
             ClassType ct = (ClassType) type;
             ClassSymbol c = (ClassSymbol) ct.tsym;
             classReference(c);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri May 09 09:28:47 2014 -0400
@@ -1865,8 +1865,10 @@
                 return new ClassType(restype.getEnclosingType(),
                               List.<Type>of(new WildcardType(types.erasure(qualifierType),
                                                                BoundKind.EXTENDS,
-                                                               syms.boundClass)),
-                              restype.tsym);
+                                                             syms.boundClass,
+                                                             Type.noAnnotations)),
+                                     restype.tsym,
+                                     restype.getAnnotationMirrors());
             } else {
                 return restype;
             }
@@ -2036,7 +2038,8 @@
             } else if (TreeInfo.isDiamond(tree)) {
                 ClassType site = new ClassType(clazztype.getEnclosingType(),
                             clazztype.tsym.type.getTypeArguments(),
-                            clazztype.tsym);
+                                               clazztype.tsym,
+                                               clazztype.getAnnotationMirrors());
 
                 Env<AttrContext> diamondEnv = localEnv.dup(tree);
                 diamondEnv.info.selectSuper = cdef != null;
@@ -2255,7 +2258,8 @@
             owntype = elemtype;
             for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
                 attribExpr(l.head, localEnv, syms.intType);
-                owntype = new ArrayType(owntype, syms.arrayClass);
+                owntype = new ArrayType(owntype, syms.arrayClass,
+                                        Type.noAnnotations);
             }
         } else {
             // we are seeing an untyped aggregate { ... }
@@ -2272,7 +2276,8 @@
         }
         if (tree.elems != null) {
             attribExprs(tree.elems, localEnv, elemtype);
-            owntype = new ArrayType(elemtype, syms.arrayClass);
+            owntype = new ArrayType(elemtype, syms.arrayClass,
+                                    Type.noAnnotations);
         }
         if (!types.isReifiable(elemtype))
             log.error(tree.pos(), "generic.array.creation");
@@ -3244,7 +3249,7 @@
         if (skind == TYP) {
             Type elt = site;
             while (elt.hasTag(ARRAY))
-                elt = ((ArrayType)elt.unannotatedType()).elemtype;
+                elt = ((ArrayType)elt).elemtype;
             if (elt.hasTag(TYPEVAR)) {
                 log.error(tree.pos(), "type.var.cant.be.deref");
                 result = types.createErrorType(tree.type);
@@ -3557,7 +3562,8 @@
                             normOuter = types.erasure(ownOuter);
                         if (normOuter != ownOuter)
                             owntype = new ClassType(
-                                normOuter, List.<Type>nil(), owntype.tsym);
+                                normOuter, List.<Type>nil(), owntype.tsym,
+                                owntype.getAnnotationMirrors());
                     }
                 }
                 break;
@@ -3861,7 +3867,7 @@
 
     public void visitTypeArray(JCArrayTypeTree tree) {
         Type etype = attribType(tree.elemtype, env);
-        Type type = new ArrayType(etype, syms.arrayClass);
+        Type type = new ArrayType(etype, syms.arrayClass, Type.noAnnotations);
         result = check(tree, type, TYP, resultInfo);
     }
 
@@ -3909,7 +3915,8 @@
                         clazzOuter = site;
                     }
                 }
-                owntype = new ClassType(clazzOuter, actuals, clazztype.tsym);
+                owntype = new ClassType(clazzOuter, actuals, clazztype.tsym,
+                                        clazztype.getAnnotationMirrors());
             } else {
                 if (formals.length() != 0) {
                     log.error(tree.pos(), "wrong.number.type.args",
@@ -4060,7 +4067,8 @@
             : attribType(tree.inner, env);
         result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type),
                                               tree.kind.kind,
-                                              syms.boundClass),
+                                              syms.boundClass,
+                                              Type.noAnnotations),
                        TYP, resultInfo);
     }
 
@@ -4088,7 +4096,7 @@
             public void run() {
                 List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
                 Assert.check(annotations.size() == compounds.size());
-                    tree.type = tree.type.unannotatedType().annotatedType(compounds);
+                tree.type = tree.type.annotatedType(compounds);
                 }
         });
     }
@@ -4470,6 +4478,7 @@
             }
         }
         public void visitVarDef(final JCVariableDecl tree) {
+            //System.err.println("validateTypeAnnotations.visitVarDef " + tree);
             if (tree.sym != null && tree.sym.type != null)
                 validateAnnotatedType(tree.vartype, tree.sym.type);
             scan(tree.mods);
@@ -4512,6 +4521,7 @@
             super.visitNewArray(tree);
         }
         public void visitClassDef(JCClassDecl tree) {
+            //System.err.println("validateTypeAnnotations.visitClassDef " + tree);
             if (sigOnly) {
                 scan(tree.mods);
                 scan(tree.typarams);
@@ -4540,7 +4550,7 @@
          * can occur.
          */
         private void validateAnnotatedType(final JCTree errtree, final Type type) {
-            // System.out.println("Attr.validateAnnotatedType: " + errtree + " type: " + type);
+            //System.err.println("Attr.validateAnnotatedType: " + errtree + " type: " + type);
 
             if (type.isPrimitiveOrVoid()) {
                 return;
@@ -4578,8 +4588,7 @@
                     }
                 } else if (enclTr.hasTag(ANNOTATED_TYPE)) {
                     JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr;
-                    if (enclTy == null ||
-                            enclTy.hasTag(NONE)) {
+                    if (enclTy == null || enclTy.hasTag(NONE)) {
                         if (at.getAnnotations().size() == 1) {
                             log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute);
                         } else {
@@ -4598,16 +4607,16 @@
                 } else if (enclTr.hasTag(JCTree.Tag.WILDCARD)) {
                     JCWildcard wc = (JCWildcard) enclTr;
                     if (wc.getKind() == JCTree.Kind.EXTENDS_WILDCARD) {
-                        validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy.unannotatedType()).getExtendsBound());
+                        validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getExtendsBound());
                     } else if (wc.getKind() == JCTree.Kind.SUPER_WILDCARD) {
-                        validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy.unannotatedType()).getSuperBound());
+                        validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getSuperBound());
                     } else {
                         // Nothing to do for UNBOUND
                     }
                     repeat = false;
                 } else if (enclTr.hasTag(TYPEARRAY)) {
                     JCArrayTypeTree art = (JCArrayTypeTree) enclTr;
-                    validateAnnotatedType(art.getType(), ((ArrayType)enclTy.unannotatedType()).getComponentType());
+                    validateAnnotatedType(art.getType(), ((ArrayType)enclTy).getComponentType());
                     repeat = false;
                 } else if (enclTr.hasTag(TYPEUNION)) {
                     JCTypeUnion ut = (JCTypeUnion) enclTr;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri May 09 09:28:47 2014 -0400
@@ -2234,11 +2234,11 @@
         if  (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0)
             return;
         if (seen.contains(t)) {
-            tv = (TypeVar)t.unannotatedType();
+            tv = (TypeVar)t;
             tv.bound = types.createErrorType(t);
             log.error(pos, "cyclic.inheritance", t);
         } else if (t.hasTag(TYPEVAR)) {
-            tv = (TypeVar)t.unannotatedType();
+            tv = (TypeVar)t;
             seen = seen.prepend(tv);
             for (Type b : types.getBounds(tv))
                 checkNonCyclic1(pos, b, seen);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Fri May 09 09:28:47 2014 -0400
@@ -134,13 +134,18 @@
         SpeculativeCache speculativeCache;
 
         DeferredType(JCExpression tree, Env<AttrContext> env) {
-            super(null);
+            super(null, noAnnotations);
             this.tree = tree;
             this.env = attr.copyEnv(env);
             this.speculativeCache = new SpeculativeCache();
         }
 
         @Override
+        public DeferredType annotatedType(List<Attribute.TypeCompound> typeAnnotations) {
+            throw new AssertionError("Cannot annotate a deferred type");
+        }
+
+        @Override
         public TypeTag getTag() {
             return DEFERRED;
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri May 09 09:28:47 2014 -0400
@@ -373,7 +373,7 @@
             List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER);
             if (Type.containsAny(upperBounds, vars)) {
                 TypeSymbol fresh_tvar = new TypeVariableSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
-                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null);
+                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null, Type.noAnnotations);
                 todo.append(uv);
                 uv.inst = fresh_tvar.type;
             } else if (upperBounds.nonEmpty()) {
@@ -1505,7 +1505,9 @@
                         LOWER.solve(uv, inferenceContext) :
                         infer.syms.botType;
                 CapturedType prevCaptured = (CapturedType)uv.qtype;
-                return new CapturedType(prevCaptured.tsym.name, prevCaptured.tsym.owner, upper, lower, prevCaptured.wildcard);
+                return new CapturedType(prevCaptured.tsym.name, prevCaptured.tsym.owner,
+                                        upper, lower, prevCaptured.wildcard,
+                                        Type.noAnnotations);
             }
         };
 
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Fri May 09 09:28:47 2014 -0400
@@ -28,7 +28,6 @@
 import java.util.*;
 
 import com.sun.tools.javac.code.*;
-import com.sun.tools.javac.code.Type.AnnotatedType;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.main.Option.PkgInfo;
 import com.sun.tools.javac.tree.*;
@@ -452,7 +451,8 @@
             ClassSymbol outerCacheClass = outerCacheClass();
             this.mapVar = new VarSymbol(STATIC | SYNTHETIC | FINAL,
                                         varName,
-                                        new ArrayType(syms.intType, syms.arrayClass),
+                                        new ArrayType(syms.intType, syms.arrayClass,
+                                                      Type.noAnnotations),
                                         outerCacheClass);
             enterSynthetic(pos, mapVar, outerCacheClass.members());
         }
@@ -493,7 +493,8 @@
                         syms.lengthVar);
             JCExpression mapVarInit = make
                 .NewArray(make.Type(syms.intType), List.of(size), null)
-                .setType(new ArrayType(syms.intType, syms.arrayClass));
+                .setType(new ArrayType(syms.intType, syms.arrayClass,
+                                       Type.noAnnotations));
 
             // try { $SwitchMap$Color[red.ordinal()] = 1; } catch (java.lang.NoSuchFieldError ex) {}
             ListBuffer<JCStatement> stmts = new ListBuffer<>();
@@ -1979,7 +1980,7 @@
                          List.<JCExpression>of(make.Literal(INT, 0).setType(syms.intType)),
                          null);
             newcache.type = new ArrayType(types.erasure(outerCacheClass.type),
-                                          syms.arrayClass);
+                                          syms.arrayClass, Type.noAnnotations);
 
             // forNameSym := java.lang.Class.forName(
             //     String s,boolean init,ClassLoader loader)
@@ -2568,7 +2569,8 @@
         Name valuesName = names.fromString(target.syntheticNameChar() + "VALUES");
         while (tree.sym.members().lookup(valuesName).scope != null) // avoid name clash
             valuesName = names.fromString(valuesName + "" + target.syntheticNameChar());
-        Type arrayType = new ArrayType(types.erasure(tree.type), syms.arrayClass);
+        Type arrayType = new ArrayType(types.erasure(tree.type),
+                                       syms.arrayClass, Type.noAnnotations);
         VarSymbol valuesVar = new VarSymbol(PRIVATE|FINAL|STATIC|SYNTHETIC,
                                             valuesName,
                                             arrayType,
@@ -2841,7 +2843,7 @@
         tree.underlyingType = translate(tree.underlyingType);
         // but maintain type annotations in the type.
         if (tree.type.isAnnotated()) {
-            tree.type = tree.underlyingType.type.unannotatedType().annotatedType(tree.type.getAnnotationMirrors());
+            tree.type = tree.underlyingType.type.annotatedType(tree.type.getAnnotationMirrors());
         } else if (tree.underlyingType.type.isAnnotated()) {
             tree.type = tree.underlyingType.type;
         }
@@ -3145,7 +3147,8 @@
             JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
                                                List.<JCExpression>nil(),
                                                elems.toList());
-            boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
+            boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass,
+                                           Type.noAnnotations);
             result.append(boxedArgs);
         } else {
             if (args.length() != 1) throw new AssertionError(args);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri May 09 09:28:47 2014 -0400
@@ -457,7 +457,8 @@
      *  to the symbol table.
      */
     private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) {
-        JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass));
+        JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass,
+                                                          Type.noAnnotations));
 
         // public static T[] values() { return ???; }
         JCMethodDecl values = make.
@@ -677,7 +678,7 @@
                 //because varargs is represented in the tree as a
                 //modifier on the parameter declaration, and not as a
                 //distinct type of array node.
-                ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType();
+                ArrayType atype = (ArrayType)tree.vartype.type;
                 tree.vartype.type = atype.makeVarargs();
             }
             Scope enclScope = enter.enterScope(env);
@@ -1255,11 +1256,13 @@
             ClassType ct = (ClassType) sym.type;
             Assert.check(ct.typarams_field.isEmpty());
             if (n == 1) {
-                TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType);
+                TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType,
+                                        Type.noAnnotations);
                 ct.typarams_field = ct.typarams_field.prepend(v);
             } else {
                 for (int i = n; i > 0; i--) {
-                    TypeVar v = new TypeVar(names.fromString("T" + i), sym, syms.botType);
+                    TypeVar v = new TypeVar(names.fromString("T" + i), sym,
+                                            syms.botType, Type.noAnnotations);
                     ct.typarams_field = ct.typarams_field.prepend(v);
                 }
             }
@@ -1310,8 +1313,8 @@
         }
         Type mType = new MethodType(argtypes, null, thrown, c);
         Type initType = typarams.nonEmpty() ?
-                new ForAll(typarams, mType) :
-                mType;
+            new ForAll(typarams, mType) :
+            mType;
         MethodSymbol init = new MethodSymbol(flags, names.init,
                 initType, c);
         init.params = createDefaultConstructorParams(make, baseInit, init,
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri May 09 09:28:47 2014 -0400
@@ -2639,7 +2639,7 @@
                             ((ForAll)sym.type).tvars :
                             List.<Type>nil();
                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
-                            types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
+                                                 types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
                     MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
                         @Override
                         public Symbol baseSymbol() {
@@ -3280,7 +3280,7 @@
                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
             if (site.isRaw()) {
-                this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym);
+                this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym, site.getAnnotationMirrors());
                 needsInference = true;
             }
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri May 09 09:28:47 2014 -0400
@@ -624,18 +624,18 @@
         case '+': {
             sigp++;
             Type t = sigToType();
-            return new WildcardType(t, BoundKind.EXTENDS,
-                                    syms.boundClass);
+            return new WildcardType(t, BoundKind.EXTENDS, syms.boundClass,
+                                    Type.noAnnotations);
         }
         case '*':
             sigp++;
             return new WildcardType(syms.objectType, BoundKind.UNBOUND,
-                                    syms.boundClass);
+                                    syms.boundClass, Type.noAnnotations);
         case '-': {
             sigp++;
             Type t = sigToType();
-            return new WildcardType(t, BoundKind.SUPER,
-                                    syms.boundClass);
+            return new WildcardType(t, BoundKind.SUPER, syms.boundClass,
+                                    Type.noAnnotations);
         }
         case 'B':
             sigp++;
@@ -680,7 +680,8 @@
             return syms.booleanType;
         case '[':
             sigp++;
-            return new ArrayType(sigToType(), syms.arrayClass);
+            return new ArrayType(sigToType(), syms.arrayClass,
+                                 Type.noAnnotations);
         case '(':
             sigp++;
             List<Type> argtypes = sigToTypes(')');
@@ -735,7 +736,8 @@
                 try {
                     return (outer == Type.noType) ?
                             t.erasure(types) :
-                            new ClassType(outer, List.<Type>nil(), t);
+                        new ClassType(outer, List.<Type>nil(), t,
+                                      Type.noAnnotations);
                 } finally {
                     sbp = startSbp;
                 }
@@ -745,7 +747,8 @@
                 ClassSymbol t = syms.enterClass(names.fromUtf(signatureBuffer,
                                                          startSbp,
                                                          sbp - startSbp));
-                outer = new ClassType(outer, sigToTypes('>'), t) {
+                outer = new ClassType(outer, sigToTypes('>'), t,
+                                      Type.noAnnotations) {
                         boolean completed = false;
                         @Override
                         public Type getEnclosingType() {
@@ -808,7 +811,8 @@
                     t = syms.enterClass(names.fromUtf(signatureBuffer,
                                                  startSbp,
                                                  sbp - startSbp));
-                    outer = new ClassType(outer, List.<Type>nil(), t);
+                    outer = new ClassType(outer, List.<Type>nil(), t,
+                                          Type.noAnnotations);
                 }
                 signatureBuffer[sbp++] = (byte)'$';
                 continue;
@@ -871,7 +875,8 @@
         Name name = names.fromUtf(signature, start, sigp - start);
         TypeVar tvar;
         if (sigEnterPhase) {
-            tvar = new TypeVar(name, currentOwner, syms.botType);
+            tvar = new TypeVar(name, currentOwner, syms.botType,
+                               Type.noAnnotations);
             typevars.enter(tvar.tsym);
         } else {
             tvar = (TypeVar)findTypeVar(name);
@@ -910,7 +915,8 @@
                 // we don't know for sure if this owner is correct.  It could
                 // be a method and there is no way to tell before reading the
                 // enclosing method attribute.
-                TypeVar t = new TypeVar(name, currentOwner, syms.botType);
+                TypeVar t = new TypeVar(name, currentOwner, syms.botType,
+                                        Type.noAnnotations);
                 missingTypeVariables = missingTypeVariables.prepend(t);
                 // System.err.println("Missing type var " + name);
                 return t;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri May 09 09:28:47 2014 -0400
@@ -286,7 +286,6 @@
          */
         @Override
         public void assembleSig(Type type) {
-            type = type.unannotatedType();
             switch (type.getTag()) {
                 case UNINITIALIZED_THIS:
                 case UNINITIALIZED_OBJECT:
@@ -354,7 +353,7 @@
         } else if (t.hasTag(ARRAY)) {
             return typeSig(types.erasure(t));
         } else {
-            throw new AssertionError("xClassName");
+            throw new AssertionError("xClassName expects class or array type, got " + t);
         }
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java	Fri May 09 09:28:47 2014 -0400
@@ -928,7 +928,7 @@
         if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
         if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
         if (o instanceof Type) {
-            Type ty = ((Type)o).unannotatedType();
+            Type ty = (Type) o;
 
             if (ty instanceof Type.ArrayType) return syms.classType;
             if (ty instanceof Type.MethodType) return syms.methodTypeType;
@@ -1579,8 +1579,8 @@
 
     /** Add a catch clause to code.
      */
-    public void addCatch(
-        char startPc, char endPc, char handlerPc, char catchType) {
+    public void addCatch(char startPc, char endPc,
+                         char handlerPc, char catchType) {
             catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
         }
 
@@ -2149,7 +2149,7 @@
             for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
                 TypeAnnotationPosition p = ta.position;
                 if (p.hasCatchType()) {
-                    final int idx = findExceptionIndex(p.getCatchType());
+                    final int idx = findExceptionIndex(p);
                     if (idx == -1)
                         Assert.error("Could not find exception index for type annotation " +
                                      ta + " on exception parameter");
@@ -2159,14 +2159,17 @@
         }
     }
 
-    private int findExceptionIndex(int catchType) {
+    private int findExceptionIndex(TypeAnnotationPosition p) {
+        final int catchType = p.getCatchType();
+        final int startPos = p.getStartPos();
+        final int len = catchInfo.length();
         List<char[]> iter = catchInfo.toList();
-        int len = catchInfo.length();
         for (int i = 0; i < len; ++i) {
             char[] catchEntry = iter.head;
             iter = iter.tail;
-            char ct = catchEntry[3];
-            if (catchType == ct) {
+            int ct = catchEntry[3];
+            int sp = catchEntry[0];
+            if (catchType == ct && sp == startPos) {
                 return i;
             }
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri May 09 09:28:47 2014 -0400
@@ -317,10 +317,6 @@
     int makeRef(DiagnosticPosition pos, Type type) {
         checkDimension(pos, type);
         if (type.isAnnotated()) {
-            // Treat annotated types separately - we don't want
-            // to collapse all of them - at least for annotated
-            // exceptions.
-            // TODO: review this.
             return pool.put((Object)type);
         } else {
             return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
@@ -1647,7 +1643,7 @@
                         if (subCatch.type.isAnnotated()) {
                             for (Attribute.TypeCompound tc :
                                      subCatch.type.getAnnotationMirrors()) {
-                                tc.position.setCatchType(catchType);
+                                tc.position.setCatchInfo(catchType, startpc);
                             }
                         }
                     }
@@ -1664,7 +1660,7 @@
                         if (subCatch.type.isAnnotated()) {
                             for (Attribute.TypeCompound tc :
                                      subCatch.type.getAnnotationMirrors()) {
-                                tc.position.setCatchType(catchType);
+                                tc.position.setCatchInfo(catchType, startpc);
                             }
                         }
                     }
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Fri May 09 09:28:47 2014 -0400
@@ -674,11 +674,6 @@
         }
 
         @Override
-        public R visitAnnotatedType(Type.AnnotatedType t, P p) {
-            return defaultAction(t, p);
-        }
-
-        @Override
         public R visitType(Type t, P p) {
             return defaultAction(t, p);
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Fri May 09 09:28:47 2014 -0400
@@ -102,10 +102,11 @@
      */
     public int put(Object value) {
         value = makePoolValue(value);
-//      assert !(value instanceof Type.TypeVar);
+        Assert.check(!(value instanceof Type.TypeVar));
+        Assert.check(!(value instanceof Types.UniqueType &&
+                       ((UniqueType) value).type instanceof Type.TypeVar));
         Integer index = indices.get(value);
         if (index == null) {
-//          System.err.println("put " + value + " " + value.getClass());//DEBUG
             index = pp;
             indices.put(value, index);
             pool = ArrayUtils.ensureCapacity(pool, pp);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/UninitializedType.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/UninitializedType.java	Fri May 09 09:28:47 2014 -0400
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.jvm;
 
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.util.List;
 
 import static com.sun.tools.javac.code.TypeTag.UNINITIALIZED_OBJECT;
 import static com.sun.tools.javac.code.TypeTag.UNINITIALIZED_THIS;
@@ -41,19 +42,27 @@
 class UninitializedType extends Type.DelegatedType {
 
     public static UninitializedType uninitializedThis(Type qtype) {
-        return new UninitializedType(UNINITIALIZED_THIS, qtype, -1);
+        return new UninitializedType(UNINITIALIZED_THIS, qtype, -1,
+                                     qtype.getAnnotationMirrors());
     }
 
     public static UninitializedType uninitializedObject(Type qtype, int offset) {
-        return new UninitializedType(UNINITIALIZED_OBJECT, qtype, offset);
+        return new UninitializedType(UNINITIALIZED_OBJECT, qtype, offset,
+                                     qtype.getAnnotationMirrors());
     }
 
     public final int offset; // PC where allocation took place
-    private UninitializedType(TypeTag tag, Type qtype, int offset) {
-        super(tag, qtype);
+    private UninitializedType(TypeTag tag, Type qtype, int offset,
+                              List<Attribute.TypeCompound> typeAnnotations) {
+        super(tag, qtype, typeAnnotations);
         this.offset = offset;
     }
 
+    @Override
+    public UninitializedType annotatedType(List<Attribute.TypeCompound> typeAnnotations) {
+        return new UninitializedType(tag, qtype, offset, typeAnnotations);
+    }
+
     Type initializedType() {
         return qtype;
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Fri May 09 09:28:47 2014 -0400
@@ -168,7 +168,8 @@
         case PACKAGE:
             throw new IllegalArgumentException(componentType.toString());
         }
-        return new Type.ArrayType((Type) componentType, syms.arrayClass);
+        return new Type.ArrayType((Type) componentType, syms.arrayClass,
+                                  Type.noAnnotations);
     }
 
     public WildcardType getWildcardType(TypeMirror extendsBound,
@@ -193,7 +194,8 @@
         case DECLARED:
         case ERROR:
         case TYPEVAR:
-            return new Type.WildcardType(bound, bkind, syms.boundClass);
+            return new Type.WildcardType(bound, bkind, syms.boundClass,
+                                         Type.noAnnotations);
         default:
             throw new IllegalArgumentException(bound.toString());
         }
@@ -243,7 +245,8 @@
             }
             // TODO: Would like a way to check that type args match formals.
 
-            return (DeclaredType) new Type.ClassType(outer, targs.toList(), sym);
+            return (DeclaredType) new Type.ClassType(outer, targs.toList(), sym,
+                                                     Type.noAnnotations);
         }
 
     /**
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri May 09 09:28:47 2014 -0400
@@ -1089,7 +1089,8 @@
                 for (ClassSymbol cs : symtab.classes.values()) {
                     if (cs.classfile != null || cs.kind == Kinds.ERR) {
                         cs.reset();
-                        cs.type = new ClassType(cs.type.getEnclosingType(), null, cs);
+                        cs.type = new ClassType(cs.type.getEnclosingType(),
+                                                null, cs, Type.noAnnotations);
                         if (cs.completer == null) {
                             cs.completer = initialCompleter;
                         }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java	Fri May 09 09:28:47 2014 -0400
@@ -65,7 +65,7 @@
 
     @Override
     public com.sun.javadoc.Type underlyingType() {
-        return TypeMaker.getType(env, type.unannotatedType(), true, false);
+        return TypeMaker.getType(env, type, true, false);
     }
 
     @Override
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java	Fri May 09 09:28:47 2014 -0400
@@ -140,9 +140,6 @@
      */
     static String getTypeString(DocEnv env, Type t, boolean full) {
         // TODO: should annotations be included here?
-        if (t.isAnnotated()) {
-            t = t.unannotatedType();
-        }
         switch (t.getTag()) {
         case ARRAY:
             StringBuilder s = new StringBuilder();
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java	Fri May 09 09:28:47 2014 -0400
@@ -42,7 +42,7 @@
 
 public class Driver {
 
-    private static final PrintStream out = System.out;
+    private static final PrintStream out = System.err;
 
     public static void main(String[] args) throws Exception {
         if (args.length == 0 || args.length > 1)
--- a/langtools/test/tools/javac/types/TypeHarness.java	Fri May 09 08:52:57 2014 -0700
+++ b/langtools/test/tools/javac/types/TypeHarness.java	Fri May 09 09:28:47 2014 -0400
@@ -255,7 +255,8 @@
 
         public ClassType Class(long flags, Type... typeArgs) {
             ClassSymbol csym = new ClassSymbol(flags, syntheticName(), predef.noSymbol);
-            csym.type = new ClassType(Type.noType, List.from(typeArgs), csym);
+            csym.type = new ClassType(Type.noType, List.from(typeArgs), csym,
+                                      Type.noAnnotations);
             ((ClassType)csym.type).supertype_field = predef.objectType;
             return (ClassType)csym.type;
         }
@@ -301,7 +302,7 @@
         }
 
         public ArrayType Array(Type elemType) {
-            return new ArrayType(elemType, predef.arrayClass);
+            return new ArrayType(elemType, predef.arrayClass, Type.noAnnotations);
         }
 
         public TypeVar TypeVariable() {
@@ -310,16 +311,16 @@
 
         public TypeVar TypeVariable(Type bound) {
             TypeSymbol tvsym = new TypeVariableSymbol(0, syntheticName(), null, predef.noSymbol);
-            tvsym.type = new TypeVar(tvsym, bound, null);
+            tvsym.type = new TypeVar(tvsym, bound, null, Type.noAnnotations);
             return (TypeVar)tvsym.type;
         }
 
         public WildcardType Wildcard(BoundKind bk, Type bound) {
-            return new WildcardType(bound, bk, predef.boundClass);
+            return new WildcardType(bound, bk, predef.boundClass, Type.noAnnotations);
         }
 
         public CapturedType CapturedVariable(Type upper, Type lower) {
-            return new CapturedType(syntheticName(), predef.noSymbol, upper, lower, null);
+            return new CapturedType(syntheticName(), predef.noSymbol, upper, lower, null, Type.noAnnotations);
         }
 
         public ClassType Intersection(Type classBound, Type... intfBounds) {