7177387: Add target-typing support in method context

Thu, 04 Oct 2012 13:04:53 +0100

author
mcimadamore
date
Thu, 04 Oct 2012 13:04:53 +0100
changeset 1347
1408af4cd8b0
parent 1346
20e4a54b1629
child 1348
573ceb23beeb

7177387: Add target-typing support in method context
Summary: Add support for deferred types and speculative attribution
Reviewed-by: jjg, dlsmith

src/share/classes/com/sun/tools/javac/code/Printer.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Source.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Symtab.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Type.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/TypeTags.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Attr.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/AttrContext.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Check.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Infer.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Lower.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/MemberEnter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Resolve.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/main/JavaCompiler.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/resources/compiler.properties file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/tree/Pretty.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/tree/TreeInfo.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/List.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/Log.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java file | annotate | diff | comparison | revisions
test/tools/javac/conditional/Conditional.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples.not-yet.txt file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/IncompatibleTypesInConditional.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/TypeConditional.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Printer.java	Sat Sep 29 09:00:58 2012 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Printer.java	Thu Oct 04 13:04:53 2012 +0100
     1.3 @@ -30,6 +30,10 @@
     1.4  import com.sun.tools.javac.api.Messages;
     1.5  import com.sun.tools.javac.code.Type.*;
     1.6  import com.sun.tools.javac.code.Symbol.*;
     1.7 +import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
     1.8 +import com.sun.tools.javac.tree.JCTree;
     1.9 +import com.sun.tools.javac.tree.Pretty;
    1.10 +import com.sun.tools.javac.util.Assert;
    1.11  import com.sun.tools.javac.util.List;
    1.12  import com.sun.tools.javac.util.ListBuffer;
    1.13  
    1.14 @@ -50,6 +54,11 @@
    1.15  
    1.16      List<Type> seenCaptured = List.nil();
    1.17      static final int PRIME = 997;  // largest prime less than 1000
    1.18 +    boolean raw;
    1.19 +
    1.20 +    protected Printer(boolean raw) {
    1.21 +        this.raw = raw;
    1.22 +    }
    1.23  
    1.24      /**
    1.25       * This method should be overriden in order to provide proper i18n support.
    1.26 @@ -78,7 +87,7 @@
    1.27       * @return printer visitor instance
    1.28       */
    1.29      public static Printer createStandardPrinter(final Messages messages) {
    1.30 -        return new Printer() {
    1.31 +        return new Printer(false) {
    1.32              @Override
    1.33              protected String localize(Locale locale, String key, Object... args) {
    1.34                  return messages.getLocalizedString(locale, key, args);
    1.35 @@ -165,6 +174,34 @@
    1.36          return "<" + visitTypes(t.tvars, locale) + ">" + visit(t.qtype, locale);
    1.37      }
    1.38  
    1.39 +    public String visitDeferredType(DeferredType t, Locale locale) {
    1.40 +        return raw ? localize(locale, getDeferredKey(t.tree)) :
    1.41 +            deferredTypeTree2String(t.tree);
    1.42 +    }
    1.43 +    //where
    1.44 +        private String deferredTypeTree2String(JCTree tree) {
    1.45 +            switch(tree.getTag()) {
    1.46 +                case PARENS:
    1.47 +                    return deferredTypeTree2String(((JCTree.JCParens)tree).expr);
    1.48 +                case CONDEXPR:
    1.49 +                    return Pretty.toSimpleString(tree, 15);
    1.50 +                default:
    1.51 +                    Assert.error("unexpected tree kind " + tree.getKind());
    1.52 +                    return null;
    1.53 +            }
    1.54 +        }
    1.55 +        private String getDeferredKey (JCTree tree) {
    1.56 +            switch (tree.getTag()) {
    1.57 +                case PARENS:
    1.58 +                    return getDeferredKey(((JCTree.JCParens)tree).expr);
    1.59 +                case CONDEXPR:
    1.60 +                     return "compiler.misc.type.conditional";
    1.61 +                default:
    1.62 +                    Assert.error("unexpected tree kind " + tree.getKind());
    1.63 +                    return null;
    1.64 +            }
    1.65 +        }
    1.66 +
    1.67      @Override
    1.68      public String visitUndetVar(UndetVar t, Locale locale) {
    1.69          if (t.inst != null) {
    1.70 @@ -228,10 +265,14 @@
    1.71      }
    1.72  
    1.73      public String visitType(Type t, Locale locale) {
    1.74 -        String s = (t.tsym == null || t.tsym.name == null)
    1.75 -                ? localize(locale, "compiler.misc.type.none")
    1.76 -                : t.tsym.name.toString();
    1.77 -        return s;
    1.78 +        if (t.tag == DEFERRED) {
    1.79 +            return visitDeferredType((DeferredType)t, locale);
    1.80 +        } else {
    1.81 +            String s = (t.tsym == null || t.tsym.name == null)
    1.82 +                    ? localize(locale, "compiler.misc.type.none")
    1.83 +                    : t.tsym.name.toString();
    1.84 +            return s;
    1.85 +        }
    1.86      }
    1.87  
    1.88      /**
     2.1 --- a/src/share/classes/com/sun/tools/javac/code/Source.java	Sat Sep 29 09:00:58 2012 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Thu Oct 04 13:04:53 2012 +0100
     2.3 @@ -194,6 +194,9 @@
     2.4      public boolean allowObjectToPrimitiveCast() {
     2.5          return compareTo(JDK1_7) >= 0;
     2.6      }
     2.7 +    public boolean allowPoly() {
     2.8 +        return compareTo(JDK1_8) >= 0;
     2.9 +    }
    2.10      public boolean allowLambda() {
    2.11          return compareTo(JDK1_8) >= 0;
    2.12      }
     3.1 --- a/src/share/classes/com/sun/tools/javac/code/Symtab.java	Sat Sep 29 09:00:58 2012 -0700
     3.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Oct 04 13:04:53 2012 +0100
     3.3 @@ -183,6 +183,10 @@
     3.4       */
     3.5      public final Name[] boxedName = new Name[TypeTags.TypeTagCount];
     3.6  
     3.7 +    /** A set containing all operator names.
     3.8 +     */
     3.9 +    public final Set<Name> operatorNames = new HashSet<Name>();
    3.10 +
    3.11      /** A hashtable containing the encountered top-level and member classes,
    3.12       *  indexed by flat names. The table does not contain local classes.
    3.13       *  It should be updated from the outside to reflect classes defined
    3.14 @@ -244,7 +248,7 @@
    3.15                              int opcode) {
    3.16          predefClass.members().enter(
    3.17              new OperatorSymbol(
    3.18 -                names.fromString(name),
    3.19 +                makeOperatorName(name),
    3.20                  new MethodType(List.of(left, right), res,
    3.21                                 List.<Type>nil(), methodClass),
    3.22                  opcode,
    3.23 @@ -275,7 +279,7 @@
    3.24                                       Type res,
    3.25                                       int opcode) {
    3.26          OperatorSymbol sym =
    3.27 -            new OperatorSymbol(names.fromString(name),
    3.28 +            new OperatorSymbol(makeOperatorName(name),
    3.29                                 new MethodType(List.of(arg),
    3.30                                                res,
    3.31                                                List.<Type>nil(),
    3.32 @@ -286,6 +290,16 @@
    3.33          return sym;
    3.34      }
    3.35  
    3.36 +    /**
    3.37 +     * Create a new operator name from corresponding String representation
    3.38 +     * and add the name to the set of known operator names.
    3.39 +     */
    3.40 +    private Name makeOperatorName(String name) {
    3.41 +        Name opName = names.fromString(name);
    3.42 +        operatorNames.add(opName);
    3.43 +        return opName;
    3.44 +    }
    3.45 +
    3.46      /** Enter a class into symbol table.
    3.47       *  @param    The name of the class.
    3.48       */
     4.1 --- a/src/share/classes/com/sun/tools/javac/code/Type.java	Sat Sep 29 09:00:58 2012 -0700
     4.2 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Oct 04 13:04:53 2012 +0100
     4.3 @@ -75,6 +75,9 @@
     4.4      /** Constant type: no type at all. */
     4.5      public static final JCNoType noType = new JCNoType(NONE);
     4.6  
     4.7 +    /** Constant type: special type to be used during recovery of deferred expressions. */
     4.8 +    public static final JCNoType recoveryType = new JCNoType(NONE);
     4.9 +
    4.10      /** If this switch is turned on, the names of type variables
    4.11       *  and anonymous classes are printed with hashcodes appended.
    4.12       */
     5.1 --- a/src/share/classes/com/sun/tools/javac/code/TypeTags.java	Sat Sep 29 09:00:58 2012 -0700
     5.2 +++ b/src/share/classes/com/sun/tools/javac/code/TypeTags.java	Thu Oct 04 13:04:53 2012 +0100
     5.3 @@ -102,9 +102,13 @@
     5.4       */
     5.5      public static final int FORALL = WILDCARD+1;
     5.6  
     5.7 +    /** The tag of deferred expression types in method context
     5.8 +     */
     5.9 +    public static final int DEFERRED = FORALL+1;
    5.10 +
    5.11      /** The tag of the bottom type <null>.
    5.12       */
    5.13 -    public static final int BOT = FORALL+1;
    5.14 +    public static final int BOT = DEFERRED+1;
    5.15  
    5.16      /** The tag of a missing type.
    5.17       */
     6.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Sat Sep 29 09:00:58 2012 -0700
     6.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Oct 04 13:04:53 2012 +0100
     6.3 @@ -3154,6 +3154,14 @@
     6.4          }
     6.5          return Type.noType;
     6.6      }
     6.7 +
     6.8 +    /**
     6.9 +     * Return the unboxed type if 't' is a boxed class, otherwise return 't' itself.
    6.10 +     */
    6.11 +    public Type unboxedTypeOrType(Type t) {
    6.12 +        Type unboxedType = unboxedType(t);
    6.13 +        return unboxedType.tag == NONE ? t : unboxedType;
    6.14 +    }
    6.15      // </editor-fold>
    6.16  
    6.17      // <editor-fold defaultstate="collapsed" desc="Capture conversion">
     7.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Sat Sep 29 09:00:58 2012 -0700
     7.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 04 13:04:53 2012 +0100
     7.3 @@ -25,12 +25,10 @@
     7.4  
     7.5  package com.sun.tools.javac.comp;
     7.6  
     7.7 -import java.util.*;
     7.8 -import java.util.Set;
     7.9 -import javax.lang.model.element.ElementKind;
    7.10 -import javax.tools.JavaFileObject;
    7.11 -
    7.12  import com.sun.tools.javac.code.*;
    7.13 +import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
    7.14 +import com.sun.tools.javac.comp.Infer.InferenceContext;
    7.15 +import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
    7.16  import com.sun.tools.javac.jvm.*;
    7.17  import com.sun.tools.javac.tree.*;
    7.18  import com.sun.tools.javac.util.*;
    7.19 @@ -49,6 +47,11 @@
    7.20  import com.sun.source.tree.TreeVisitor;
    7.21  import com.sun.source.util.SimpleTreeVisitor;
    7.22  
    7.23 +import java.util.*;
    7.24 +import java.util.Set;
    7.25 +import javax.lang.model.element.ElementKind;
    7.26 +import javax.tools.JavaFileObject;
    7.27 +
    7.28  import static com.sun.tools.javac.code.Flags.*;
    7.29  import static com.sun.tools.javac.code.Flags.ANNOTATION;
    7.30  import static com.sun.tools.javac.code.Flags.BLOCK;
    7.31 @@ -80,6 +83,7 @@
    7.32      final Symtab syms;
    7.33      final Resolve rs;
    7.34      final Infer infer;
    7.35 +    final DeferredAttr deferredAttr;
    7.36      final Check chk;
    7.37      final MemberEnter memberEnter;
    7.38      final TreeMaker make;
    7.39 @@ -110,6 +114,7 @@
    7.40          make = TreeMaker.instance(context);
    7.41          enter = Enter.instance(context);
    7.42          infer = Infer.instance(context);
    7.43 +        deferredAttr = DeferredAttr.instance(context);
    7.44          cfolder = ConstFold.instance(context);
    7.45          target = Target.instance(context);
    7.46          types = Types.instance(context);
    7.47 @@ -127,6 +132,7 @@
    7.48          allowCovariantReturns = source.allowCovariantReturns();
    7.49          allowAnonOuterThis = source.allowAnonOuterThis();
    7.50          allowStringsInSwitch = source.allowStringsInSwitch();
    7.51 +        allowPoly = source.allowPoly() && options.isSet("allowPoly");
    7.52          sourceName = source.name;
    7.53          relax = (options.isSet("-retrofit") ||
    7.54                   options.isSet("-relax"));
    7.55 @@ -144,6 +150,10 @@
    7.56       */
    7.57      boolean relax;
    7.58  
    7.59 +    /** Switch: support target-typing inference
    7.60 +     */
    7.61 +    boolean allowPoly;
    7.62 +
    7.63      /** Switch: support generics?
    7.64       */
    7.65      boolean allowGenerics;
    7.66 @@ -207,15 +217,29 @@
    7.67       *  @param ownkind  The computed kind of the tree
    7.68       *  @param resultInfo  The expected result of the tree
    7.69       */
    7.70 -    Type check(JCTree tree, Type owntype, int ownkind, ResultInfo resultInfo) {
    7.71 +    Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) {
    7.72 +        InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
    7.73 +        Type owntype = found;
    7.74          if (owntype.tag != ERROR && resultInfo.pt.tag != METHOD && resultInfo.pt.tag != FORALL) {
    7.75 -            if ((ownkind & ~resultInfo.pkind) == 0) {
    7.76 -                owntype = resultInfo.check(tree, owntype);
    7.77 +            if (inferenceContext.free(found)) {
    7.78 +                inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
    7.79 +                    @Override
    7.80 +                    public void typesInferred(InferenceContext inferenceContext) {
    7.81 +                        ResultInfo pendingResult =
    7.82 +                                    resultInfo.dup(inferenceContext.asInstType(resultInfo.pt, types));
    7.83 +                        check(tree, inferenceContext.asInstType(found, types), ownkind, pendingResult);
    7.84 +                    }
    7.85 +                });
    7.86 +                return tree.type = resultInfo.pt;
    7.87              } else {
    7.88 -                log.error(tree.pos(), "unexpected.type",
    7.89 -                          kindNames(resultInfo.pkind),
    7.90 -                          kindName(ownkind));
    7.91 -                owntype = types.createErrorType(owntype);
    7.92 +                if ((ownkind & ~resultInfo.pkind) == 0) {
    7.93 +                    owntype = resultInfo.check(tree, owntype);
    7.94 +                } else {
    7.95 +                    log.error(tree.pos(), "unexpected.type",
    7.96 +                            kindNames(resultInfo.pkind),
    7.97 +                            kindName(ownkind));
    7.98 +                    owntype = types.createErrorType(owntype);
    7.99 +                }
   7.100              }
   7.101          }
   7.102          tree.type = owntype;
   7.103 @@ -297,8 +321,6 @@
   7.104              } else {
   7.105                  log.error(pos, "cant.assign.val.to.final.var", v);
   7.106              }
   7.107 -        } else if ((v.flags() & EFFECTIVELY_FINAL) != 0) {
   7.108 -            v.flags_field &= ~EFFECTIVELY_FINAL;
   7.109          }
   7.110      }
   7.111  
   7.112 @@ -431,14 +453,38 @@
   7.113          static final long serialVersionUID = -6924771130405446405L;
   7.114          private Env<AttrContext> env;
   7.115          private BreakAttr(Env<AttrContext> env) {
   7.116 -            this.env = env;
   7.117 +            this.env = copyEnv(env);
   7.118 +        }
   7.119 +
   7.120 +        private Env<AttrContext> copyEnv(Env<AttrContext> env) {
   7.121 +            Env<AttrContext> newEnv =
   7.122 +                    env.dup(env.tree, env.info.dup(copyScope(env.info.scope)));
   7.123 +            if (newEnv.outer != null) {
   7.124 +                newEnv.outer = copyEnv(newEnv.outer);
   7.125 +            }
   7.126 +            return newEnv;
   7.127 +        }
   7.128 +
   7.129 +        private Scope copyScope(Scope sc) {
   7.130 +            Scope newScope = new Scope(sc.owner);
   7.131 +            List<Symbol> elemsList = List.nil();
   7.132 +            while (sc != null) {
   7.133 +                for (Scope.Entry e = sc.elems ; e != null ; e = e.sibling) {
   7.134 +                    elemsList = elemsList.prepend(e.sym);
   7.135 +                }
   7.136 +                sc = sc.next;
   7.137 +            }
   7.138 +            for (Symbol s : elemsList) {
   7.139 +                newScope.enter(s);
   7.140 +            }
   7.141 +            return newScope;
   7.142          }
   7.143      }
   7.144  
   7.145      class ResultInfo {
   7.146 -        int pkind;
   7.147 -        Type pt;
   7.148 -        CheckContext checkContext;
   7.149 +        final int pkind;
   7.150 +        final Type pt;
   7.151 +        final CheckContext checkContext;
   7.152  
   7.153          ResultInfo(int pkind, Type pt) {
   7.154              this(pkind, pt, chk.basicHandler);
   7.155 @@ -450,15 +496,19 @@
   7.156              this.checkContext = checkContext;
   7.157          }
   7.158  
   7.159 -        protected Type check(DiagnosticPosition pos, Type found) {
   7.160 +        protected Type check(final DiagnosticPosition pos, final Type found) {
   7.161              return chk.checkType(pos, found, pt, checkContext);
   7.162          }
   7.163 +
   7.164 +        protected ResultInfo dup(Type newPt) {
   7.165 +            return new ResultInfo(pkind, newPt, checkContext);
   7.166 +        }
   7.167      }
   7.168  
   7.169 -    private final ResultInfo statInfo;
   7.170 -    private final ResultInfo varInfo;
   7.171 -    private final ResultInfo unknownExprInfo;
   7.172 -    private final ResultInfo unknownTypeInfo;
   7.173 +    final ResultInfo statInfo;
   7.174 +    final ResultInfo varInfo;
   7.175 +    final ResultInfo unknownExprInfo;
   7.176 +    final ResultInfo unknownTypeInfo;
   7.177  
   7.178      Type pt() {
   7.179          return resultInfo.pt;
   7.180 @@ -491,7 +541,7 @@
   7.181       *  @param env     The environment visitor argument.
   7.182       *  @param resultInfo   The result info visitor argument.
   7.183       */
   7.184 -    private Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
   7.185 +    Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
   7.186          Env<AttrContext> prevEnv = this.env;
   7.187          ResultInfo prevResult = this.resultInfo;
   7.188          try {
   7.189 @@ -563,9 +613,12 @@
   7.190       */
   7.191      List<Type> attribArgs(List<JCExpression> trees, Env<AttrContext> env) {
   7.192          ListBuffer<Type> argtypes = new ListBuffer<Type>();
   7.193 -        for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
   7.194 -            argtypes.append(chk.checkNonVoid(
   7.195 -                l.head.pos(), types.upperBound(attribExpr(l.head, env, Infer.anyPoly))));
   7.196 +        for (JCExpression arg : trees) {
   7.197 +            Type argtype = allowPoly && TreeInfo.isPoly(arg, env.tree) ?
   7.198 +                    deferredAttr.new DeferredType(arg, env) :
   7.199 +                    chk.checkNonVoid(arg, attribExpr(arg, env, Infer.anyPoly));
   7.200 +            argtypes.append(argtype);
   7.201 +        }
   7.202          return argtypes.toList();
   7.203      }
   7.204  
   7.205 @@ -979,8 +1032,11 @@
   7.206              // Create a new local environment with a local scope.
   7.207              Env<AttrContext> localEnv =
   7.208                  env.dup(tree, env.info.dup(env.info.scope.dup()));
   7.209 -            attribStats(tree.stats, localEnv);
   7.210 -            localEnv.info.scope.leave();
   7.211 +            try {
   7.212 +                attribStats(tree.stats, localEnv);
   7.213 +            } finally {
   7.214 +                localEnv.info.scope.leave();
   7.215 +            }
   7.216          }
   7.217          result = null;
   7.218      }
   7.219 @@ -1000,43 +1056,51 @@
   7.220      public void visitForLoop(JCForLoop tree) {
   7.221          Env<AttrContext> loopEnv =
   7.222              env.dup(env.tree, env.info.dup(env.info.scope.dup()));
   7.223 -        attribStats(tree.init, loopEnv);
   7.224 -        if (tree.cond != null) attribExpr(tree.cond, loopEnv, syms.booleanType);
   7.225 -        loopEnv.tree = tree; // before, we were not in loop!
   7.226 -        attribStats(tree.step, loopEnv);
   7.227 -        attribStat(tree.body, loopEnv);
   7.228 -        loopEnv.info.scope.leave();
   7.229 -        result = null;
   7.230 +        try {
   7.231 +            attribStats(tree.init, loopEnv);
   7.232 +            if (tree.cond != null) attribExpr(tree.cond, loopEnv, syms.booleanType);
   7.233 +            loopEnv.tree = tree; // before, we were not in loop!
   7.234 +            attribStats(tree.step, loopEnv);
   7.235 +            attribStat(tree.body, loopEnv);
   7.236 +            result = null;
   7.237 +        }
   7.238 +        finally {
   7.239 +            loopEnv.info.scope.leave();
   7.240 +        }
   7.241      }
   7.242  
   7.243      public void visitForeachLoop(JCEnhancedForLoop tree) {
   7.244          Env<AttrContext> loopEnv =
   7.245              env.dup(env.tree, env.info.dup(env.info.scope.dup()));
   7.246 -        attribStat(tree.var, loopEnv);
   7.247 -        Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv));
   7.248 -        chk.checkNonVoid(tree.pos(), exprType);
   7.249 -        Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
   7.250 -        if (elemtype == null) {
   7.251 -            // or perhaps expr implements Iterable<T>?
   7.252 -            Type base = types.asSuper(exprType, syms.iterableType.tsym);
   7.253 -            if (base == null) {
   7.254 -                log.error(tree.expr.pos(),
   7.255 -                        "foreach.not.applicable.to.type",
   7.256 -                        exprType,
   7.257 -                        diags.fragment("type.req.array.or.iterable"));
   7.258 -                elemtype = types.createErrorType(exprType);
   7.259 -            } else {
   7.260 -                List<Type> iterableParams = base.allparams();
   7.261 -                elemtype = iterableParams.isEmpty()
   7.262 -                    ? syms.objectType
   7.263 -                    : types.upperBound(iterableParams.head);
   7.264 +        try {
   7.265 +            attribStat(tree.var, loopEnv);
   7.266 +            Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv));
   7.267 +            chk.checkNonVoid(tree.pos(), exprType);
   7.268 +            Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
   7.269 +            if (elemtype == null) {
   7.270 +                // or perhaps expr implements Iterable<T>?
   7.271 +                Type base = types.asSuper(exprType, syms.iterableType.tsym);
   7.272 +                if (base == null) {
   7.273 +                    log.error(tree.expr.pos(),
   7.274 +                            "foreach.not.applicable.to.type",
   7.275 +                            exprType,
   7.276 +                            diags.fragment("type.req.array.or.iterable"));
   7.277 +                    elemtype = types.createErrorType(exprType);
   7.278 +                } else {
   7.279 +                    List<Type> iterableParams = base.allparams();
   7.280 +                    elemtype = iterableParams.isEmpty()
   7.281 +                        ? syms.objectType
   7.282 +                        : types.upperBound(iterableParams.head);
   7.283 +                }
   7.284              }
   7.285 +            chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
   7.286 +            loopEnv.tree = tree; // before, we were not in loop!
   7.287 +            attribStat(tree.body, loopEnv);
   7.288 +            result = null;
   7.289          }
   7.290 -        chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
   7.291 -        loopEnv.tree = tree; // before, we were not in loop!
   7.292 -        attribStat(tree.body, loopEnv);
   7.293 -        loopEnv.info.scope.leave();
   7.294 -        result = null;
   7.295 +        finally {
   7.296 +            loopEnv.info.scope.leave();
   7.297 +        }
   7.298      }
   7.299  
   7.300      public void visitLabelled(JCLabeledStatement tree) {
   7.301 @@ -1062,61 +1126,69 @@
   7.302          Env<AttrContext> switchEnv =
   7.303              env.dup(tree, env.info.dup(env.info.scope.dup()));
   7.304  
   7.305 -        boolean enumSwitch =
   7.306 -            allowEnums &&
   7.307 -            (seltype.tsym.flags() & Flags.ENUM) != 0;
   7.308 -        boolean stringSwitch = false;
   7.309 -        if (types.isSameType(seltype, syms.stringType)) {
   7.310 -            if (allowStringsInSwitch) {
   7.311 -                stringSwitch = true;
   7.312 -            } else {
   7.313 -                log.error(tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
   7.314 +        try {
   7.315 +
   7.316 +            boolean enumSwitch =
   7.317 +                allowEnums &&
   7.318 +                (seltype.tsym.flags() & Flags.ENUM) != 0;
   7.319 +            boolean stringSwitch = false;
   7.320 +            if (types.isSameType(seltype, syms.stringType)) {
   7.321 +                if (allowStringsInSwitch) {
   7.322 +                    stringSwitch = true;
   7.323 +                } else {
   7.324 +                    log.error(tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
   7.325 +                }
   7.326              }
   7.327 +            if (!enumSwitch && !stringSwitch)
   7.328 +                seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType);
   7.329 +
   7.330 +            // Attribute all cases and
   7.331 +            // check that there are no duplicate case labels or default clauses.
   7.332 +            Set<Object> labels = new HashSet<Object>(); // The set of case labels.
   7.333 +            boolean hasDefault = false;      // Is there a default label?
   7.334 +            for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
   7.335 +                JCCase c = l.head;
   7.336 +                Env<AttrContext> caseEnv =
   7.337 +                    switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup()));
   7.338 +                try {
   7.339 +                    if (c.pat != null) {
   7.340 +                        if (enumSwitch) {
   7.341 +                            Symbol sym = enumConstant(c.pat, seltype);
   7.342 +                            if (sym == null) {
   7.343 +                                log.error(c.pat.pos(), "enum.label.must.be.unqualified.enum");
   7.344 +                            } else if (!labels.add(sym)) {
   7.345 +                                log.error(c.pos(), "duplicate.case.label");
   7.346 +                            }
   7.347 +                        } else {
   7.348 +                            Type pattype = attribExpr(c.pat, switchEnv, seltype);
   7.349 +                            if (pattype.tag != ERROR) {
   7.350 +                                if (pattype.constValue() == null) {
   7.351 +                                    log.error(c.pat.pos(),
   7.352 +                                              (stringSwitch ? "string.const.req" : "const.expr.req"));
   7.353 +                                } else if (labels.contains(pattype.constValue())) {
   7.354 +                                    log.error(c.pos(), "duplicate.case.label");
   7.355 +                                } else {
   7.356 +                                    labels.add(pattype.constValue());
   7.357 +                                }
   7.358 +                            }
   7.359 +                        }
   7.360 +                    } else if (hasDefault) {
   7.361 +                        log.error(c.pos(), "duplicate.default.label");
   7.362 +                    } else {
   7.363 +                        hasDefault = true;
   7.364 +                    }
   7.365 +                    attribStats(c.stats, caseEnv);
   7.366 +                } finally {
   7.367 +                    caseEnv.info.scope.leave();
   7.368 +                    addVars(c.stats, switchEnv.info.scope);
   7.369 +                }
   7.370 +            }
   7.371 +
   7.372 +            result = null;
   7.373          }
   7.374 -        if (!enumSwitch && !stringSwitch)
   7.375 -            seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType);
   7.376 -
   7.377 -        // Attribute all cases and
   7.378 -        // check that there are no duplicate case labels or default clauses.
   7.379 -        Set<Object> labels = new HashSet<Object>(); // The set of case labels.
   7.380 -        boolean hasDefault = false;      // Is there a default label?
   7.381 -        for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
   7.382 -            JCCase c = l.head;
   7.383 -            Env<AttrContext> caseEnv =
   7.384 -                switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup()));
   7.385 -            if (c.pat != null) {
   7.386 -                if (enumSwitch) {
   7.387 -                    Symbol sym = enumConstant(c.pat, seltype);
   7.388 -                    if (sym == null) {
   7.389 -                        log.error(c.pat.pos(), "enum.label.must.be.unqualified.enum");
   7.390 -                    } else if (!labels.add(sym)) {
   7.391 -                        log.error(c.pos(), "duplicate.case.label");
   7.392 -                    }
   7.393 -                } else {
   7.394 -                    Type pattype = attribExpr(c.pat, switchEnv, seltype);
   7.395 -                    if (pattype.tag != ERROR) {
   7.396 -                        if (pattype.constValue() == null) {
   7.397 -                            log.error(c.pat.pos(),
   7.398 -                                      (stringSwitch ? "string.const.req" : "const.expr.req"));
   7.399 -                        } else if (labels.contains(pattype.constValue())) {
   7.400 -                            log.error(c.pos(), "duplicate.case.label");
   7.401 -                        } else {
   7.402 -                            labels.add(pattype.constValue());
   7.403 -                        }
   7.404 -                    }
   7.405 -                }
   7.406 -            } else if (hasDefault) {
   7.407 -                log.error(c.pos(), "duplicate.default.label");
   7.408 -            } else {
   7.409 -                hasDefault = true;
   7.410 -            }
   7.411 -            attribStats(c.stats, caseEnv);
   7.412 -            caseEnv.info.scope.leave();
   7.413 -            addVars(c.stats, switchEnv.info.scope);
   7.414 +        finally {
   7.415 +            switchEnv.info.scope.leave();
   7.416          }
   7.417 -
   7.418 -        switchEnv.info.scope.leave();
   7.419 -        result = null;
   7.420      }
   7.421      // where
   7.422          /** Add any variables defined in stats to the switch scope. */
   7.423 @@ -1158,63 +1230,72 @@
   7.424      public void visitTry(JCTry tree) {
   7.425          // Create a new local environment with a local
   7.426          Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
   7.427 -        boolean isTryWithResource = tree.resources.nonEmpty();
   7.428 -        // Create a nested environment for attributing the try block if needed
   7.429 -        Env<AttrContext> tryEnv = isTryWithResource ?
   7.430 -            env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
   7.431 -            localEnv;
   7.432 -        // Attribute resource declarations
   7.433 -        for (JCTree resource : tree.resources) {
   7.434 -            CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
   7.435 -                @Override
   7.436 -                public void report(DiagnosticPosition pos, JCDiagnostic details) {
   7.437 -                    chk.basicHandler.report(pos, diags.fragment("try.not.applicable.to.type", details));
   7.438 +        try {
   7.439 +            boolean isTryWithResource = tree.resources.nonEmpty();
   7.440 +            // Create a nested environment for attributing the try block if needed
   7.441 +            Env<AttrContext> tryEnv = isTryWithResource ?
   7.442 +                env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
   7.443 +                localEnv;
   7.444 +            try {
   7.445 +                // Attribute resource declarations
   7.446 +                for (JCTree resource : tree.resources) {
   7.447 +                    CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
   7.448 +                        @Override
   7.449 +                        public void report(DiagnosticPosition pos, JCDiagnostic details) {
   7.450 +                            chk.basicHandler.report(pos, diags.fragment("try.not.applicable.to.type", details));
   7.451 +                        }
   7.452 +                    };
   7.453 +                    ResultInfo twrResult = new ResultInfo(VAL, syms.autoCloseableType, twrContext);
   7.454 +                    if (resource.hasTag(VARDEF)) {
   7.455 +                        attribStat(resource, tryEnv);
   7.456 +                        twrResult.check(resource, resource.type);
   7.457 +
   7.458 +                        //check that resource type cannot throw InterruptedException
   7.459 +                        checkAutoCloseable(resource.pos(), localEnv, resource.type);
   7.460 +
   7.461 +                        VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
   7.462 +                        var.setData(ElementKind.RESOURCE_VARIABLE);
   7.463 +                    } else {
   7.464 +                        attribTree(resource, tryEnv, twrResult);
   7.465 +                    }
   7.466                  }
   7.467 -            };
   7.468 -            ResultInfo twrResult = new ResultInfo(VAL, syms.autoCloseableType, twrContext);
   7.469 -            if (resource.hasTag(VARDEF)) {
   7.470 -                attribStat(resource, tryEnv);
   7.471 -                twrResult.check(resource, resource.type);
   7.472 -
   7.473 -                //check that resource type cannot throw InterruptedException
   7.474 -                checkAutoCloseable(resource.pos(), localEnv, resource.type);
   7.475 -
   7.476 -                VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
   7.477 -                var.setData(ElementKind.RESOURCE_VARIABLE);
   7.478 -            } else {
   7.479 -                attribTree(resource, tryEnv, twrResult);
   7.480 +                // Attribute body
   7.481 +                attribStat(tree.body, tryEnv);
   7.482 +            } finally {
   7.483 +                if (isTryWithResource)
   7.484 +                    tryEnv.info.scope.leave();
   7.485              }
   7.486 +
   7.487 +            // Attribute catch clauses
   7.488 +            for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
   7.489 +                JCCatch c = l.head;
   7.490 +                Env<AttrContext> catchEnv =
   7.491 +                    localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
   7.492 +                try {
   7.493 +                    Type ctype = attribStat(c.param, catchEnv);
   7.494 +                    if (TreeInfo.isMultiCatch(c)) {
   7.495 +                        //multi-catch parameter is implicitly marked as final
   7.496 +                        c.param.sym.flags_field |= FINAL | UNION;
   7.497 +                    }
   7.498 +                    if (c.param.sym.kind == Kinds.VAR) {
   7.499 +                        c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
   7.500 +                    }
   7.501 +                    chk.checkType(c.param.vartype.pos(),
   7.502 +                                  chk.checkClassType(c.param.vartype.pos(), ctype),
   7.503 +                                  syms.throwableType);
   7.504 +                    attribStat(c.body, catchEnv);
   7.505 +                } finally {
   7.506 +                    catchEnv.info.scope.leave();
   7.507 +                }
   7.508 +            }
   7.509 +
   7.510 +            // Attribute finalizer
   7.511 +            if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
   7.512 +            result = null;
   7.513          }
   7.514 -        // Attribute body
   7.515 -        attribStat(tree.body, tryEnv);
   7.516 -        if (isTryWithResource)
   7.517 -            tryEnv.info.scope.leave();
   7.518 -
   7.519 -        // Attribute catch clauses
   7.520 -        for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
   7.521 -            JCCatch c = l.head;
   7.522 -            Env<AttrContext> catchEnv =
   7.523 -                localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
   7.524 -            Type ctype = attribStat(c.param, catchEnv);
   7.525 -            if (TreeInfo.isMultiCatch(c)) {
   7.526 -                //multi-catch parameter is implicitly marked as final
   7.527 -                c.param.sym.flags_field |= FINAL | UNION;
   7.528 -            }
   7.529 -            if (c.param.sym.kind == Kinds.VAR) {
   7.530 -                c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
   7.531 -            }
   7.532 -            chk.checkType(c.param.vartype.pos(),
   7.533 -                          chk.checkClassType(c.param.vartype.pos(), ctype),
   7.534 -                          syms.throwableType);
   7.535 -            attribStat(c.body, catchEnv);
   7.536 -            catchEnv.info.scope.leave();
   7.537 +        finally {
   7.538 +            localEnv.info.scope.leave();
   7.539          }
   7.540 -
   7.541 -        // Attribute finalizer
   7.542 -        if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
   7.543 -
   7.544 -        localEnv.info.scope.leave();
   7.545 -        result = null;
   7.546      }
   7.547  
   7.548      void checkAutoCloseable(DiagnosticPosition pos, Env<AttrContext> env, Type resource) {
   7.549 @@ -1222,10 +1303,10 @@
   7.550              types.asSuper(resource, syms.autoCloseableType.tsym) != null &&
   7.551              !types.isSameType(resource, syms.autoCloseableType)) { // Don't emit warning for AutoCloseable itself
   7.552              Symbol close = syms.noSymbol;
   7.553 -            boolean prevDeferDiags = log.deferDiagnostics;
   7.554 +            Filter<JCDiagnostic> prevDeferDiagsFilter = log.deferredDiagFilter;
   7.555              Queue<JCDiagnostic> prevDeferredDiags = log.deferredDiagnostics;
   7.556              try {
   7.557 -                log.deferDiagnostics = true;
   7.558 +                log.deferAll();
   7.559                  log.deferredDiagnostics = ListBuffer.lb();
   7.560                  close = rs.resolveQualifiedMethod(pos,
   7.561                          env,
   7.562 @@ -1235,7 +1316,7 @@
   7.563                          List.<Type>nil());
   7.564              }
   7.565              finally {
   7.566 -                log.deferDiagnostics = prevDeferDiags;
   7.567 +                log.deferredDiagFilter = prevDeferDiagsFilter;
   7.568                  log.deferredDiagnostics = prevDeferredDiags;
   7.569              }
   7.570              if (close.kind == MTH &&
   7.571 @@ -1248,50 +1329,71 @@
   7.572      }
   7.573  
   7.574      public void visitConditional(JCConditional tree) {
   7.575 -        attribExpr(tree.cond, env, syms.booleanType);
   7.576 -        attribExpr(tree.truepart, env);
   7.577 -        attribExpr(tree.falsepart, env);
   7.578 -        result = check(tree,
   7.579 -                       capture(condType(tree.pos(), tree.cond.type,
   7.580 -                                        tree.truepart.type, tree.falsepart.type)),
   7.581 -                       VAL, resultInfo);
   7.582 +        Type condtype = attribExpr(tree.cond, env, syms.booleanType);
   7.583 +
   7.584 +        boolean standaloneConditional = !allowPoly ||
   7.585 +                pt().tag == NONE && pt() != Type.recoveryType ||
   7.586 +                isBooleanOrNumeric(env, tree);
   7.587 +
   7.588 +        if (!standaloneConditional && resultInfo.pt.tag == VOID) {
   7.589 +            //cannot get here (i.e. it means we are returning from void method - which is already an error)
   7.590 +            result = tree.type = types.createErrorType(resultInfo.pt);
   7.591 +            return;
   7.592 +        }
   7.593 +
   7.594 +        ResultInfo condInfo = standaloneConditional ?
   7.595 +                unknownExprInfo :
   7.596 +                new ResultInfo(VAL, pt(), new Check.NestedCheckContext(resultInfo.checkContext) {
   7.597 +                    //this will use enclosing check context to check compatibility of
   7.598 +                    //subexpression against target type; if we are in a method check context,
   7.599 +                    //depending on whether boxing is allowed, we could have incompatibilities
   7.600 +                    @Override
   7.601 +                    public void report(DiagnosticPosition pos, JCDiagnostic details) {
   7.602 +                        enclosingContext.report(pos, diags.fragment("incompatible.type.in.conditional", details));
   7.603 +                    }
   7.604 +                });
   7.605 +
   7.606 +        Type truetype = attribTree(tree.truepart, env, condInfo);
   7.607 +        Type falsetype = attribTree(tree.falsepart, env, condInfo);
   7.608 +
   7.609 +        Type owntype = standaloneConditional ? condType(tree, truetype, falsetype) : pt();
   7.610 +        if (condtype.constValue() != null &&
   7.611 +                truetype.constValue() != null &&
   7.612 +                falsetype.constValue() != null) {
   7.613 +            //constant folding
   7.614 +            owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype);
   7.615 +        }
   7.616 +        result = check(tree, owntype, VAL, resultInfo);
   7.617      }
   7.618      //where
   7.619 +        @SuppressWarnings("fallthrough")
   7.620 +        private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
   7.621 +            switch (tree.getTag()) {
   7.622 +                case LITERAL: return ((JCLiteral)tree).typetag < CLASS;
   7.623 +                case LAMBDA: case REFERENCE: return false;
   7.624 +                case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr);
   7.625 +                case CONDEXPR:
   7.626 +                    JCConditional condTree = (JCConditional)tree;
   7.627 +                    return isBooleanOrNumeric(env, condTree.truepart) &&
   7.628 +                            isBooleanOrNumeric(env, condTree.falsepart);
   7.629 +                default:
   7.630 +                    Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
   7.631 +                    speculativeType = types.unboxedTypeOrType(speculativeType);
   7.632 +                    return speculativeType.tag <= BOOLEAN;
   7.633 +            }
   7.634 +        }
   7.635 +
   7.636          /** Compute the type of a conditional expression, after
   7.637 -         *  checking that it exists. See Spec 15.25.
   7.638 -         *
   7.639 -         *  @param pos      The source position to be used for
   7.640 -         *                  error diagnostics.
   7.641 -         *  @param condtype The type of the expression's condition.
   7.642 -         *  @param thentype The type of the expression's then-part.
   7.643 -         *  @param elsetype The type of the expression's else-part.
   7.644 -         */
   7.645 -        private Type condType(DiagnosticPosition pos,
   7.646 -                              Type condtype,
   7.647 -                              Type thentype,
   7.648 -                              Type elsetype) {
   7.649 -            Type ctype = condType1(pos, condtype, thentype, elsetype);
   7.650 -
   7.651 -            // If condition and both arms are numeric constants,
   7.652 -            // evaluate at compile-time.
   7.653 -            return ((condtype.constValue() != null) &&
   7.654 -                    (thentype.constValue() != null) &&
   7.655 -                    (elsetype.constValue() != null))
   7.656 -                ? cfolder.coerce(condtype.isTrue()?thentype:elsetype, ctype)
   7.657 -                : ctype;
   7.658 -        }
   7.659 -        /** Compute the type of a conditional expression, after
   7.660 -         *  checking that it exists.  Does not take into
   7.661 +         *  checking that it exists.  See JLS 15.25. Does not take into
   7.662           *  account the special case where condition and both arms
   7.663           *  are constants.
   7.664           *
   7.665           *  @param pos      The source position to be used for error
   7.666           *                  diagnostics.
   7.667 -         *  @param condtype The type of the expression's condition.
   7.668           *  @param thentype The type of the expression's then-part.
   7.669           *  @param elsetype The type of the expression's else-part.
   7.670           */
   7.671 -        private Type condType1(DiagnosticPosition pos, Type condtype,
   7.672 +        private Type condType(DiagnosticPosition pos,
   7.673                                 Type thentype, Type elsetype) {
   7.674              // If same type, that is the result
   7.675              if (types.isSameType(thentype, elsetype))
   7.676 @@ -1445,22 +1547,19 @@
   7.677      public void visitReturn(JCReturn tree) {
   7.678          // Check that there is an enclosing method which is
   7.679          // nested within than the enclosing class.
   7.680 -        if (env.enclMethod == null ||
   7.681 -            env.enclMethod.sym.owner != env.enclClass.sym) {
   7.682 +        if (env.info.returnResult == null) {
   7.683              log.error(tree.pos(), "ret.outside.meth");
   7.684 -
   7.685          } else {
   7.686              // Attribute return expression, if it exists, and check that
   7.687              // it conforms to result type of enclosing method.
   7.688 -            Symbol m = env.enclMethod.sym;
   7.689 -            if (m.type.getReturnType().tag == VOID) {
   7.690 -                if (tree.expr != null)
   7.691 +            if (tree.expr != null) {
   7.692 +                if (env.info.returnResult.pt.tag == VOID) {
   7.693                      log.error(tree.expr.pos(),
   7.694                                "cant.ret.val.from.meth.decl.void");
   7.695 -            } else if (tree.expr == null) {
   7.696 +                }
   7.697 +                attribTree(tree.expr, env, env.info.returnResult);
   7.698 +            } else if (env.info.returnResult.pt.tag != VOID) {
   7.699                  log.error(tree.pos(), "missing.ret.val");
   7.700 -            } else {
   7.701 -                attribExpr(tree.expr, env, m.type.getReturnType());
   7.702              }
   7.703          }
   7.704          result = null;
   7.705 @@ -1562,7 +1661,7 @@
   7.706                      // current instance (JLS ???).
   7.707                      boolean selectSuperPrev = localEnv.info.selectSuper;
   7.708                      localEnv.info.selectSuper = true;
   7.709 -                    localEnv.info.varArgs = false;
   7.710 +                    localEnv.info.pendingResolutionPhase = null;
   7.711                      Symbol sym = rs.resolveConstructor(
   7.712                          tree.meth.pos(), localEnv, site, argtypes, typeargtypes);
   7.713                      localEnv.info.selectSuper = selectSuperPrev;
   7.714 @@ -1573,8 +1672,7 @@
   7.715                      // ...and check that it is legal in the current context.
   7.716                      // (this will also set the tree's type)
   7.717                      Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
   7.718 -                    checkId(tree.meth, site, sym, localEnv, new ResultInfo(MTH, mpt),
   7.719 -                            tree.varargsElement != null);
   7.720 +                    checkId(tree.meth, site, sym, localEnv, new ResultInfo(MTH, mpt));
   7.721                  }
   7.722                  // Otherwise, `site' is an error type and we do nothing
   7.723              }
   7.724 @@ -1589,8 +1687,8 @@
   7.725              // whose formal argument types is exactly the list of actual
   7.726              // arguments (this will also set the method symbol).
   7.727              Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
   7.728 -            localEnv.info.varArgs = false;
   7.729 -            Type mtype = attribExpr(tree.meth, localEnv, mpt);
   7.730 +            localEnv.info.pendingResolutionPhase = null;
   7.731 +            Type mtype = attribTree(tree.meth, localEnv, new ResultInfo(VAL, mpt, resultInfo.checkContext));
   7.732  
   7.733              // Compute the result type.
   7.734              Type restype = mtype.getReturnType();
   7.735 @@ -1625,7 +1723,7 @@
   7.736              // current context.  Also, capture the return type
   7.737              result = check(tree, capture(restype), VAL, resultInfo);
   7.738  
   7.739 -            if (localEnv.info.varArgs)
   7.740 +            if (localEnv.info.lastResolveVarargs())
   7.741                  Assert.check(result.isErroneous() || tree.varargsElement != null);
   7.742          }
   7.743          chk.validate(tree.typeargs, localEnv);
   7.744 @@ -1652,11 +1750,11 @@
   7.745          /** Obtain a method type with given argument types.
   7.746           */
   7.747          Type newMethodTemplate(Type restype, List<Type> argtypes, List<Type> typeargtypes) {
   7.748 -            MethodType mt = new MethodType(argtypes, restype, null, syms.methodClass);
   7.749 +            MethodType mt = new MethodType(argtypes, restype, List.<Type>nil(), syms.methodClass);
   7.750              return (typeargtypes == null) ? mt : (Type)new ForAll(typeargtypes, mt);
   7.751          }
   7.752  
   7.753 -    public void visitNewClass(JCNewClass tree) {
   7.754 +    public void visitNewClass(final JCNewClass tree) {
   7.755          Type owntype = types.createErrorType(tree.type);
   7.756  
   7.757          // The local environment of a class creation is
   7.758 @@ -1729,19 +1827,6 @@
   7.759          List<Type> argtypes = attribArgs(tree.args, localEnv);
   7.760          List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
   7.761  
   7.762 -        if (TreeInfo.isDiamond(tree) && !clazztype.isErroneous()) {
   7.763 -            Pair<Symbol, Type> diamondResult =
   7.764 -                    attribDiamond(localEnv, tree, clazztype, argtypes, typeargtypes);
   7.765 -            tree.clazz.type = types.createErrorType(clazztype);
   7.766 -            tree.constructor = diamondResult.fst;
   7.767 -            tree.constructorType = diamondResult.snd;
   7.768 -            if (!diamondResult.snd.isErroneous()) {
   7.769 -                tree.clazz.type = clazztype = diamondResult.snd.getReturnType();
   7.770 -                tree.constructorType = types.createMethodTypeWithReturn(diamondResult.snd, syms.voidType);
   7.771 -            }
   7.772 -            clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true);
   7.773 -        }
   7.774 -
   7.775          // If we have made no mistakes in the class type...
   7.776          if (clazztype.tag == CLASS) {
   7.777              // Enums may not be instantiated except implicitly
   7.778 @@ -1768,18 +1853,57 @@
   7.779                  // Error recovery: pretend no arguments were supplied.
   7.780                  argtypes = List.nil();
   7.781                  typeargtypes = List.nil();
   7.782 +            } else if (TreeInfo.isDiamond(tree)) {
   7.783 +                ClassType site = new ClassType(clazztype.getEnclosingType(),
   7.784 +                            clazztype.tsym.type.getTypeArguments(),
   7.785 +                            clazztype.tsym);
   7.786 +
   7.787 +                Env<AttrContext> diamondEnv = localEnv.dup(tree);
   7.788 +                diamondEnv.info.selectSuper = cdef != null;
   7.789 +                diamondEnv.info.pendingResolutionPhase = null;
   7.790 +
   7.791 +                //if the type of the instance creation expression is a class type
   7.792 +                //apply method resolution inference (JLS 15.12.2.7). The return type
   7.793 +                //of the resolved constructor will be a partially instantiated type
   7.794 +                Symbol constructor = rs.resolveDiamond(tree.pos(),
   7.795 +                            diamondEnv,
   7.796 +                            site,
   7.797 +                            argtypes,
   7.798 +                            typeargtypes);
   7.799 +                tree.constructor = constructor.baseSymbol();
   7.800 +
   7.801 +                final TypeSymbol csym = clazztype.tsym;
   7.802 +                ResultInfo diamondResult = new ResultInfo(MTH, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes), new Check.NestedCheckContext(resultInfo.checkContext) {
   7.803 +                    @Override
   7.804 +                    public void report(DiagnosticPosition _unused, JCDiagnostic details) {
   7.805 +                        enclosingContext.report(tree.clazz,
   7.806 +                                diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", csym), details));
   7.807 +                    }
   7.808 +                });
   7.809 +                Type constructorType = tree.constructorType = types.createErrorType(clazztype);
   7.810 +                constructorType = checkId(tree, site,
   7.811 +                        constructor,
   7.812 +                        diamondEnv,
   7.813 +                        diamondResult);
   7.814 +
   7.815 +                tree.clazz.type = types.createErrorType(clazztype);
   7.816 +                if (!constructorType.isErroneous()) {
   7.817 +                    tree.clazz.type = clazztype = constructorType.getReturnType();
   7.818 +                    tree.constructorType = types.createMethodTypeWithReturn(constructorType, syms.voidType);
   7.819 +                }
   7.820 +                clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true);
   7.821              }
   7.822  
   7.823              // Resolve the called constructor under the assumption
   7.824              // that we are referring to a superclass instance of the
   7.825              // current instance (JLS ???).
   7.826 -            else if (!TreeInfo.isDiamond(tree)) {
   7.827 +            else {
   7.828                  //the following code alters some of the fields in the current
   7.829                  //AttrContext - hence, the current context must be dup'ed in
   7.830                  //order to avoid downstream failures
   7.831                  Env<AttrContext> rsEnv = localEnv.dup(tree);
   7.832                  rsEnv.info.selectSuper = cdef != null;
   7.833 -                rsEnv.info.varArgs = false;
   7.834 +                rsEnv.info.pendingResolutionPhase = null;
   7.835                  tree.constructor = rs.resolveConstructor(
   7.836                      tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
   7.837                  if (cdef == null) { //do not check twice!
   7.838 @@ -1787,42 +1911,11 @@
   7.839                              clazztype,
   7.840                              tree.constructor,
   7.841                              rsEnv,
   7.842 -                            new ResultInfo(MTH, newMethodTemplate(syms.voidType, argtypes, typeargtypes)),
   7.843 -                            rsEnv.info.varArgs);
   7.844 -                    if (rsEnv.info.varArgs)
   7.845 +                            new ResultInfo(MTH, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
   7.846 +                    if (rsEnv.info.lastResolveVarargs())
   7.847                          Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
   7.848                  }
   7.849 -                if (tree.def == null &&
   7.850 -                        !clazztype.isErroneous() &&
   7.851 -                        clazztype.getTypeArguments().nonEmpty() &&
   7.852 -                        findDiamonds) {
   7.853 -                    boolean prevDeferDiags = log.deferDiagnostics;
   7.854 -                    Queue<JCDiagnostic> prevDeferredDiags = log.deferredDiagnostics;
   7.855 -                    Type inferred = null;
   7.856 -                    try {
   7.857 -                        //disable diamond-related diagnostics
   7.858 -                        log.deferDiagnostics = true;
   7.859 -                        log.deferredDiagnostics = ListBuffer.lb();
   7.860 -                        inferred = attribDiamond(localEnv,
   7.861 -                                tree,
   7.862 -                                clazztype,
   7.863 -                                argtypes,
   7.864 -                                typeargtypes).snd;
   7.865 -                    } finally {
   7.866 -                        log.deferDiagnostics = prevDeferDiags;
   7.867 -                        log.deferredDiagnostics = prevDeferredDiags;
   7.868 -                    }
   7.869 -                    if (!inferred.isErroneous()) {
   7.870 -                        inferred = inferred.getReturnType();
   7.871 -                    }
   7.872 -                    if (inferred != null &&
   7.873 -                            types.isAssignable(inferred, pt().tag == NONE ? syms.objectType : pt(), Warner.noWarnings)) {
   7.874 -                        String key = types.isSameType(clazztype, inferred) ?
   7.875 -                            "diamond.redundant.args" :
   7.876 -                            "diamond.redundant.args.1";
   7.877 -                        log.warning(tree.clazz.pos(), key, clazztype, inferred);
   7.878 -                    }
   7.879 -                }
   7.880 +                findDiamondIfNeeded(localEnv, tree, clazztype);
   7.881              }
   7.882  
   7.883              if (cdef != null) {
   7.884 @@ -1887,8 +1980,7 @@
   7.885                      clazztype,
   7.886                      tree.constructor,
   7.887                      localEnv,
   7.888 -                    new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes)),
   7.889 -                    localEnv.info.varArgs);
   7.890 +                    new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
   7.891              }
   7.892  
   7.893              if (tree.constructor != null && tree.constructor.kind == MTH)
   7.894 @@ -1897,53 +1989,33 @@
   7.895          result = check(tree, owntype, VAL, resultInfo);
   7.896          chk.validate(tree.typeargs, localEnv);
   7.897      }
   7.898 -
   7.899 -    Pair<Symbol, Type> attribDiamond(Env<AttrContext> env,
   7.900 -                        final JCNewClass tree,
   7.901 -                        final Type clazztype,
   7.902 -                        List<Type> argtypes,
   7.903 -                        List<Type> typeargtypes) {
   7.904 -        if (clazztype.isErroneous() ||
   7.905 -                clazztype.isInterface()) {
   7.906 -            //if the type of the instance creation expression is erroneous,
   7.907 -            //or if it's an interface, or if something prevented us to form a valid
   7.908 -            //mapping, return the (possibly erroneous) type unchanged
   7.909 -            return new Pair<Symbol, Type>(syms.noSymbol, clazztype);
   7.910 +    //where
   7.911 +        void findDiamondIfNeeded(Env<AttrContext> env, JCNewClass tree, Type clazztype) {
   7.912 +            if (tree.def == null &&
   7.913 +                    !clazztype.isErroneous() &&
   7.914 +                    clazztype.getTypeArguments().nonEmpty() &&
   7.915 +                    findDiamonds) {
   7.916 +                JCTypeApply ta = (JCTypeApply)tree.clazz;
   7.917 +                List<JCExpression> prevTypeargs = ta.arguments;
   7.918 +                try {
   7.919 +                    //create a 'fake' diamond AST node by removing type-argument trees
   7.920 +                    ta.arguments = List.nil();
   7.921 +                    ResultInfo findDiamondResult = new ResultInfo(VAL,
   7.922 +                            resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt());
   7.923 +                    Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type;
   7.924 +                    if (!inferred.isErroneous() &&
   7.925 +                        types.isAssignable(inferred, pt().tag == NONE ? syms.objectType : pt(), Warner.noWarnings)) {
   7.926 +                        String key = types.isSameType(clazztype, inferred) ?
   7.927 +                            "diamond.redundant.args" :
   7.928 +                            "diamond.redundant.args.1";
   7.929 +                        log.warning(tree.clazz.pos(), key, clazztype, inferred);
   7.930 +                    }
   7.931 +                } finally {
   7.932 +                    ta.arguments = prevTypeargs;
   7.933 +                }
   7.934 +            }
   7.935          }
   7.936  
   7.937 -        //dup attribution environment and augment the set of inference variables
   7.938 -        Env<AttrContext> localEnv = env.dup(tree);
   7.939 -
   7.940 -        ClassType site = new ClassType(clazztype.getEnclosingType(),
   7.941 -                    clazztype.tsym.type.getTypeArguments(),
   7.942 -                    clazztype.tsym);
   7.943 -
   7.944 -        //if the type of the instance creation expression is a class type
   7.945 -        //apply method resolution inference (JLS 15.12.2.7). The return type
   7.946 -        //of the resolved constructor will be a partially instantiated type
   7.947 -        Symbol constructor = rs.resolveDiamond(tree.pos(),
   7.948 -                    localEnv,
   7.949 -                    site,
   7.950 -                    argtypes,
   7.951 -                    typeargtypes);
   7.952 -
   7.953 -        Type constructorType = types.createErrorType(clazztype);
   7.954 -        ResultInfo diamondResult = new ResultInfo(MTH, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes), new Check.NestedCheckContext(resultInfo.checkContext) {
   7.955 -            @Override
   7.956 -            public void report(DiagnosticPosition _unused, JCDiagnostic details) {
   7.957 -                enclosingContext.report(tree.clazz,
   7.958 -                        diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", clazztype.tsym), details));
   7.959 -            }
   7.960 -        });
   7.961 -        constructorType = checkId(tree, site,
   7.962 -                constructor,
   7.963 -                localEnv,
   7.964 -                diamondResult,
   7.965 -                localEnv.info.varArgs);
   7.966 -
   7.967 -        return new Pair<Symbol, Type>(constructor.baseSymbol(), constructorType);
   7.968 -    }
   7.969 -
   7.970      /** Make an attributed null check tree.
   7.971       */
   7.972      public JCExpression makeNullCheck(JCExpression arg) {
   7.973 @@ -1960,13 +2032,14 @@
   7.974  
   7.975      public void visitNewArray(JCNewArray tree) {
   7.976          Type owntype = types.createErrorType(tree.type);
   7.977 +        Env<AttrContext> localEnv = env.dup(tree);
   7.978          Type elemtype;
   7.979          if (tree.elemtype != null) {
   7.980 -            elemtype = attribType(tree.elemtype, env);
   7.981 -            chk.validate(tree.elemtype, env);
   7.982 +            elemtype = attribType(tree.elemtype, localEnv);
   7.983 +            chk.validate(tree.elemtype, localEnv);
   7.984              owntype = elemtype;
   7.985              for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
   7.986 -                attribExpr(l.head, env, syms.intType);
   7.987 +                attribExpr(l.head, localEnv, syms.intType);
   7.988                  owntype = new ArrayType(owntype, syms.arrayClass);
   7.989              }
   7.990          } else {
   7.991 @@ -1983,7 +2056,7 @@
   7.992              }
   7.993          }
   7.994          if (tree.elems != null) {
   7.995 -            attribExprs(tree.elems, env, elemtype);
   7.996 +            attribExprs(tree.elems, localEnv, elemtype);
   7.997              owntype = new ArrayType(elemtype, syms.arrayClass);
   7.998          }
   7.999          if (!types.isReifiable(elemtype))
  7.1000 @@ -2132,18 +2205,34 @@
  7.1001          result = check(tree, owntype, VAL, resultInfo);
  7.1002      }
  7.1003  
  7.1004 -    public void visitTypeCast(JCTypeCast tree) {
  7.1005 +    public void visitTypeCast(final JCTypeCast tree) {
  7.1006          Type clazztype = attribType(tree.clazz, env);
  7.1007          chk.validate(tree.clazz, env, false);
  7.1008          //a fresh environment is required for 292 inference to work properly ---
  7.1009          //see Infer.instantiatePolymorphicSignatureInstance()
  7.1010          Env<AttrContext> localEnv = env.dup(tree);
  7.1011 -        Type exprtype = attribExpr(tree.expr, localEnv, Infer.anyPoly);
  7.1012 -        Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
  7.1013 +        //should we propagate the target type?
  7.1014 +        final ResultInfo castInfo;
  7.1015 +        final boolean isPoly = TreeInfo.isPoly(tree.expr, tree);
  7.1016 +        if (isPoly) {
  7.1017 +            //expression is a poly - we need to propagate target type info
  7.1018 +            castInfo = new ResultInfo(VAL, clazztype, new Check.NestedCheckContext(resultInfo.checkContext) {
  7.1019 +                @Override
  7.1020 +                public boolean compatible(Type found, Type req, Warner warn) {
  7.1021 +                    return types.isCastable(found, req, warn);
  7.1022 +                }
  7.1023 +            });
  7.1024 +        } else {
  7.1025 +            //standalone cast - target-type info is not propagated
  7.1026 +            castInfo = unknownExprInfo;
  7.1027 +        }
  7.1028 +        Type exprtype = attribTree(tree.expr, localEnv, castInfo);
  7.1029 +        Type owntype = isPoly ? clazztype : chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
  7.1030          if (exprtype.constValue() != null)
  7.1031              owntype = cfolder.coerce(exprtype, owntype);
  7.1032          result = check(tree, capture(owntype), VAL, resultInfo);
  7.1033 -        chk.checkRedundantCast(localEnv, tree);
  7.1034 +        if (!isPoly)
  7.1035 +            chk.checkRedundantCast(localEnv, tree);
  7.1036      }
  7.1037  
  7.1038      public void visitTypeTest(JCInstanceOf tree) {
  7.1039 @@ -2170,15 +2259,13 @@
  7.1040  
  7.1041      public void visitIdent(JCIdent tree) {
  7.1042          Symbol sym;
  7.1043 -        boolean varArgs = false;
  7.1044  
  7.1045          // Find symbol
  7.1046          if (pt().tag == METHOD || pt().tag == FORALL) {
  7.1047              // If we are looking for a method, the prototype `pt' will be a
  7.1048              // method type with the type of the call's arguments as parameters.
  7.1049 -            env.info.varArgs = false;
  7.1050 +            env.info.pendingResolutionPhase = null;
  7.1051              sym = rs.resolveMethod(tree.pos(), env, tree.name, pt().getParameterTypes(), pt().getTypeArguments());
  7.1052 -            varArgs = env.info.varArgs;
  7.1053          } else if (tree.sym != null && tree.sym.kind != VAR) {
  7.1054              sym = tree.sym;
  7.1055          } else {
  7.1056 @@ -2240,7 +2327,7 @@
  7.1057              while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym))
  7.1058                  env1 = env1.outer;
  7.1059          }
  7.1060 -        result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo, varArgs);
  7.1061 +        result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
  7.1062      }
  7.1063  
  7.1064      public void visitSelect(JCFieldAccess tree) {
  7.1065 @@ -2283,13 +2370,13 @@
  7.1066              sitesym.name == names._super;
  7.1067  
  7.1068          // Determine the symbol represented by the selection.
  7.1069 -        env.info.varArgs = false;
  7.1070 +        env.info.pendingResolutionPhase = null;
  7.1071          Symbol sym = selectSym(tree, sitesym, site, env, resultInfo);
  7.1072          if (sym.exists() && !isType(sym) && (pkind() & (PCK | TYP)) != 0) {
  7.1073              site = capture(site);
  7.1074              sym = selectSym(tree, sitesym, site, env, resultInfo);
  7.1075          }
  7.1076 -        boolean varArgs = env.info.varArgs;
  7.1077 +        boolean varArgs = env.info.lastResolveVarargs();
  7.1078          tree.sym = sym;
  7.1079  
  7.1080          if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) {
  7.1081 @@ -2340,7 +2427,7 @@
  7.1082                  if ((sym.flags() & STATIC) == 0 &&
  7.1083                      sym.name != names._super &&
  7.1084                      (sym.kind == VAR || sym.kind == MTH)) {
  7.1085 -                    rs.access(rs.new StaticError(sym),
  7.1086 +                    rs.accessBase(rs.new StaticError(sym),
  7.1087                                tree.pos(), site, sym.name, true);
  7.1088                  }
  7.1089              }
  7.1090 @@ -2364,7 +2451,7 @@
  7.1091          }
  7.1092  
  7.1093          env.info.selectSuper = selectSuperPrev;
  7.1094 -        result = checkId(tree, site, sym, env, resultInfo, varArgs);
  7.1095 +        result = checkId(tree, site, sym, env, resultInfo);
  7.1096      }
  7.1097      //where
  7.1098          /** Determine symbol referenced by a Select expression,
  7.1099 @@ -2383,7 +2470,7 @@
  7.1100              Name name = tree.name;
  7.1101              switch (site.tag) {
  7.1102              case PACKAGE:
  7.1103 -                return rs.access(
  7.1104 +                return rs.accessBase(
  7.1105                      rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind),
  7.1106                      pos, location, site, name, true);
  7.1107              case ARRAY:
  7.1108 @@ -2407,7 +2494,7 @@
  7.1109                      // We are seeing a plain identifier as selector.
  7.1110                      Symbol sym = rs.findIdentInType(env, site, name, resultInfo.pkind);
  7.1111                      if ((resultInfo.pkind & ERRONEOUS) == 0)
  7.1112 -                        sym = rs.access(sym, pos, location, site, name, true);
  7.1113 +                        sym = rs.accessBase(sym, pos, location, site, name, true);
  7.1114                      return sym;
  7.1115                  }
  7.1116              case WILDCARD:
  7.1117 @@ -2429,7 +2516,7 @@
  7.1118                      Symbol sym2 = (sym.flags() & Flags.PRIVATE) != 0 ?
  7.1119                          rs.new AccessError(env, site, sym) :
  7.1120                                  sym;
  7.1121 -                    rs.access(sym2, pos, location, site, name, true);
  7.1122 +                    rs.accessBase(sym2, pos, location, site, name, true);
  7.1123                      return sym;
  7.1124                  }
  7.1125              case ERROR:
  7.1126 @@ -2480,9 +2567,18 @@
  7.1127                       Type site,
  7.1128                       Symbol sym,
  7.1129                       Env<AttrContext> env,
  7.1130 -                     ResultInfo resultInfo,
  7.1131 -                     boolean useVarargs) {
  7.1132 -            if (resultInfo.pt.isErroneous()) return types.createErrorType(site);
  7.1133 +                     ResultInfo resultInfo) {
  7.1134 +            Type pt = resultInfo.pt.tag == FORALL || resultInfo.pt.tag == METHOD ?
  7.1135 +                    resultInfo.pt.map(deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase)) :
  7.1136 +                    resultInfo.pt;
  7.1137 +
  7.1138 +            DeferredAttr.DeferredTypeMap recoveryMap =
  7.1139 +                    deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
  7.1140 +
  7.1141 +            if (pt.isErroneous()) {
  7.1142 +                Type.map(resultInfo.pt.getParameterTypes(), recoveryMap);
  7.1143 +                return types.createErrorType(site);
  7.1144 +            }
  7.1145              Type owntype; // The computed type of this identifier occurrence.
  7.1146              switch (sym.kind) {
  7.1147              case TYP:
  7.1148 @@ -2560,10 +2656,11 @@
  7.1149                  owntype = checkMethod(site, sym,
  7.1150                          new ResultInfo(VAL, resultInfo.pt.getReturnType(), resultInfo.checkContext),
  7.1151                          env, TreeInfo.args(env.tree), resultInfo.pt.getParameterTypes(),
  7.1152 -                        resultInfo.pt.getTypeArguments(), env.info.varArgs);
  7.1153 +                        resultInfo.pt.getTypeArguments());
  7.1154                  break;
  7.1155              }
  7.1156              case PCK: case ERR:
  7.1157 +                Type.map(resultInfo.pt.getParameterTypes(), recoveryMap);
  7.1158                  owntype = sym.type;
  7.1159                  break;
  7.1160              default:
  7.1161 @@ -2703,8 +2800,7 @@
  7.1162                              Env<AttrContext> env,
  7.1163                              final List<JCExpression> argtrees,
  7.1164                              List<Type> argtypes,
  7.1165 -                            List<Type> typeargtypes,
  7.1166 -                            boolean useVarargs) {
  7.1167 +                            List<Type> typeargtypes) {
  7.1168          // Test (5): if symbol is an instance method of a raw type, issue
  7.1169          // an unchecked warning if its argument types change under erasure.
  7.1170          if (allowGenerics &&
  7.1171 @@ -2726,18 +2822,16 @@
  7.1172          // any type arguments and value arguments.
  7.1173          noteWarner.clear();
  7.1174          try {
  7.1175 -            Type owntype = rs.rawInstantiate(
  7.1176 +            Type owntype = rs.checkMethod(
  7.1177                      env,
  7.1178                      site,
  7.1179                      sym,
  7.1180                      resultInfo,
  7.1181                      argtypes,
  7.1182                      typeargtypes,
  7.1183 -                    allowBoxing,
  7.1184 -                    useVarargs,
  7.1185                      noteWarner);
  7.1186  
  7.1187 -            return chk.checkMethod(owntype, sym, env, argtrees, argtypes, useVarargs,
  7.1188 +            return chk.checkMethod(owntype, sym, env, argtrees, argtypes, env.info.lastResolveVarargs(),
  7.1189                      noteWarner.hasNonSilentLint(LintCategory.UNCHECKED));
  7.1190          } catch (Infer.InferenceException ex) {
  7.1191              //invalid target type - propagate exception outwards or report error
  7.1192 @@ -2745,7 +2839,7 @@
  7.1193              resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic());
  7.1194              return types.createErrorType(site);
  7.1195          } catch (Resolve.InapplicableMethodException ex) {
  7.1196 -            Assert.error();
  7.1197 +            Assert.error(ex.getDiagnostic().getMessage(Locale.getDefault()));
  7.1198              return null;
  7.1199          }
  7.1200      }
  7.1201 @@ -3053,8 +3147,10 @@
  7.1202  
  7.1203              Lint prevLint = chk.setLint(env.info.lint);
  7.1204              JavaFileObject prev = log.useSource(c.sourcefile);
  7.1205 +            ResultInfo prevReturnRes = env.info.returnResult;
  7.1206  
  7.1207              try {
  7.1208 +                env.info.returnResult = null;
  7.1209                  // java.lang.Enum may not be subclassed by a non-enum
  7.1210                  if (st.tsym == syms.enumSym &&
  7.1211                      ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
  7.1212 @@ -3071,6 +3167,7 @@
  7.1213  
  7.1214                  chk.checkDeprecatedAnnotation(env.tree.pos(), c);
  7.1215              } finally {
  7.1216 +                env.info.returnResult = prevReturnRes;
  7.1217                  log.useSource(prev);
  7.1218                  chk.setLint(prevLint);
  7.1219              }
     8.1 --- a/src/share/classes/com/sun/tools/javac/comp/AttrContext.java	Sat Sep 29 09:00:58 2012 -0700
     8.2 +++ b/src/share/classes/com/sun/tools/javac/comp/AttrContext.java	Thu Oct 04 13:04:53 2012 +0100
     8.3 @@ -56,7 +56,7 @@
     8.4  
     8.5      /** Are arguments to current function applications boxed into an array for varargs?
     8.6       */
     8.7 -    boolean varArgs = false;
     8.8 +    Resolve.MethodResolutionPhase pendingResolutionPhase = null;
     8.9  
    8.10      /** A record of the lint/SuppressWarnings currently in effect
    8.11       */
    8.12 @@ -67,6 +67,11 @@
    8.13       */
    8.14      Symbol enclVar = null;
    8.15  
    8.16 +    /** ResultInfo to be used for attributing 'return' statement expressions
    8.17 +     * (set by Attr.visitMethod and Attr.visitLambda)
    8.18 +     */
    8.19 +    Attr.ResultInfo returnResult = null;
    8.20 +
    8.21      /** Duplicate this context, replacing scope field and copying all others.
    8.22       */
    8.23      AttrContext dup(Scope scope) {
    8.24 @@ -75,9 +80,10 @@
    8.25          info.staticLevel = staticLevel;
    8.26          info.isSelfCall = isSelfCall;
    8.27          info.selectSuper = selectSuper;
    8.28 -        info.varArgs = varArgs;
    8.29 +        info.pendingResolutionPhase = pendingResolutionPhase;
    8.30          info.lint = lint;
    8.31          info.enclVar = enclVar;
    8.32 +        info.returnResult = returnResult;
    8.33          return info;
    8.34      }
    8.35  
    8.36 @@ -93,6 +99,11 @@
    8.37          return scope.getElements();
    8.38      }
    8.39  
    8.40 +    boolean lastResolveVarargs() {
    8.41 +        return pendingResolutionPhase != null &&
    8.42 +                pendingResolutionPhase.isVarargsRequired();
    8.43 +    }
    8.44 +
    8.45      public String toString() {
    8.46          return "AttrContext[" + scope.toString() + "]";
    8.47      }
     9.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Sat Sep 29 09:00:58 2012 -0700
     9.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Oct 04 13:04:53 2012 +0100
     9.3 @@ -40,6 +40,7 @@
     9.4  import com.sun.tools.javac.code.Lint.LintCategory;
     9.5  import com.sun.tools.javac.code.Type.*;
     9.6  import com.sun.tools.javac.code.Symbol.*;
     9.7 +import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
     9.8  import com.sun.tools.javac.comp.Infer.InferenceContext;
     9.9  import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
    9.10  
    9.11 @@ -68,6 +69,7 @@
    9.12      private final Resolve rs;
    9.13      private final Symtab syms;
    9.14      private final Enter enter;
    9.15 +    private final DeferredAttr deferredAttr;
    9.16      private final Infer infer;
    9.17      private final Types types;
    9.18      private final JCDiagnostic.Factory diags;
    9.19 @@ -100,6 +102,7 @@
    9.20          rs = Resolve.instance(context);
    9.21          syms = Symtab.instance(context);
    9.22          enter = Enter.instance(context);
    9.23 +        deferredAttr = DeferredAttr.instance(context);
    9.24          infer = Infer.instance(context);
    9.25          this.types = Types.instance(context);
    9.26          diags = JCDiagnostic.Factory.instance(context);
    9.27 @@ -433,6 +436,8 @@
    9.28          public Warner checkWarner(DiagnosticPosition pos, Type found, Type req);
    9.29  
    9.30          public Infer.InferenceContext inferenceContext();
    9.31 +
    9.32 +        public DeferredAttr.DeferredAttrContext deferredAttrContext();
    9.33      }
    9.34  
    9.35      /**
    9.36 @@ -463,6 +468,10 @@
    9.37          public Infer.InferenceContext inferenceContext() {
    9.38              return enclosingContext.inferenceContext();
    9.39          }
    9.40 +
    9.41 +        public DeferredAttrContext deferredAttrContext() {
    9.42 +            return enclosingContext.deferredAttrContext();
    9.43 +        }
    9.44      }
    9.45  
    9.46      /**
    9.47 @@ -483,6 +492,10 @@
    9.48          public InferenceContext inferenceContext() {
    9.49              return infer.emptyContext;
    9.50          }
    9.51 +
    9.52 +        public DeferredAttrContext deferredAttrContext() {
    9.53 +            return deferredAttr.emptyDeferredAttrContext;
    9.54 +        }
    9.55      };
    9.56  
    9.57      /** Check that a given type is assignable to a given proto-type.
    9.58 @@ -817,6 +830,8 @@
    9.59                  sym.owner == syms.enumSym)
    9.60                  formals = formals.tail.tail;
    9.61          List<JCExpression> args = argtrees;
    9.62 +        DeferredAttr.DeferredTypeMap checkDeferredMap =
    9.63 +                deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
    9.64          while (formals.head != last) {
    9.65              JCTree arg = args.head;
    9.66              Warner warn = convertWarner(arg.pos(), arg.type, formals.head);
    9.67 @@ -835,7 +850,7 @@
    9.68          } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
    9.69              // non-varargs call to varargs method
    9.70              Type varParam = owntype.getParameterTypes().last();
    9.71 -            Type lastArg = argtypes.last();
    9.72 +            Type lastArg = checkDeferredMap.apply(argtypes.last());
    9.73              if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
    9.74                      !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
    9.75                  log.warning(argtrees.last().pos(), "inexact.non-varargs.call",
    9.76 @@ -847,7 +862,7 @@
    9.77                      kindName(sym),
    9.78                      sym.name,
    9.79                      rs.methodArguments(sym.type.getParameterTypes()),
    9.80 -                    rs.methodArguments(argtypes),
    9.81 +                    rs.methodArguments(Type.map(argtypes, checkDeferredMap)),
    9.82                      kindName(sym.location()),
    9.83                      sym.location());
    9.84             owntype = new MethodType(owntype.getParameterTypes(),
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Oct 04 13:04:53 2012 +0100
    10.3 @@ -0,0 +1,553 @@
    10.4 +/*
    10.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
    10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 + *
    10.8 + * This code is free software; you can redistribute it and/or modify it
    10.9 + * under the terms of the GNU General Public License version 2 only, as
   10.10 + * published by the Free Software Foundation.  Oracle designates this
   10.11 + * particular file as subject to the "Classpath" exception as provided
   10.12 + * by Oracle in the LICENSE file that accompanied this code.
   10.13 + *
   10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.17 + * version 2 for more details (a copy is included in the LICENSE file that
   10.18 + * accompanied this code).
   10.19 + *
   10.20 + * You should have received a copy of the GNU General Public License version
   10.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.23 + *
   10.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   10.25 + * or visit www.oracle.com if you need additional information or have any
   10.26 + * questions.
   10.27 + */
   10.28 +
   10.29 +package com.sun.tools.javac.comp;
   10.30 +
   10.31 +import com.sun.tools.javac.code.*;
   10.32 +import com.sun.tools.javac.tree.*;
   10.33 +import com.sun.tools.javac.util.*;
   10.34 +import com.sun.tools.javac.code.Symbol.*;
   10.35 +import com.sun.tools.javac.code.Type.*;
   10.36 +import com.sun.tools.javac.comp.Attr.ResultInfo;
   10.37 +import com.sun.tools.javac.comp.Infer.InferenceContext;
   10.38 +import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase;
   10.39 +import com.sun.tools.javac.tree.JCTree.*;
   10.40 +
   10.41 +import javax.tools.JavaFileObject;
   10.42 +
   10.43 +import java.util.ArrayList;
   10.44 +import java.util.HashSet;
   10.45 +import java.util.Map;
   10.46 +import java.util.Queue;
   10.47 +import java.util.Set;
   10.48 +import java.util.WeakHashMap;
   10.49 +
   10.50 +import static com.sun.tools.javac.code.TypeTags.*;
   10.51 +import static com.sun.tools.javac.tree.JCTree.Tag.*;
   10.52 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
   10.53 +
   10.54 +/**
   10.55 + * This is an helper class that is used to perform deferred type-analysis.
   10.56 + * Each time a poly expression occurs in argument position, javac attributes it
   10.57 + * with a temporary 'deferred type' that is checked (possibly multiple times)
   10.58 + * against an expected formal type.
   10.59 + *
   10.60 + *  <p><b>This is NOT part of any supported API.
   10.61 + *  If you write code that depends on this, you do so at your own risk.
   10.62 + *  This code and its internal interfaces are subject to change or
   10.63 + *  deletion without notice.</b>
   10.64 + */
   10.65 +public class DeferredAttr extends JCTree.Visitor {
   10.66 +    protected static final Context.Key<DeferredAttr> deferredAttrKey =
   10.67 +        new Context.Key<DeferredAttr>();
   10.68 +
   10.69 +    final Attr attr;
   10.70 +    final Check chk;
   10.71 +    final Enter enter;
   10.72 +    final Infer infer;
   10.73 +    final Log log;
   10.74 +    final Symtab syms;
   10.75 +    final TreeMaker make;
   10.76 +    final Types types;
   10.77 +
   10.78 +    public static DeferredAttr instance(Context context) {
   10.79 +        DeferredAttr instance = context.get(deferredAttrKey);
   10.80 +        if (instance == null)
   10.81 +            instance = new DeferredAttr(context);
   10.82 +        return instance;
   10.83 +    }
   10.84 +
   10.85 +    protected DeferredAttr(Context context) {
   10.86 +        context.put(deferredAttrKey, this);
   10.87 +        attr = Attr.instance(context);
   10.88 +        chk = Check.instance(context);
   10.89 +        enter = Enter.instance(context);
   10.90 +        infer = Infer.instance(context);
   10.91 +        log = Log.instance(context);
   10.92 +        syms = Symtab.instance(context);
   10.93 +        make = TreeMaker.instance(context);
   10.94 +        types = Types.instance(context);
   10.95 +    }
   10.96 +
   10.97 +    /**
   10.98 +     * This type represents a deferred type. A deferred type starts off with
   10.99 +     * no information on the underlying expression type. Such info needs to be
  10.100 +     * discovered through type-checking the deferred type against a target-type.
  10.101 +     * Every deferred type keeps a pointer to the AST node from which it originated.
  10.102 +     */
  10.103 +    public class DeferredType extends Type {
  10.104 +
  10.105 +        public JCExpression tree;
  10.106 +        Env<AttrContext> env;
  10.107 +        AttrMode mode;
  10.108 +        SpeculativeCache speculativeCache;
  10.109 +
  10.110 +        DeferredType(JCExpression tree, Env<AttrContext> env) {
  10.111 +            super(DEFERRED, null);
  10.112 +            this.tree = tree;
  10.113 +            this.env = env.dup(tree, env.info.dup());
  10.114 +            this.speculativeCache = new SpeculativeCache();
  10.115 +        }
  10.116 +
  10.117 +        /**
  10.118 +         * A speculative cache is used to keep track of all overload resolution rounds
  10.119 +         * that triggered speculative attribution on a given deferred type. Each entry
  10.120 +         * stores a pointer to the speculative tree and the resolution phase in which the entry
  10.121 +         * has been added.
  10.122 +         */
  10.123 +        class SpeculativeCache {
  10.124 +
  10.125 +            private Map<Symbol, List<Entry>> cache =
  10.126 +                    new WeakHashMap<Symbol, List<Entry>>();
  10.127 +
  10.128 +            class Entry {
  10.129 +                JCTree speculativeTree;
  10.130 +                Resolve.MethodResolutionPhase phase;
  10.131 +
  10.132 +                public Entry(JCTree speculativeTree, MethodResolutionPhase phase) {
  10.133 +                    this.speculativeTree = speculativeTree;
  10.134 +                    this.phase = phase;
  10.135 +                }
  10.136 +
  10.137 +                boolean matches(Resolve.MethodResolutionPhase phase) {
  10.138 +                    return this.phase == phase;
  10.139 +                }
  10.140 +            }
  10.141 +
  10.142 +            /**
  10.143 +             * Clone a speculative cache entry as a fresh entry associated
  10.144 +             * with a new method (this maybe required to fixup speculative cache
  10.145 +             * misses after Resolve.access())
  10.146 +             */
  10.147 +            void dupAllTo(Symbol from, Symbol to) {
  10.148 +                Assert.check(cache.get(to) == null);
  10.149 +                List<Entry> entries = cache.get(from);
  10.150 +                if (entries != null) {
  10.151 +                    cache.put(to, entries);
  10.152 +                }
  10.153 +            }
  10.154 +
  10.155 +            /**
  10.156 +             * Retrieve a speculative cache entry corresponding to given symbol
  10.157 +             * and resolution phase
  10.158 +             */
  10.159 +            Entry get(Symbol msym, MethodResolutionPhase phase) {
  10.160 +                List<Entry> entries = cache.get(msym);
  10.161 +                if (entries == null) return null;
  10.162 +                for (Entry e : entries) {
  10.163 +                    if (e.matches(phase)) return e;
  10.164 +                }
  10.165 +                return null;
  10.166 +            }
  10.167 +
  10.168 +            /**
  10.169 +             * Stores a speculative cache entry corresponding to given symbol
  10.170 +             * and resolution phase
  10.171 +             */
  10.172 +            void put(Symbol msym, JCTree speculativeTree, MethodResolutionPhase phase) {
  10.173 +                List<Entry> entries = cache.get(msym);
  10.174 +                if (entries == null) {
  10.175 +                    entries = List.nil();
  10.176 +                }
  10.177 +                cache.put(msym, entries.prepend(new Entry(speculativeTree, phase)));
  10.178 +            }
  10.179 +        }
  10.180 +
  10.181 +        /**
  10.182 +         * Get the type that has been computed during a speculative attribution round
  10.183 +         */
  10.184 +        Type speculativeType(Symbol msym, MethodResolutionPhase phase) {
  10.185 +            SpeculativeCache.Entry e = speculativeCache.get(msym, phase);
  10.186 +            return e != null ? e.speculativeTree.type : Type.noType;
  10.187 +        }
  10.188 +
  10.189 +        /**
  10.190 +         * Check a deferred type against a potential target-type. Depending on
  10.191 +         * the current attribution mode, a normal vs. speculative attribution
  10.192 +         * round is performed on the underlying AST node. There can be only one
  10.193 +         * speculative round for a given target method symbol; moreover, a normal
  10.194 +         * attribution round must follow one or more speculative rounds.
  10.195 +         */
  10.196 +        Type check(ResultInfo resultInfo) {
  10.197 +            DeferredAttrContext deferredAttrContext =
  10.198 +                    resultInfo.checkContext.deferredAttrContext();
  10.199 +            Assert.check(deferredAttrContext != emptyDeferredAttrContext);
  10.200 +            List<Type> stuckVars = stuckVars(tree, resultInfo);
  10.201 +            if (stuckVars.nonEmpty()) {
  10.202 +                deferredAttrContext.addDeferredAttrNode(this, resultInfo, stuckVars);
  10.203 +                return Type.noType;
  10.204 +            } else {
  10.205 +                try {
  10.206 +                    switch (deferredAttrContext.mode) {
  10.207 +                        case SPECULATIVE:
  10.208 +                            Assert.check(mode == null ||
  10.209 +                                    (mode == AttrMode.SPECULATIVE &&
  10.210 +                                    speculativeType(deferredAttrContext.msym, deferredAttrContext.phase).tag == NONE));
  10.211 +                            JCTree speculativeTree = attribSpeculative(tree, env, resultInfo);
  10.212 +                            speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase);
  10.213 +                            return speculativeTree.type;
  10.214 +                        case CHECK:
  10.215 +                            Assert.check(mode == AttrMode.SPECULATIVE);
  10.216 +                            return attr.attribTree(tree, env, resultInfo);
  10.217 +                    }
  10.218 +                    Assert.error();
  10.219 +                    return null;
  10.220 +                } finally {
  10.221 +                    mode = deferredAttrContext.mode;
  10.222 +                }
  10.223 +            }
  10.224 +        }
  10.225 +    }
  10.226 +
  10.227 +    /**
  10.228 +     * The 'mode' in which the deferred type is to be type-checked
  10.229 +     */
  10.230 +    public enum AttrMode {
  10.231 +        /**
  10.232 +         * A speculative type-checking round is used during overload resolution
  10.233 +         * mainly to generate constraints on inference variables. Side-effects
  10.234 +         * arising from type-checking the expression associated with the deferred
  10.235 +         * type are reversed after the speculative round finishes. This means the
  10.236 +         * expression tree will be left in a blank state.
  10.237 +         */
  10.238 +        SPECULATIVE,
  10.239 +        /**
  10.240 +         * This is the plain type-checking mode. Produces side-effects on the underlying AST node
  10.241 +         */
  10.242 +        CHECK;
  10.243 +    }
  10.244 +
  10.245 +    /**
  10.246 +     * Routine that performs speculative type-checking; the input AST node is
  10.247 +     * cloned (to avoid side-effects cause by Attr) and compiler state is
  10.248 +     * restored after type-checking. All diagnostics (but critical ones) are
  10.249 +     * disabled during speculative type-checking.
  10.250 +     */
  10.251 +    JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
  10.252 +        JCTree newTree = new TreeCopier<Object>(make).copy(tree);
  10.253 +        Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared()));
  10.254 +        speculativeEnv.info.scope.owner = env.info.scope.owner;
  10.255 +        Filter<JCDiagnostic> prevDeferDiagsFilter = log.deferredDiagFilter;
  10.256 +        Queue<JCDiagnostic> prevDeferredDiags = log.deferredDiagnostics;
  10.257 +        final JavaFileObject currentSource = log.currentSourceFile();
  10.258 +        try {
  10.259 +            log.deferredDiagnostics = new ListBuffer<JCDiagnostic>();
  10.260 +            log.deferredDiagFilter = new Filter<JCDiagnostic>() {
  10.261 +                public boolean accepts(JCDiagnostic t) {
  10.262 +                    return t.getDiagnosticSource().getFile().equals(currentSource);
  10.263 +                }
  10.264 +            };
  10.265 +            attr.attribTree(newTree, speculativeEnv, resultInfo);
  10.266 +            unenterScanner.scan(newTree);
  10.267 +            return newTree;
  10.268 +        } catch (Abort ex) {
  10.269 +            //if some very bad condition occurred during deferred attribution
  10.270 +            //we should dump all errors before killing javac
  10.271 +            log.reportDeferredDiagnostics();
  10.272 +            throw ex;
  10.273 +        } finally {
  10.274 +            unenterScanner.scan(newTree);
  10.275 +            log.deferredDiagFilter = prevDeferDiagsFilter;
  10.276 +            log.deferredDiagnostics = prevDeferredDiags;
  10.277 +        }
  10.278 +    }
  10.279 +    //where
  10.280 +        protected TreeScanner unenterScanner = new TreeScanner() {
  10.281 +            @Override
  10.282 +            public void visitClassDef(JCClassDecl tree) {
  10.283 +                ClassSymbol csym = tree.sym;
  10.284 +                enter.typeEnvs.remove(csym);
  10.285 +                chk.compiled.remove(csym.flatname);
  10.286 +                syms.classes.remove(csym.flatname);
  10.287 +                super.visitClassDef(tree);
  10.288 +            }
  10.289 +        };
  10.290 +
  10.291 +    /**
  10.292 +     * A deferred context is created on each method check. A deferred context is
  10.293 +     * used to keep track of information associated with the method check, such as
  10.294 +     * the symbol of the method being checked, the overload resolution phase,
  10.295 +     * the kind of attribution mode to be applied to deferred types and so forth.
  10.296 +     * As deferred types are processed (by the method check routine) stuck AST nodes
  10.297 +     * are added (as new deferred attribution nodes) to this context. The complete()
  10.298 +     * routine makes sure that all pending nodes are properly processed, by
  10.299 +     * progressively instantiating all inference variables on which one or more
  10.300 +     * deferred attribution node is stuck.
  10.301 +     */
  10.302 +    class DeferredAttrContext {
  10.303 +
  10.304 +        /** attribution mode */
  10.305 +        final AttrMode mode;
  10.306 +
  10.307 +        /** symbol of the method being checked */
  10.308 +        final Symbol msym;
  10.309 +
  10.310 +        /** method resolution step */
  10.311 +        final Resolve.MethodResolutionPhase phase;
  10.312 +
  10.313 +        /** inference context */
  10.314 +        final InferenceContext inferenceContext;
  10.315 +
  10.316 +        /** list of deferred attribution nodes to be processed */
  10.317 +        ArrayList<DeferredAttrNode> deferredAttrNodes = new ArrayList<DeferredAttrNode>();
  10.318 +
  10.319 +        DeferredAttrContext(AttrMode mode, Symbol msym, MethodResolutionPhase phase, InferenceContext inferenceContext) {
  10.320 +            this.mode = mode;
  10.321 +            this.msym = msym;
  10.322 +            this.phase = phase;
  10.323 +            this.inferenceContext = inferenceContext;
  10.324 +        }
  10.325 +
  10.326 +        /**
  10.327 +         * Adds a node to the list of deferred attribution nodes - used by Resolve.rawCheckArgumentsApplicable
  10.328 +         * Nodes added this way act as 'roots' for the out-of-order method checking process.
  10.329 +         */
  10.330 +        void addDeferredAttrNode(final DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
  10.331 +            deferredAttrNodes.add(new DeferredAttrNode(dt, resultInfo, stuckVars));
  10.332 +        }
  10.333 +
  10.334 +        /**
  10.335 +         * Incrementally process all nodes, by skipping 'stuck' nodes and attributing
  10.336 +         * 'unstuck' ones. If at any point no progress can be made (no 'unstuck' nodes)
  10.337 +         * some inference variable might get eagerly instantiated so that all nodes
  10.338 +         * can be type-checked.
  10.339 +         */
  10.340 +        void complete() {
  10.341 +            while (!deferredAttrNodes.isEmpty()) {
  10.342 +                Set<Type> stuckVars = new HashSet<Type>();
  10.343 +                boolean progress = false;
  10.344 +                //scan a defensive copy of the node list - this is because a deferred
  10.345 +                //attribution round can add new nodes to the list
  10.346 +                for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) {
  10.347 +                    if (!deferredAttrNode.isStuck()) {
  10.348 +                        deferredAttrNode.process();
  10.349 +                        deferredAttrNodes.remove(deferredAttrNode);
  10.350 +                        progress = true;
  10.351 +                    } else {
  10.352 +                        stuckVars.addAll(deferredAttrNode.stuckVars);
  10.353 +                    }
  10.354 +                }
  10.355 +                if (!progress) {
  10.356 +                    //remove all variables that have already been instantiated
  10.357 +                    //from the list of stuck variables
  10.358 +                    inferenceContext.solveAny(inferenceContext.freeVarsIn(List.from(stuckVars)), types, infer);
  10.359 +                    inferenceContext.notifyChange(types);
  10.360 +                }
  10.361 +            }
  10.362 +        }
  10.363 +
  10.364 +        /**
  10.365 +         * Class representing a deferred attribution node. It keeps track of
  10.366 +         * a deferred type, along with the expected target type information.
  10.367 +         */
  10.368 +        class DeferredAttrNode implements Infer.InferenceContext.FreeTypeListener {
  10.369 +
  10.370 +            /** underlying deferred type */
  10.371 +            DeferredType dt;
  10.372 +
  10.373 +            /** underlying target type information */
  10.374 +            ResultInfo resultInfo;
  10.375 +
  10.376 +            /** list of uninferred inference variables causing this node to be stuck */
  10.377 +            List<Type> stuckVars;
  10.378 +
  10.379 +            DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
  10.380 +                this.dt = dt;
  10.381 +                this.resultInfo = resultInfo;
  10.382 +                this.stuckVars = stuckVars;
  10.383 +                if (!stuckVars.isEmpty()) {
  10.384 +                    resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this);
  10.385 +                }
  10.386 +            }
  10.387 +
  10.388 +            @Override
  10.389 +            public void typesInferred(InferenceContext inferenceContext) {
  10.390 +                stuckVars = List.nil();
  10.391 +                resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt, types));
  10.392 +            }
  10.393 +
  10.394 +            /**
  10.395 +             * is this node stuck?
  10.396 +             */
  10.397 +            boolean isStuck() {
  10.398 +                return stuckVars.nonEmpty();
  10.399 +            }
  10.400 +
  10.401 +            /**
  10.402 +             * Process a deferred attribution node.
  10.403 +             * Invariant: a stuck node cannot be processed.
  10.404 +             */
  10.405 +            void process() {
  10.406 +                if (isStuck()) {
  10.407 +                    throw new IllegalStateException("Cannot process a stuck deferred node");
  10.408 +                }
  10.409 +                dt.check(resultInfo);
  10.410 +            }
  10.411 +        }
  10.412 +    }
  10.413 +
  10.414 +    /** an empty deferred attribution context - all methods throw exceptions */
  10.415 +    final DeferredAttrContext emptyDeferredAttrContext =
  10.416 +            new DeferredAttrContext(null, null, null, null) {
  10.417 +                @Override
  10.418 +                void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) {
  10.419 +                    Assert.error("Empty deferred context!");
  10.420 +                }
  10.421 +                @Override
  10.422 +                void complete() {
  10.423 +                    Assert.error("Empty deferred context!");
  10.424 +                }
  10.425 +            };
  10.426 +
  10.427 +    /**
  10.428 +     * Map a list of types possibly containing one or more deferred types
  10.429 +     * into a list of ordinary types. Each deferred type D is mapped into a type T,
  10.430 +     * where T is computed by retrieving the type that has already been
  10.431 +     * computed for D during a previous deferred attribution round of the given kind.
  10.432 +     */
  10.433 +    class DeferredTypeMap extends Type.Mapping {
  10.434 +
  10.435 +        DeferredAttrContext deferredAttrContext;
  10.436 +
  10.437 +        protected DeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) {
  10.438 +            super(String.format("deferredTypeMap[%s]", mode));
  10.439 +            this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase, infer.emptyContext);
  10.440 +        }
  10.441 +
  10.442 +        protected boolean validState(DeferredType dt) {
  10.443 +            return dt.mode != null &&
  10.444 +                    deferredAttrContext.mode.ordinal() <= dt.mode.ordinal();
  10.445 +        }
  10.446 +
  10.447 +        @Override
  10.448 +        public Type apply(Type t) {
  10.449 +            if (t.tag != DEFERRED) {
  10.450 +                return t.map(this);
  10.451 +            } else {
  10.452 +                DeferredType dt = (DeferredType)t;
  10.453 +                Assert.check(validState(dt));
  10.454 +                return typeOf(dt);
  10.455 +            }
  10.456 +        }
  10.457 +
  10.458 +        protected Type typeOf(DeferredType dt) {
  10.459 +            switch (deferredAttrContext.mode) {
  10.460 +                case CHECK:
  10.461 +                    return dt.tree.type == null ? Type.noType : dt.tree.type;
  10.462 +                case SPECULATIVE:
  10.463 +                    return dt.speculativeType(deferredAttrContext.msym, deferredAttrContext.phase);
  10.464 +            }
  10.465 +            Assert.error();
  10.466 +            return null;
  10.467 +        }
  10.468 +    }
  10.469 +
  10.470 +    /**
  10.471 +     * Specialized recovery deferred mapping.
  10.472 +     * Each deferred type D is mapped into a type T, where T is computed either by
  10.473 +     * (i) retrieving the type that has already been computed for D during a previous
  10.474 +     * attribution round (as before), or (ii) by synthesizing a new type R for D
  10.475 +     * (the latter step is useful in a recovery scenario).
  10.476 +     */
  10.477 +    public class RecoveryDeferredTypeMap extends DeferredTypeMap {
  10.478 +
  10.479 +        public RecoveryDeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) {
  10.480 +            super(mode, msym, phase);
  10.481 +        }
  10.482 +
  10.483 +        @Override
  10.484 +        protected Type typeOf(DeferredType dt) {
  10.485 +            Type owntype = super.typeOf(dt);
  10.486 +            return owntype.tag == NONE ?
  10.487 +                        recover(dt) : owntype;
  10.488 +        }
  10.489 +
  10.490 +        @Override
  10.491 +        protected boolean validState(DeferredType dt) {
  10.492 +            return true;
  10.493 +        }
  10.494 +
  10.495 +        /**
  10.496 +         * Synthesize a type for a deferred type that hasn't been previously
  10.497 +         * reduced to an ordinary type. Functional deferred types and conditionals
  10.498 +         * are mapped to themselves, in order to have a richer diagnostic
  10.499 +         * representation. Remaining deferred types are attributed using
  10.500 +         * a default expected type (j.l.Object).
  10.501 +         */
  10.502 +        private Type recover(DeferredType dt) {
  10.503 +            dt.check(new RecoveryInfo());
  10.504 +            switch (TreeInfo.skipParens(dt.tree).getTag()) {
  10.505 +                case LAMBDA:
  10.506 +                case REFERENCE:
  10.507 +                case CONDEXPR:
  10.508 +                    //propagate those deferred types to the
  10.509 +                    //diagnostic formatter
  10.510 +                    return dt;
  10.511 +                default:
  10.512 +                    return super.apply(dt);
  10.513 +            }
  10.514 +        }
  10.515 +
  10.516 +        class RecoveryInfo extends ResultInfo {
  10.517 +
  10.518 +            public RecoveryInfo() {
  10.519 +                attr.super(Kinds.VAL, Type.recoveryType, new Check.NestedCheckContext(chk.basicHandler) {
  10.520 +                    @Override
  10.521 +                    public DeferredAttrContext deferredAttrContext() {
  10.522 +                        return deferredAttrContext;
  10.523 +                    }
  10.524 +                    @Override
  10.525 +                    public boolean compatible(Type found, Type req, Warner warn) {
  10.526 +                        return true;
  10.527 +                    }
  10.528 +                    @Override
  10.529 +                    public void report(DiagnosticPosition pos, JCDiagnostic details) {
  10.530 +                        //do nothing
  10.531 +                    }
  10.532 +                });
  10.533 +            }
  10.534 +
  10.535 +            @Override
  10.536 +            protected Type check(DiagnosticPosition pos, Type found) {
  10.537 +                return chk.checkNonVoid(pos, super.check(pos, found));
  10.538 +            }
  10.539 +        }
  10.540 +    }
  10.541 +
  10.542 +    /**
  10.543 +     * Retrieves the list of inference variables that need to be inferred before
  10.544 +     * an AST node can be type-checked
  10.545 +     */
  10.546 +    @SuppressWarnings("fallthrough")
  10.547 +    List<Type> stuckVars(JCExpression tree, ResultInfo resultInfo) {
  10.548 +        switch (tree.getTag()) {
  10.549 +            case LAMBDA:
  10.550 +            case REFERENCE:
  10.551 +                Assert.error("not supported yet");
  10.552 +            default:
  10.553 +                return List.nil();
  10.554 +        }
  10.555 +    }
  10.556 +}
    11.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Sat Sep 29 09:00:58 2012 -0700
    11.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Oct 04 13:04:53 2012 +0100
    11.3 @@ -29,6 +29,7 @@
    11.4  import com.sun.tools.javac.code.Symbol.*;
    11.5  import com.sun.tools.javac.code.Type.*;
    11.6  import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
    11.7 +import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
    11.8  import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
    11.9  import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
   11.10  import com.sun.tools.javac.tree.JCTree;
   11.11 @@ -62,6 +63,7 @@
   11.12      Types types;
   11.13      Check chk;
   11.14      Resolve rs;
   11.15 +    DeferredAttr deferredAttr;
   11.16      Log log;
   11.17      JCDiagnostic.Factory diags;
   11.18  
   11.19 @@ -77,6 +79,7 @@
   11.20          syms = Symtab.instance(context);
   11.21          types = Types.instance(context);
   11.22          rs = Resolve.instance(context);
   11.23 +        deferredAttr = DeferredAttr.instance(context);
   11.24          log = Log.instance(context);
   11.25          chk = Check.instance(context);
   11.26          diags = JCDiagnostic.Factory.instance(context);
   11.27 @@ -187,7 +190,7 @@
   11.28              Attr.ResultInfo resultInfo,
   11.29              Warner warn) throws InferenceException {
   11.30          Type to = resultInfo.pt;
   11.31 -        if (to.tag == NONE) {
   11.32 +        if (to.tag == NONE || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
   11.33              to = mtype.getReturnType().tag <= VOID ?
   11.34                      mtype.getReturnType() : syms.objectType;
   11.35          }
   11.36 @@ -268,14 +271,16 @@
   11.37                                    List<Type> argtypes,
   11.38                                    boolean allowBoxing,
   11.39                                    boolean useVarargs,
   11.40 +                                  Resolve.MethodResolutionContext resolveContext,
   11.41                                    Warner warn) throws InferenceException {
   11.42          //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
   11.43          final InferenceContext inferenceContext = new InferenceContext(tvars, this);
   11.44          inferenceException.clear();
   11.45  
   11.46          try {
   11.47 -            rs.checkRawArgumentsAcceptable(env, inferenceContext, argtypes, mt.getParameterTypes(),
   11.48 -                    allowBoxing, useVarargs, warn, new InferenceCheckHandler(inferenceContext));
   11.49 +            rs.checkRawArgumentsAcceptable(env, msym, resolveContext.attrMode(), inferenceContext,
   11.50 +                    argtypes, mt.getParameterTypes(), allowBoxing, useVarargs, warn,
   11.51 +                    new InferenceCheckHandler(inferenceContext));
   11.52  
   11.53              // minimize as yet undetermined type variables
   11.54              for (Type t : inferenceContext.undetvars) {
   11.55 @@ -469,6 +474,7 @@
   11.56       */
   11.57      Type instantiatePolymorphicSignatureInstance(Env<AttrContext> env,
   11.58                                              MethodSymbol spMethod,  // sig. poly. method or null if none
   11.59 +                                            Resolve.MethodResolutionContext resolveContext,
   11.60                                              List<Type> argtypes) {
   11.61          final Type restype;
   11.62  
   11.63 @@ -498,7 +504,7 @@
   11.64                  restype = syms.objectType;
   11.65          }
   11.66  
   11.67 -        List<Type> paramtypes = Type.map(argtypes, implicitArgType);
   11.68 +        List<Type> paramtypes = Type.map(argtypes, new ImplicitArgType(spMethod, resolveContext.step));
   11.69          List<Type> exType = spMethod != null ?
   11.70              spMethod.getThrownTypes() :
   11.71              List.of(syms.throwableType); // make it throw all exceptions
   11.72 @@ -510,16 +516,21 @@
   11.73          return mtype;
   11.74      }
   11.75      //where
   11.76 -        Mapping implicitArgType = new Mapping ("implicitArgType") {
   11.77 -                public Type apply(Type t) {
   11.78 -                    t = types.erasure(t);
   11.79 -                    if (t.tag == BOT)
   11.80 -                        // nulls type as the marker type Null (which has no instances)
   11.81 -                        // infer as java.lang.Void for now
   11.82 -                        t = types.boxedClass(syms.voidType).type;
   11.83 -                    return t;
   11.84 -                }
   11.85 -        };
   11.86 +        class ImplicitArgType extends DeferredAttr.DeferredTypeMap {
   11.87 +
   11.88 +            public ImplicitArgType(Symbol msym, Resolve.MethodResolutionPhase phase) {
   11.89 +                deferredAttr.super(AttrMode.SPECULATIVE, msym, phase);
   11.90 +            }
   11.91 +
   11.92 +            public Type apply(Type t) {
   11.93 +                t = types.erasure(super.apply(t));
   11.94 +                if (t.tag == BOT)
   11.95 +                    // nulls type as the marker type Null (which has no instances)
   11.96 +                    // infer as java.lang.Void for now
   11.97 +                    t = types.boxedClass(syms.voidType).type;
   11.98 +                return t;
   11.99 +            }
  11.100 +        }
  11.101  
  11.102      /**
  11.103       * Mapping that turns inference variables into undet vars
  11.104 @@ -708,6 +719,22 @@
  11.105                  throw thrownEx;
  11.106              }
  11.107          }
  11.108 +
  11.109 +        void solveAny(List<Type> varsToSolve, Types types, Infer infer) {
  11.110 +            boolean progress = false;
  11.111 +            for (Type t : varsToSolve) {
  11.112 +                UndetVar uv = (UndetVar)asFree(t, types);
  11.113 +                if (uv.inst == null) {
  11.114 +                    infer.minimizeInst(uv, Warner.noWarnings);
  11.115 +                    if (uv.inst != null) {
  11.116 +                        progress = true;
  11.117 +                    }
  11.118 +                }
  11.119 +            }
  11.120 +            if (!progress) {
  11.121 +                throw infer.inferenceException.setMessage("cyclic.inference", varsToSolve);
  11.122 +            }
  11.123 +        }
  11.124      }
  11.125  
  11.126      final InferenceContext emptyContext = new InferenceContext(List.<Type>nil(), this);
    12.1 --- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Sat Sep 29 09:00:58 2012 -0700
    12.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Oct 04 13:04:53 2012 +0100
    12.3 @@ -1998,7 +1998,7 @@
    12.4              // replace with <BoxedClass>.TYPE
    12.5              ClassSymbol c = types.boxedClass(type);
    12.6              Symbol typeSym =
    12.7 -                rs.access(
    12.8 +                rs.accessBase(
    12.9                      rs.findIdentInType(attrEnv, c.type, names.TYPE, VAR),
   12.10                      pos, c.type, names.TYPE, true);
   12.11              if (typeSym.kind == VAR)
    13.1 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Sat Sep 29 09:00:58 2012 -0700
    13.2 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Oct 04 13:04:53 2012 +0100
    13.3 @@ -604,6 +604,10 @@
    13.4              env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
    13.5          localEnv.enclMethod = tree;
    13.6          localEnv.info.scope.owner = tree.sym;
    13.7 +        if (tree.sym.type != null) {
    13.8 +            //when this is called in the enter stage, there's no type to be set
    13.9 +            localEnv.info.returnResult = attr.new ResultInfo(VAL, tree.sym.type.getReturnType());
   13.10 +        }
   13.11          if ((tree.mods.flags & STATIC) != 0) localEnv.info.staticLevel++;
   13.12          return localEnv;
   13.13      }
    14.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Sat Sep 29 09:00:58 2012 -0700
    14.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Oct 04 13:04:53 2012 +0100
    14.3 @@ -31,6 +31,9 @@
    14.4  import com.sun.tools.javac.code.Type.*;
    14.5  import com.sun.tools.javac.comp.Attr.ResultInfo;
    14.6  import com.sun.tools.javac.comp.Check.CheckContext;
    14.7 +import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
    14.8 +import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
    14.9 +import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
   14.10  import com.sun.tools.javac.comp.Infer.InferenceContext;
   14.11  import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
   14.12  import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
   14.13 @@ -42,15 +45,12 @@
   14.14  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
   14.15  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
   14.16  
   14.17 -import java.util.ArrayList;
   14.18  import java.util.Arrays;
   14.19  import java.util.Collection;
   14.20  import java.util.EnumMap;
   14.21  import java.util.EnumSet;
   14.22 -import java.util.HashSet;
   14.23  import java.util.Iterator;
   14.24  import java.util.Map;
   14.25 -import java.util.Set;
   14.26  
   14.27  import javax.lang.model.element.ElementVisitor;
   14.28  
   14.29 @@ -77,6 +77,7 @@
   14.30      Log log;
   14.31      Symtab syms;
   14.32      Attr attr;
   14.33 +    DeferredAttr deferredAttr;
   14.34      Check chk;
   14.35      Infer infer;
   14.36      ClassReader reader;
   14.37 @@ -109,6 +110,7 @@
   14.38          names = Names.instance(context);
   14.39          log = Log.instance(context);
   14.40          attr = Attr.instance(context);
   14.41 +        deferredAttr = DeferredAttr.instance(context);
   14.42          chk = Check.instance(context);
   14.43          infer = Infer.instance(context);
   14.44          reader = ClassReader.instance(context);
   14.45 @@ -219,9 +221,12 @@
   14.46              }
   14.47          }
   14.48          String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
   14.49 +        List<Type> argtypes2 = Type.map(argtypes,
   14.50 +                    deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
   14.51          JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
   14.52                  site.tsym, mostSpecificPos, currentResolutionContext.step,
   14.53 -                methodArguments(argtypes), methodArguments(typeargtypes));
   14.54 +                methodArguments(argtypes2),
   14.55 +                methodArguments(typeargtypes));
   14.56          JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
   14.57          log.report(d);
   14.58      }
   14.59 @@ -501,13 +506,34 @@
   14.60                                      argtypes,
   14.61                                      allowBoxing,
   14.62                                      useVarargs,
   14.63 +                                    currentResolutionContext,
   14.64                                      warn);
   14.65  
   14.66 -        checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(),
   14.67 +        checkRawArgumentsAcceptable(env, m, argtypes, mt.getParameterTypes(),
   14.68                                  allowBoxing, useVarargs, warn);
   14.69          return mt;
   14.70      }
   14.71  
   14.72 +    Type checkMethod(Env<AttrContext> env,
   14.73 +                     Type site,
   14.74 +                     Symbol m,
   14.75 +                     ResultInfo resultInfo,
   14.76 +                     List<Type> argtypes,
   14.77 +                     List<Type> typeargtypes,
   14.78 +                     Warner warn) {
   14.79 +        MethodResolutionContext prevContext = currentResolutionContext;
   14.80 +        try {
   14.81 +            currentResolutionContext = new MethodResolutionContext();
   14.82 +            currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK;
   14.83 +            MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
   14.84 +            return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
   14.85 +                    step.isBoxingRequired(), step.isVarargsRequired(), warn);
   14.86 +        }
   14.87 +        finally {
   14.88 +            currentResolutionContext = prevContext;
   14.89 +        }
   14.90 +    }
   14.91 +
   14.92      /** Same but returns null instead throwing a NoInstanceException
   14.93       */
   14.94      Type instantiate(Env<AttrContext> env,
   14.95 @@ -530,13 +556,14 @@
   14.96      /** Check if a parameter list accepts a list of args.
   14.97       */
   14.98      boolean argumentsAcceptable(Env<AttrContext> env,
   14.99 +                                Symbol msym,
  14.100                                  List<Type> argtypes,
  14.101                                  List<Type> formals,
  14.102                                  boolean allowBoxing,
  14.103                                  boolean useVarargs,
  14.104                                  Warner warn) {
  14.105          try {
  14.106 -            checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn);
  14.107 +            checkRawArgumentsAcceptable(env, msym, argtypes, formals, allowBoxing, useVarargs, warn);
  14.108              return true;
  14.109          } catch (InapplicableMethodException ex) {
  14.110              return false;
  14.111 @@ -583,12 +610,13 @@
  14.112      };
  14.113  
  14.114      void checkRawArgumentsAcceptable(Env<AttrContext> env,
  14.115 +                                Symbol msym,
  14.116                                  List<Type> argtypes,
  14.117                                  List<Type> formals,
  14.118                                  boolean allowBoxing,
  14.119                                  boolean useVarargs,
  14.120                                  Warner warn) {
  14.121 -        checkRawArgumentsAcceptable(env, infer.emptyContext, argtypes, formals,
  14.122 +        checkRawArgumentsAcceptable(env, msym, currentResolutionContext.attrMode(), infer.emptyContext, argtypes, formals,
  14.123                  allowBoxing, useVarargs, warn, resolveHandler);
  14.124      }
  14.125  
  14.126 @@ -598,35 +626,41 @@
  14.127       * compatible (by method invocation conversion) with the types in F.
  14.128       *
  14.129       * Since this routine is shared between overload resolution and method
  14.130 -     * type-inference, it is crucial that actual types are converted to the
  14.131 -     * corresponding 'undet' form (i.e. where inference variables are replaced
  14.132 -     * with undetvars) so that constraints can be propagated and collected.
  14.133 +     * type-inference, a (possibly empty) inference context is used to convert
  14.134 +     * formal types to the corresponding 'undet' form ahead of a compatibility
  14.135 +     * check so that constraints can be propagated and collected.
  14.136       *
  14.137 -     * Moreover, if one or more types in A is a poly type, this routine calls
  14.138 -     * Infer.instantiateArg in order to complete the poly type (this might involve
  14.139 -     * deferred attribution).
  14.140 +     * Moreover, if one or more types in A is a deferred type, this routine uses
  14.141 +     * DeferredAttr in order to perform deferred attribution. If one or more actual
  14.142 +     * deferred types are stuck, they are placed in a queue and revisited later
  14.143 +     * after the remainder of the arguments have been seen. If this is not sufficient
  14.144 +     * to 'unstuck' the argument, a cyclic inference error is called out.
  14.145       *
  14.146       * A method check handler (see above) is used in order to report errors.
  14.147       */
  14.148      void checkRawArgumentsAcceptable(final Env<AttrContext> env,
  14.149 +                                Symbol msym,
  14.150 +                                DeferredAttr.AttrMode mode,
  14.151                                  final Infer.InferenceContext inferenceContext,
  14.152                                  List<Type> argtypes,
  14.153                                  List<Type> formals,
  14.154                                  boolean allowBoxing,
  14.155                                  boolean useVarargs,
  14.156                                  Warner warn,
  14.157 -                                MethodCheckHandler handler) {
  14.158 +                                final MethodCheckHandler handler) {
  14.159          Type varargsFormal = useVarargs ? formals.last() : null;
  14.160 -        ListBuffer<Type> checkedArgs = ListBuffer.lb();
  14.161  
  14.162          if (varargsFormal == null &&
  14.163                  argtypes.size() != formals.size()) {
  14.164              throw handler.arityMismatch(); // not enough args
  14.165          }
  14.166  
  14.167 +        DeferredAttr.DeferredAttrContext deferredAttrContext =
  14.168 +                deferredAttr.new DeferredAttrContext(mode, msym, currentResolutionContext.step, inferenceContext);
  14.169 +
  14.170          while (argtypes.nonEmpty() && formals.head != varargsFormal) {
  14.171 -            ResultInfo resultInfo = methodCheckResult(formals.head, allowBoxing, false, inferenceContext, handler, warn);
  14.172 -            checkedArgs.append(resultInfo.check(env.tree.pos(), argtypes.head));
  14.173 +            ResultInfo mresult = methodCheckResult(formals.head, allowBoxing, false, inferenceContext, deferredAttrContext, handler, warn);
  14.174 +            mresult.check(null, argtypes.head);
  14.175              argtypes = argtypes.tail;
  14.176              formals = formals.tail;
  14.177          }
  14.178 @@ -638,15 +672,17 @@
  14.179          if (useVarargs) {
  14.180              //note: if applicability check is triggered by most specific test,
  14.181              //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
  14.182 -            Type elt = types.elemtype(varargsFormal);
  14.183 +            final Type elt = types.elemtype(varargsFormal);
  14.184 +            ResultInfo mresult = methodCheckResult(elt, allowBoxing, true, inferenceContext, deferredAttrContext, handler, warn);
  14.185              while (argtypes.nonEmpty()) {
  14.186 -                ResultInfo resultInfo = methodCheckResult(elt, allowBoxing, true, inferenceContext, handler, warn);
  14.187 -                checkedArgs.append(resultInfo.check(env.tree.pos(), argtypes.head));
  14.188 +                mresult.check(null, argtypes.head);
  14.189                  argtypes = argtypes.tail;
  14.190              }
  14.191              //check varargs element type accessibility
  14.192              varargsAccessible(env, elt, handler, inferenceContext);
  14.193          }
  14.194 +
  14.195 +        deferredAttrContext.complete();
  14.196      }
  14.197  
  14.198      void varargsAccessible(final Env<AttrContext> env, final Type t, final Resolve.MethodCheckHandler handler, final InferenceContext inferenceContext) {
  14.199 @@ -674,12 +710,15 @@
  14.200          MethodCheckHandler handler;
  14.201          boolean useVarargs;
  14.202          Infer.InferenceContext inferenceContext;
  14.203 +        DeferredAttrContext deferredAttrContext;
  14.204          Warner rsWarner;
  14.205  
  14.206 -        public MethodCheckContext(MethodCheckHandler handler, boolean useVarargs, Infer.InferenceContext inferenceContext, Warner rsWarner) {
  14.207 +        public MethodCheckContext(MethodCheckHandler handler, boolean useVarargs,
  14.208 +                Infer.InferenceContext inferenceContext, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
  14.209              this.handler = handler;
  14.210              this.useVarargs = useVarargs;
  14.211              this.inferenceContext = inferenceContext;
  14.212 +            this.deferredAttrContext = deferredAttrContext;
  14.213              this.rsWarner = rsWarner;
  14.214          }
  14.215  
  14.216 @@ -694,6 +733,10 @@
  14.217          public InferenceContext inferenceContext() {
  14.218              return inferenceContext;
  14.219          }
  14.220 +
  14.221 +        public DeferredAttrContext deferredAttrContext() {
  14.222 +            return deferredAttrContext;
  14.223 +        }
  14.224      }
  14.225  
  14.226      /**
  14.227 @@ -702,8 +745,9 @@
  14.228       */
  14.229      class StrictMethodContext extends MethodCheckContext {
  14.230  
  14.231 -        public StrictMethodContext(MethodCheckHandler handler, boolean useVarargs, Infer.InferenceContext inferenceContext, Warner rsWarner) {
  14.232 -            super(handler, useVarargs, inferenceContext, rsWarner);
  14.233 +        public StrictMethodContext(MethodCheckHandler handler, boolean useVarargs,
  14.234 +                Infer.InferenceContext inferenceContext, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
  14.235 +            super(handler, useVarargs, inferenceContext, deferredAttrContext, rsWarner);
  14.236          }
  14.237  
  14.238          public boolean compatible(Type found, Type req, Warner warn) {
  14.239 @@ -717,8 +761,9 @@
  14.240       */
  14.241      class LooseMethodContext extends MethodCheckContext {
  14.242  
  14.243 -        public LooseMethodContext(MethodCheckHandler handler, boolean useVarargs, Infer.InferenceContext inferenceContext, Warner rsWarner) {
  14.244 -            super(handler, useVarargs, inferenceContext, rsWarner);
  14.245 +        public LooseMethodContext(MethodCheckHandler handler, boolean useVarargs,
  14.246 +                Infer.InferenceContext inferenceContext, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
  14.247 +            super(handler, useVarargs, inferenceContext, deferredAttrContext, rsWarner);
  14.248          }
  14.249  
  14.250          public boolean compatible(Type found, Type req, Warner warn) {
  14.251 @@ -730,16 +775,37 @@
  14.252       * Create a method check context to be used during method applicability check
  14.253       */
  14.254      ResultInfo methodCheckResult(Type to, boolean allowBoxing, boolean useVarargs,
  14.255 -            Infer.InferenceContext inferenceContext, MethodCheckHandler methodHandler, Warner rsWarner) {
  14.256 +            Infer.InferenceContext inferenceContext, DeferredAttr.DeferredAttrContext deferredAttrContext,
  14.257 +            MethodCheckHandler methodHandler, Warner rsWarner) {
  14.258          MethodCheckContext checkContext = allowBoxing ?
  14.259 -                new LooseMethodContext(methodHandler, useVarargs, inferenceContext, rsWarner) :
  14.260 -                new StrictMethodContext(methodHandler, useVarargs, inferenceContext, rsWarner);
  14.261 -        return attr.new ResultInfo(VAL, to, checkContext) {
  14.262 -            @Override
  14.263 -            protected Type check(DiagnosticPosition pos, Type found) {
  14.264 +                new LooseMethodContext(methodHandler, useVarargs, inferenceContext, deferredAttrContext, rsWarner) :
  14.265 +                new StrictMethodContext(methodHandler, useVarargs, inferenceContext, deferredAttrContext, rsWarner);
  14.266 +        return new MethodResultInfo(to, checkContext, deferredAttrContext);
  14.267 +    }
  14.268 +
  14.269 +    class MethodResultInfo extends ResultInfo {
  14.270 +
  14.271 +        DeferredAttr.DeferredAttrContext deferredAttrContext;
  14.272 +
  14.273 +        public MethodResultInfo(Type pt, MethodCheckContext checkContext, DeferredAttr.DeferredAttrContext deferredAttrContext) {
  14.274 +            attr.super(VAL, pt, checkContext);
  14.275 +            this.deferredAttrContext = deferredAttrContext;
  14.276 +        }
  14.277 +
  14.278 +        @Override
  14.279 +        protected Type check(DiagnosticPosition pos, Type found) {
  14.280 +            if (found.tag == DEFERRED) {
  14.281 +                DeferredType dt = (DeferredType)found;
  14.282 +                return dt.check(this);
  14.283 +            } else {
  14.284                  return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found.baseType()))));
  14.285              }
  14.286 -        };
  14.287 +        }
  14.288 +
  14.289 +        @Override
  14.290 +        protected MethodResultInfo dup(Type newPt) {
  14.291 +            return new MethodResultInfo(newPt, (MethodCheckContext)checkContext, deferredAttrContext);
  14.292 +        }
  14.293      }
  14.294  
  14.295      public static class InapplicableMethodException extends RuntimeException {
  14.296 @@ -1614,14 +1680,41 @@
  14.297       *
  14.298       *  @param sym       The symbol that was found, or a ResolveError.
  14.299       *  @param pos       The position to use for error reporting.
  14.300 +     *  @param location  The symbol the served as a context for this lookup
  14.301       *  @param site      The original type from where the selection took place.
  14.302       *  @param name      The symbol's name.
  14.303 +     *  @param qualified Did we get here through a qualified expression resolution?
  14.304       *  @param argtypes  The invocation's value arguments,
  14.305       *                   if we looked for a method.
  14.306       *  @param typeargtypes  The invocation's type arguments,
  14.307       *                   if we looked for a method.
  14.308 +     *  @param logResolveHelper helper class used to log resolve errors
  14.309       */
  14.310 -    Symbol access(Symbol sym,
  14.311 +    Symbol accessInternal(Symbol sym,
  14.312 +                  DiagnosticPosition pos,
  14.313 +                  Symbol location,
  14.314 +                  Type site,
  14.315 +                  Name name,
  14.316 +                  boolean qualified,
  14.317 +                  List<Type> argtypes,
  14.318 +                  List<Type> typeargtypes,
  14.319 +                  LogResolveHelper logResolveHelper) {
  14.320 +        if (sym.kind >= AMBIGUOUS) {
  14.321 +            ResolveError errSym = (ResolveError)sym;
  14.322 +            sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
  14.323 +            argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
  14.324 +            if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
  14.325 +                logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
  14.326 +            }
  14.327 +        }
  14.328 +        return sym;
  14.329 +    }
  14.330 +
  14.331 +    /**
  14.332 +     * Variant of the generalized access routine, to be used for generating method
  14.333 +     * resolution diagnostics
  14.334 +     */
  14.335 +    Symbol accessMethod(Symbol sym,
  14.336                    DiagnosticPosition pos,
  14.337                    Symbol location,
  14.338                    Type site,
  14.339 @@ -1629,53 +1722,91 @@
  14.340                    boolean qualified,
  14.341                    List<Type> argtypes,
  14.342                    List<Type> typeargtypes) {
  14.343 -        if (sym.kind >= AMBIGUOUS) {
  14.344 -            ResolveError errSym = (ResolveError)sym;
  14.345 -            if (!site.isErroneous() &&
  14.346 -                !Type.isErroneous(argtypes) &&
  14.347 -                (typeargtypes==null || !Type.isErroneous(typeargtypes)))
  14.348 -                logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
  14.349 -            sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
  14.350 -        }
  14.351 -        return sym;
  14.352 +        return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
  14.353      }
  14.354  
  14.355 -    /** Same as original access(), but without location.
  14.356 +    /** Same as original accessMethod(), but without location.
  14.357       */
  14.358 -    Symbol access(Symbol sym,
  14.359 +    Symbol accessMethod(Symbol sym,
  14.360                    DiagnosticPosition pos,
  14.361                    Type site,
  14.362                    Name name,
  14.363                    boolean qualified,
  14.364                    List<Type> argtypes,
  14.365                    List<Type> typeargtypes) {
  14.366 -        return access(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
  14.367 +        return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
  14.368      }
  14.369  
  14.370 -    /** Same as original access(), but without type arguments and arguments.
  14.371 +    /**
  14.372 +     * Variant of the generalized access routine, to be used for generating variable,
  14.373 +     * type resolution diagnostics
  14.374       */
  14.375 -    Symbol access(Symbol sym,
  14.376 +    Symbol accessBase(Symbol sym,
  14.377                    DiagnosticPosition pos,
  14.378                    Symbol location,
  14.379                    Type site,
  14.380                    Name name,
  14.381                    boolean qualified) {
  14.382 -        if (sym.kind >= AMBIGUOUS)
  14.383 -            return access(sym, pos, location, site, name, qualified, List.<Type>nil(), null);
  14.384 -        else
  14.385 -            return sym;
  14.386 +        return accessInternal(sym, pos, location, site, name, qualified, List.<Type>nil(), null, basicLogResolveHelper);
  14.387      }
  14.388  
  14.389 -    /** Same as original access(), but without location, type arguments and arguments.
  14.390 +    /** Same as original accessBase(), but without location.
  14.391       */
  14.392 -    Symbol access(Symbol sym,
  14.393 +    Symbol accessBase(Symbol sym,
  14.394                    DiagnosticPosition pos,
  14.395                    Type site,
  14.396                    Name name,
  14.397                    boolean qualified) {
  14.398 -        return access(sym, pos, site.tsym, site, name, qualified);
  14.399 +        return accessBase(sym, pos, site.tsym, site, name, qualified);
  14.400      }
  14.401  
  14.402 +    interface LogResolveHelper {
  14.403 +        boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
  14.404 +        List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
  14.405 +    }
  14.406 +
  14.407 +    LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
  14.408 +        public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
  14.409 +            return !site.isErroneous();
  14.410 +        }
  14.411 +        public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
  14.412 +            return argtypes;
  14.413 +        }
  14.414 +    };
  14.415 +
  14.416 +    LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
  14.417 +        public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
  14.418 +            return !site.isErroneous() &&
  14.419 +                        !Type.isErroneous(argtypes) &&
  14.420 +                        (typeargtypes == null || !Type.isErroneous(typeargtypes));
  14.421 +        }
  14.422 +        public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
  14.423 +            if (syms.operatorNames.contains(name)) {
  14.424 +                return argtypes;
  14.425 +            } else {
  14.426 +                Symbol msym = errSym.kind == WRONG_MTH ?
  14.427 +                        ((InapplicableSymbolError)errSym).errCandidate().sym : accessedSym;
  14.428 +
  14.429 +                List<Type> argtypes2 = Type.map(argtypes,
  14.430 +                        deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, msym, currentResolutionContext.firstErroneousResolutionPhase()));
  14.431 +
  14.432 +                if (msym != accessedSym) {
  14.433 +                    //fixup deferred type caches - this 'hack' is required because the symbol
  14.434 +                    //returned by InapplicableSymbolError.access() will hide the candidate
  14.435 +                    //method symbol that can be used for lookups in the speculative cache,
  14.436 +                    //causing problems in Attr.checkId()
  14.437 +                    for (Type t : argtypes) {
  14.438 +                        if (t.tag == DEFERRED) {
  14.439 +                            DeferredType dt = (DeferredType)t;
  14.440 +                            dt.speculativeCache.dupAllTo(msym, accessedSym);
  14.441 +                        }
  14.442 +                    }
  14.443 +                }
  14.444 +                return argtypes2;
  14.445 +            }
  14.446 +        }
  14.447 +    };
  14.448 +
  14.449      /** Check that sym is not an abstract method.
  14.450       */
  14.451      void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
  14.452 @@ -1734,7 +1865,7 @@
  14.453       */
  14.454      Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
  14.455                          Name name, int kind) {
  14.456 -        return access(
  14.457 +        return accessBase(
  14.458              findIdent(env, name, kind),
  14.459              pos, env.enclClass.sym.type, name, false);
  14.460      }
  14.461 @@ -1759,19 +1890,19 @@
  14.462              while (steps.nonEmpty() &&
  14.463                     steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
  14.464                     sym.kind >= ERRONEOUS) {
  14.465 -                currentResolutionContext.step = steps.head;
  14.466 +                currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
  14.467                  sym = findFun(env, name, argtypes, typeargtypes,
  14.468                          steps.head.isBoxingRequired,
  14.469 -                        env.info.varArgs = steps.head.isVarargsRequired);
  14.470 +                        steps.head.isVarargsRequired);
  14.471                  currentResolutionContext.resolutionCache.put(steps.head, sym);
  14.472                  steps = steps.tail;
  14.473              }
  14.474              if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
  14.475                  MethodResolutionPhase errPhase =
  14.476                          currentResolutionContext.firstErroneousResolutionPhase();
  14.477 -                sym = access(currentResolutionContext.resolutionCache.get(errPhase),
  14.478 +                sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase),
  14.479                          pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
  14.480 -                env.info.varArgs = errPhase.isVarargsRequired;
  14.481 +                env.info.pendingResolutionPhase = errPhase;
  14.482              }
  14.483              return sym;
  14.484          }
  14.485 @@ -1811,10 +1942,10 @@
  14.486              while (steps.nonEmpty() &&
  14.487                     steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
  14.488                     sym.kind >= ERRONEOUS) {
  14.489 -                currentResolutionContext.step = steps.head;
  14.490 +                currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
  14.491                  sym = findMethod(env, site, name, argtypes, typeargtypes,
  14.492                          steps.head.isBoxingRequired(),
  14.493 -                        env.info.varArgs = steps.head.isVarargsRequired(), false);
  14.494 +                        steps.head.isVarargsRequired(), false);
  14.495                  currentResolutionContext.resolutionCache.put(steps.head, sym);
  14.496                  steps = steps.tail;
  14.497              }
  14.498 @@ -1822,13 +1953,13 @@
  14.499                  //if nothing is found return the 'first' error
  14.500                  MethodResolutionPhase errPhase =
  14.501                          currentResolutionContext.firstErroneousResolutionPhase();
  14.502 -                sym = access(currentResolutionContext.resolutionCache.get(errPhase),
  14.503 +                sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase),
  14.504                          pos, location, site, name, true, argtypes, typeargtypes);
  14.505 -                env.info.varArgs = errPhase.isVarargsRequired;
  14.506 +                env.info.pendingResolutionPhase = errPhase;
  14.507              } else if (allowMethodHandles) {
  14.508                  MethodSymbol msym = (MethodSymbol)sym;
  14.509                  if (msym.isSignaturePolymorphic(types)) {
  14.510 -                    env.info.varArgs = false;
  14.511 +                    env.info.pendingResolutionPhase = BASIC;
  14.512                      return findPolymorphicSignatureInstance(env, sym, argtypes);
  14.513                  }
  14.514              }
  14.515 @@ -1850,7 +1981,7 @@
  14.516                                              Symbol spMethod,
  14.517                                              List<Type> argtypes) {
  14.518          Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
  14.519 -                (MethodSymbol)spMethod, argtypes);
  14.520 +                (MethodSymbol)spMethod, currentResolutionContext, argtypes);
  14.521          for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) {
  14.522              if (types.isSameType(mtype, sym.type)) {
  14.523                 return sym;
  14.524 @@ -1918,18 +2049,18 @@
  14.525              while (steps.nonEmpty() &&
  14.526                     steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
  14.527                     sym.kind >= ERRONEOUS) {
  14.528 -                currentResolutionContext.step = steps.head;
  14.529 +                currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
  14.530                  sym = findConstructor(pos, env, site, argtypes, typeargtypes,
  14.531                          steps.head.isBoxingRequired(),
  14.532 -                        env.info.varArgs = steps.head.isVarargsRequired());
  14.533 +                        steps.head.isVarargsRequired());
  14.534                  currentResolutionContext.resolutionCache.put(steps.head, sym);
  14.535                  steps = steps.tail;
  14.536              }
  14.537              if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
  14.538                  MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
  14.539 -                sym = access(currentResolutionContext.resolutionCache.get(errPhase),
  14.540 +                sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase),
  14.541                          pos, site, names.init, true, argtypes, typeargtypes);
  14.542 -                env.info.varArgs = errPhase.isVarargsRequired();
  14.543 +                env.info.pendingResolutionPhase = errPhase;
  14.544              }
  14.545              return sym;
  14.546          }
  14.547 @@ -1961,10 +2092,10 @@
  14.548              while (steps.nonEmpty() &&
  14.549                     steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
  14.550                     sym.kind >= ERRONEOUS) {
  14.551 -                currentResolutionContext.step = steps.head;
  14.552 +                currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
  14.553                  sym = findDiamond(env, site, argtypes, typeargtypes,
  14.554                          steps.head.isBoxingRequired(),
  14.555 -                        env.info.varArgs = steps.head.isVarargsRequired());
  14.556 +                        steps.head.isVarargsRequired());
  14.557                  currentResolutionContext.resolutionCache.put(steps.head, sym);
  14.558                  steps = steps.tail;
  14.559              }
  14.560 @@ -1986,8 +2117,8 @@
  14.561                      }
  14.562                  };
  14.563                  MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
  14.564 -                sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes);
  14.565 -                env.info.varArgs = errPhase.isVarargsRequired();
  14.566 +                sym = accessMethod(errSym, pos, site, names.init, true, argtypes, typeargtypes);
  14.567 +                env.info.pendingResolutionPhase = errPhase;
  14.568              }
  14.569              return sym;
  14.570          }
  14.571 @@ -2115,7 +2246,7 @@
  14.572              if (boxingEnabled && sym.kind >= WRONG_MTHS)
  14.573                  sym = findMethod(env, syms.predefClass.type, name, argtypes,
  14.574                                   null, true, false, true);
  14.575 -            return access(sym, pos, env.enclClass.sym.type, name,
  14.576 +            return accessMethod(sym, pos, env.enclClass.sym.type, name,
  14.577                            false, argtypes, null);
  14.578          }
  14.579          finally {
  14.580 @@ -2167,7 +2298,7 @@
  14.581                  Symbol sym = env1.info.scope.lookup(name).sym;
  14.582                  if (sym != null) {
  14.583                      if (staticOnly) sym = new StaticError(sym);
  14.584 -                    return access(sym, pos, env.enclClass.sym.type,
  14.585 +                    return accessBase(sym, pos, env.enclClass.sym.type,
  14.586                                    name, true);
  14.587                  }
  14.588              }
  14.589 @@ -2199,7 +2330,7 @@
  14.590                      Symbol sym = env1.info.scope.lookup(name).sym;
  14.591                      if (sym != null) {
  14.592                          if (staticOnly) sym = new StaticError(sym);
  14.593 -                        return access(sym, pos, env.enclClass.sym.type,
  14.594 +                        return accessBase(sym, pos, env.enclClass.sym.type,
  14.595                                        name, true);
  14.596                      }
  14.597                  }
  14.598 @@ -2322,17 +2453,6 @@
  14.599                  Name name,
  14.600                  List<Type> argtypes,
  14.601                  List<Type> typeargtypes);
  14.602 -
  14.603 -        /**
  14.604 -         * A name designates an operator if it consists
  14.605 -         * of a non-empty sequence of operator symbols {@literal +-~!/*%&|^<>= }
  14.606 -         */
  14.607 -        boolean isOperator(Name name) {
  14.608 -            int i = 0;
  14.609 -            while (i < name.getByteLength() &&
  14.610 -                   "+-~!*/%&|^<>=".indexOf(name.getByteAt(i)) >= 0) i++;
  14.611 -            return i > 0 && i == name.getByteLength();
  14.612 -        }
  14.613      }
  14.614  
  14.615      /**
  14.616 @@ -2393,7 +2513,7 @@
  14.617              if (name == names.error)
  14.618                  return null;
  14.619  
  14.620 -            if (isOperator(name)) {
  14.621 +            if (syms.operatorNames.contains(name)) {
  14.622                  boolean isUnaryOp = argtypes.size() == 1;
  14.623                  String key = argtypes.size() == 1 ?
  14.624                      "operator.cant.be.applied" :
  14.625 @@ -2415,8 +2535,7 @@
  14.626                  hasLocation = !location.name.equals(names._this) &&
  14.627                          !location.name.equals(names._super);
  14.628              }
  14.629 -            boolean isConstructor = kind == ABSENT_MTH &&
  14.630 -                    name == names.table.names.init;
  14.631 +            boolean isConstructor = kind == ABSENT_MTH && name == names.init;
  14.632              KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
  14.633              Name idname = isConstructor ? site.tsym.name : name;
  14.634              String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
  14.635 @@ -2496,7 +2615,7 @@
  14.636              if (name == names.error)
  14.637                  return null;
  14.638  
  14.639 -            if (isOperator(name)) {
  14.640 +            if (syms.operatorNames.contains(name)) {
  14.641                  boolean isUnaryOp = argtypes.size() == 1;
  14.642                  String key = argtypes.size() == 1 ?
  14.643                      "operator.cant.be.applied" :
  14.644 @@ -2774,9 +2893,10 @@
  14.645          private Map<MethodResolutionPhase, Symbol> resolutionCache =
  14.646              new EnumMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.class);
  14.647  
  14.648 -        private MethodResolutionPhase step = null;
  14.649 +        MethodResolutionPhase step = null;
  14.650  
  14.651          private boolean internalResolution = false;
  14.652 +        private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
  14.653  
  14.654          private MethodResolutionPhase firstErroneousResolutionPhase() {
  14.655              MethodResolutionPhase bestSoFar = BASIC;
  14.656 @@ -2842,6 +2962,14 @@
  14.657                  return mtype != null;
  14.658              }
  14.659          }
  14.660 +
  14.661 +        DeferredAttr.AttrMode attrMode() {
  14.662 +            return attrMode;
  14.663 +        }
  14.664 +
  14.665 +        boolean internal() {
  14.666 +            return internalResolution;
  14.667 +        }
  14.668      }
  14.669  
  14.670      MethodResolutionContext currentResolutionContext = null;
    15.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Sat Sep 29 09:00:58 2012 -0700
    15.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Oct 04 13:04:53 2012 +0100
    15.3 @@ -1041,7 +1041,7 @@
    15.4                  genEndPos = true;
    15.5                  if (!taskListener.isEmpty())
    15.6                      taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
    15.7 -                log.deferDiagnostics = true;
    15.8 +                log.deferAll();
    15.9              } else { // free resources
   15.10                  procEnvImpl.close();
   15.11              }
   15.12 @@ -1151,7 +1151,7 @@
   15.13                  if (c != this)
   15.14                      annotationProcessingOccurred = c.annotationProcessingOccurred = true;
   15.15                  // doProcessing will have handled deferred diagnostics
   15.16 -                Assert.check(c.log.deferDiagnostics == false
   15.17 +                Assert.check(c.log.deferredDiagFilter == null
   15.18                          && c.log.deferredDiagnostics.size() == 0);
   15.19                  return c;
   15.20              } finally {
    16.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Sat Sep 29 09:00:58 2012 -0700
    16.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu Oct 04 13:04:53 2012 +0100
    16.3 @@ -806,7 +806,7 @@
    16.4              log = Log.instance(context);
    16.5              log.nerrors = priorErrors;
    16.6              log.nwarnings += priorWarnings;
    16.7 -            log.deferDiagnostics = true;
    16.8 +            log.deferAll();
    16.9  
   16.10              // the following is for the benefit of JavacProcessingEnvironment.getContext()
   16.11              JavacProcessingEnvironment.this.context = context;
    17.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Sat Sep 29 09:00:58 2012 -0700
    17.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Oct 04 13:04:53 2012 +0100
    17.3 @@ -635,6 +635,10 @@
    17.4      second operand: {0}\n\
    17.5      third operand : {1}
    17.6  
    17.7 +# 0: message segment
    17.8 +compiler.misc.incompatible.type.in.conditional=\
    17.9 +    bad type in conditional expression; {0}
   17.10 +
   17.11  compiler.err.new.not.allowed.in.annotation=\
   17.12      ''new'' not allowed in an annotation
   17.13  
   17.14 @@ -1701,6 +1705,10 @@
   17.15      inferred: {0}\n\
   17.16      equality constraints(s): {1}
   17.17  
   17.18 +# 0: list of type
   17.19 +compiler.misc.cyclic.inference=\
   17.20 +    Cannot instantiate inference variables {0} because of an inference loop
   17.21 +
   17.22  # 0: symbol
   17.23  compiler.misc.diamond=\
   17.24      {0}<>
   17.25 @@ -2086,6 +2094,9 @@
   17.26  compiler.misc.type.null=\
   17.27      <null>
   17.28  
   17.29 +compiler.misc.type.conditional=\
   17.30 +    conditional expression
   17.31 +
   17.32  # X#n (where n is an int id) is disambiguated tvar name
   17.33  # 0: name, 1: number
   17.34  compiler.misc.type.var=\
    18.1 --- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Sat Sep 29 09:00:58 2012 -0700
    18.2 +++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Thu Oct 04 13:04:53 2012 +0100
    18.3 @@ -81,6 +81,12 @@
    18.4       */
    18.5      DocCommentTable docComments = null;
    18.6  
    18.7 +    /**
    18.8 +     * A string sequence to be used when Pretty output should be constrained
    18.9 +     * to fit into a given size
   18.10 +     */
   18.11 +    private final static String trimSequence = "[...]";
   18.12 +
   18.13      /** Align code to be indented to left margin.
   18.14       */
   18.15      void align() throws IOException {
   18.16 @@ -129,6 +135,27 @@
   18.17          out.write(lineSep);
   18.18      }
   18.19  
   18.20 +    public static String toSimpleString(JCTree tree, int maxLength) {
   18.21 +        StringWriter s = new StringWriter();
   18.22 +        try {
   18.23 +            new Pretty(s, false).printExpr(tree);
   18.24 +        }
   18.25 +        catch (IOException e) {
   18.26 +            // should never happen, because StringWriter is defined
   18.27 +            // never to throw any IOExceptions
   18.28 +            throw new AssertionError(e);
   18.29 +        }
   18.30 +        //we need to (i) replace all line terminators with a space and (ii) remove
   18.31 +        //occurrences of 'missing' in the Pretty output (generated when types are missing)
   18.32 +        String res = s.toString().replaceAll("\\s+", " ").replaceAll("/\\*missing\\*/", "");
   18.33 +        if (res.length() < maxLength) {
   18.34 +            return res;
   18.35 +        } else {
   18.36 +            int split = (maxLength - trimSequence.length()) * 2 / 3;
   18.37 +            return res.substring(0, split) + trimSequence + res.substring(split);
   18.38 +        }
   18.39 +    }
   18.40 +
   18.41      String lineSep = System.getProperty("line.separator");
   18.42  
   18.43      /**************************************************************************
    19.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Sat Sep 29 09:00:58 2012 -0700
    19.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu Oct 04 13:04:53 2012 +0100
    19.3 @@ -245,6 +245,23 @@
    19.4          }
    19.5      }
    19.6  
    19.7 +    /** Return true if a a tree corresponds to a poly expression. */
    19.8 +    public static boolean isPoly(JCTree tree, JCTree origin) {
    19.9 +        switch (tree.getTag()) {
   19.10 +            case APPLY:
   19.11 +            case NEWCLASS:
   19.12 +            case CONDEXPR:
   19.13 +                return !origin.hasTag(TYPECAST);
   19.14 +            case LAMBDA:
   19.15 +            case REFERENCE:
   19.16 +                return true;
   19.17 +            case PARENS:
   19.18 +                return isPoly(((JCParens)tree).expr, origin);
   19.19 +            default:
   19.20 +                return false;
   19.21 +        }
   19.22 +    }
   19.23 +
   19.24      /**
   19.25       * Return true if the AST corresponds to a static select of the kind A.B
   19.26       */
    20.1 --- a/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Sat Sep 29 09:00:58 2012 -0700
    20.2 +++ b/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Thu Oct 04 13:04:53 2012 +0100
    20.3 @@ -489,7 +489,8 @@
    20.4       * type referred by a given captured type C contains C itself) which might
    20.5       * lead to infinite loops.
    20.6       */
    20.7 -    protected Printer printer = new Printer() {
    20.8 +    protected Printer printer = new Printer(isRaw()) {
    20.9 +
   20.10          @Override
   20.11          protected String localize(Locale locale, String key, Object... args) {
   20.12              return AbstractDiagnosticFormatter.this.localize(locale, key, args);
    21.1 --- a/src/share/classes/com/sun/tools/javac/util/List.java	Sat Sep 29 09:00:58 2012 -0700
    21.2 +++ b/src/share/classes/com/sun/tools/javac/util/List.java	Thu Oct 04 13:04:53 2012 +0100
    21.3 @@ -83,6 +83,19 @@
    21.4          }
    21.5      };
    21.6  
    21.7 +    /** Returns the list obtained from 'l' after removing all elements 'elem'
    21.8 +     */
    21.9 +    public static <A> List<A> filter(List<A> l, A elem) {
   21.10 +        Assert.checkNonNull(elem);
   21.11 +        List<A> res = List.nil();
   21.12 +        for (A a : l) {
   21.13 +            if (a != null && !a.equals(elem)) {
   21.14 +                res = res.prepend(a);
   21.15 +            }
   21.16 +        }
   21.17 +        return res.reverse();
   21.18 +    }
   21.19 +
   21.20      /** Construct a list consisting of given element.
   21.21       */
   21.22      public static <A> List<A> of(A x1) {
   21.23 @@ -120,6 +133,14 @@
   21.24          return xs;
   21.25      }
   21.26  
   21.27 +    public static <A> List<A> from(Iterable<? extends A> coll) {
   21.28 +        List<A> xs = nil();
   21.29 +        for (A a : coll) {
   21.30 +            xs = new List<A>(a, xs);
   21.31 +        }
   21.32 +        return xs;
   21.33 +    }
   21.34 +
   21.35      /** Construct a list consisting of a given number of identical elements.
   21.36       *  @param len    The number of elements in the list.
   21.37       *  @param init   The value of each element.
    22.1 --- a/src/share/classes/com/sun/tools/javac/util/Log.java	Sat Sep 29 09:00:58 2012 -0700
    22.2 +++ b/src/share/classes/com/sun/tools/javac/util/Log.java	Thu Oct 04 13:04:53 2012 +0100
    22.3 @@ -130,7 +130,7 @@
    22.4      /**
    22.5       * Deferred diagnostics
    22.6       */
    22.7 -    public boolean deferDiagnostics;
    22.8 +    public Filter<JCDiagnostic> deferredDiagFilter;
    22.9      public Queue<JCDiagnostic> deferredDiagnostics = new ListBuffer<JCDiagnostic>();
   22.10  
   22.11      /** Construct a log with given I/O redirections.
   22.12 @@ -450,7 +450,7 @@
   22.13  
   22.14      /** Report selected deferred diagnostics, and clear the deferDiagnostics flag. */
   22.15      public void reportDeferredDiagnostics(Set<JCDiagnostic.Kind> kinds) {
   22.16 -        deferDiagnostics = false;
   22.17 +        deferredDiagFilter = null;
   22.18          JCDiagnostic d;
   22.19          while ((d = deferredDiagnostics.poll()) != null) {
   22.20              if (kinds.contains(d.getKind()))
   22.21 @@ -464,7 +464,7 @@
   22.22       * reported so far, the diagnostic may be handed off to writeDiagnostic.
   22.23       */
   22.24      public void report(JCDiagnostic diagnostic) {
   22.25 -        if (deferDiagnostics) {
   22.26 +        if (deferredDiagFilter != null && deferredDiagFilter.accepts(diagnostic)) {
   22.27              deferredDiagnostics.add(diagnostic);
   22.28              return;
   22.29          }
   22.30 @@ -551,6 +551,18 @@
   22.31          }
   22.32      }
   22.33  
   22.34 +    public void deferAll() {
   22.35 +        deferredDiagFilter = new Filter<JCDiagnostic>() {
   22.36 +            public boolean accepts(JCDiagnostic t) {
   22.37 +                return true;
   22.38 +            }
   22.39 +        };
   22.40 +    }
   22.41 +
   22.42 +    public void deferNone() {
   22.43 +        deferredDiagFilter = null;
   22.44 +    }
   22.45 +
   22.46      /** Find a localized string in the resource bundle.
   22.47       *  Because this method is static, it ignores the locale.
   22.48       *  Use localize(key, args) when possible.
    23.1 --- a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Sat Sep 29 09:00:58 2012 -0700
    23.2 +++ b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Thu Oct 04 13:04:53 2012 +0100
    23.3 @@ -325,6 +325,10 @@
    23.4       */
    23.5      protected class RichPrinter extends Printer {
    23.6  
    23.7 +        public RichPrinter() {
    23.8 +            super(formatter.isRaw());
    23.9 +        }
   23.10 +
   23.11          @Override
   23.12          public String localize(Locale locale, String key, Object... args) {
   23.13              return formatter.localize(locale, key, args);
   23.14 @@ -393,11 +397,6 @@
   23.15          }
   23.16  
   23.17          @Override
   23.18 -        protected String printMethodArgs(List<Type> args, boolean varArgs, Locale locale) {
   23.19 -            return super.printMethodArgs(args, varArgs, locale);
   23.20 -        }
   23.21 -
   23.22 -        @Override
   23.23          public String visitClassSymbol(ClassSymbol s, Locale locale) {
   23.24              String name = nameSimplifier.simplify(s);
   23.25              if (name.length() == 0 ||
    24.1 --- a/test/tools/javac/conditional/Conditional.java	Sat Sep 29 09:00:58 2012 -0700
    24.2 +++ b/test/tools/javac/conditional/Conditional.java	Thu Oct 04 13:04:53 2012 +0100
    24.3 @@ -27,6 +27,7 @@
    24.4   * @summary Conditional operator applies assignment conversion
    24.5   * @author Tim Hanson, BEA
    24.6   *
    24.7 + * @compile -XDallowPoly Conditional.java
    24.8   * @compile/fail Conditional.java
    24.9   */
   24.10  
    25.1 --- a/test/tools/javac/diags/examples.not-yet.txt	Sat Sep 29 09:00:58 2012 -0700
    25.2 +++ b/test/tools/javac/diags/examples.not-yet.txt	Thu Oct 04 13:04:53 2012 +0100
    25.3 @@ -58,6 +58,7 @@
    25.4  compiler.misc.fatal.err.cant.close	                # JavaCompiler
    25.5  compiler.misc.file.does.not.contain.package
    25.6  compiler.misc.illegal.start.of.class.file
    25.7 +compiler.misc.cyclic.inference                          # Cannot happen w/o lambdas
    25.8  compiler.misc.kindname.annotation
    25.9  compiler.misc.kindname.enum
   25.10  compiler.misc.kindname.package
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/test/tools/javac/diags/examples/IncompatibleTypesInConditional.java	Thu Oct 04 13:04:53 2012 +0100
    26.3 @@ -0,0 +1,35 @@
    26.4 +/*
    26.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
    26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    26.7 + *
    26.8 + * This code is free software; you can redistribute it and/or modify it
    26.9 + * under the terms of the GNU General Public License version 2 only, as
   26.10 + * published by the Free Software Foundation.
   26.11 + *
   26.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   26.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   26.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   26.15 + * version 2 for more details (a copy is included in the LICENSE file that
   26.16 + * accompanied this code).
   26.17 + *
   26.18 + * You should have received a copy of the GNU General Public License version
   26.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   26.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   26.21 + *
   26.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   26.23 + * or visit www.oracle.com if you need additional information or have any
   26.24 + * questions.
   26.25 + */
   26.26 +
   26.27 +// key: compiler.err.prob.found.req
   26.28 +// key: compiler.misc.incompatible.type.in.conditional
   26.29 +// key: compiler.misc.inconvertible.types
   26.30 +// options: -XDallowPoly
   26.31 +
   26.32 +class IncompatibleTypesInConditional {
   26.33 +
   26.34 +    interface A { }
   26.35 +    interface B { }
   26.36 +
   26.37 +    B b = true ? (A)null : (B)null;
   26.38 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/test/tools/javac/diags/examples/TypeConditional.java	Thu Oct 04 13:04:53 2012 +0100
    27.3 @@ -0,0 +1,38 @@
    27.4 +/*
    27.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
    27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.7 + *
    27.8 + * This code is free software; you can redistribute it and/or modify it
    27.9 + * under the terms of the GNU General Public License version 2 only, as
   27.10 + * published by the Free Software Foundation.
   27.11 + *
   27.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   27.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   27.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   27.15 + * version 2 for more details (a copy is included in the LICENSE file that
   27.16 + * accompanied this code).
   27.17 + *
   27.18 + * You should have received a copy of the GNU General Public License version
   27.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   27.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   27.21 + *
   27.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   27.23 + * or visit www.oracle.com if you need additional information or have any
   27.24 + * questions.
   27.25 + */
   27.26 +
   27.27 +// key: compiler.err.cant.apply.symbol.1
   27.28 +// key: compiler.misc.type.conditional
   27.29 +// key: compiler.misc.no.args
   27.30 +// key: compiler.misc.arg.length.mismatch
   27.31 +// options: -XDallowPoly
   27.32 +// run: simple
   27.33 +
   27.34 +class TypeConditional {
   27.35 +
   27.36 +    void m() { }
   27.37 +
   27.38 +    void test() {
   27.39 +        m(true ? 1 : 2);
   27.40 +    }
   27.41 +}

mercurial