src/share/classes/com/sun/tools/javac/comp/Attr.java

changeset 1347
1408af4cd8b0
parent 1341
db36841709e4
child 1348
573ceb23beeb
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Sat Sep 29 09:00:58 2012 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 04 13:04:53 2012 +0100
     1.3 @@ -25,12 +25,10 @@
     1.4  
     1.5  package com.sun.tools.javac.comp;
     1.6  
     1.7 -import java.util.*;
     1.8 -import java.util.Set;
     1.9 -import javax.lang.model.element.ElementKind;
    1.10 -import javax.tools.JavaFileObject;
    1.11 -
    1.12  import com.sun.tools.javac.code.*;
    1.13 +import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
    1.14 +import com.sun.tools.javac.comp.Infer.InferenceContext;
    1.15 +import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
    1.16  import com.sun.tools.javac.jvm.*;
    1.17  import com.sun.tools.javac.tree.*;
    1.18  import com.sun.tools.javac.util.*;
    1.19 @@ -49,6 +47,11 @@
    1.20  import com.sun.source.tree.TreeVisitor;
    1.21  import com.sun.source.util.SimpleTreeVisitor;
    1.22  
    1.23 +import java.util.*;
    1.24 +import java.util.Set;
    1.25 +import javax.lang.model.element.ElementKind;
    1.26 +import javax.tools.JavaFileObject;
    1.27 +
    1.28  import static com.sun.tools.javac.code.Flags.*;
    1.29  import static com.sun.tools.javac.code.Flags.ANNOTATION;
    1.30  import static com.sun.tools.javac.code.Flags.BLOCK;
    1.31 @@ -80,6 +83,7 @@
    1.32      final Symtab syms;
    1.33      final Resolve rs;
    1.34      final Infer infer;
    1.35 +    final DeferredAttr deferredAttr;
    1.36      final Check chk;
    1.37      final MemberEnter memberEnter;
    1.38      final TreeMaker make;
    1.39 @@ -110,6 +114,7 @@
    1.40          make = TreeMaker.instance(context);
    1.41          enter = Enter.instance(context);
    1.42          infer = Infer.instance(context);
    1.43 +        deferredAttr = DeferredAttr.instance(context);
    1.44          cfolder = ConstFold.instance(context);
    1.45          target = Target.instance(context);
    1.46          types = Types.instance(context);
    1.47 @@ -127,6 +132,7 @@
    1.48          allowCovariantReturns = source.allowCovariantReturns();
    1.49          allowAnonOuterThis = source.allowAnonOuterThis();
    1.50          allowStringsInSwitch = source.allowStringsInSwitch();
    1.51 +        allowPoly = source.allowPoly() && options.isSet("allowPoly");
    1.52          sourceName = source.name;
    1.53          relax = (options.isSet("-retrofit") ||
    1.54                   options.isSet("-relax"));
    1.55 @@ -144,6 +150,10 @@
    1.56       */
    1.57      boolean relax;
    1.58  
    1.59 +    /** Switch: support target-typing inference
    1.60 +     */
    1.61 +    boolean allowPoly;
    1.62 +
    1.63      /** Switch: support generics?
    1.64       */
    1.65      boolean allowGenerics;
    1.66 @@ -207,15 +217,29 @@
    1.67       *  @param ownkind  The computed kind of the tree
    1.68       *  @param resultInfo  The expected result of the tree
    1.69       */
    1.70 -    Type check(JCTree tree, Type owntype, int ownkind, ResultInfo resultInfo) {
    1.71 +    Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) {
    1.72 +        InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
    1.73 +        Type owntype = found;
    1.74          if (owntype.tag != ERROR && resultInfo.pt.tag != METHOD && resultInfo.pt.tag != FORALL) {
    1.75 -            if ((ownkind & ~resultInfo.pkind) == 0) {
    1.76 -                owntype = resultInfo.check(tree, owntype);
    1.77 +            if (inferenceContext.free(found)) {
    1.78 +                inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
    1.79 +                    @Override
    1.80 +                    public void typesInferred(InferenceContext inferenceContext) {
    1.81 +                        ResultInfo pendingResult =
    1.82 +                                    resultInfo.dup(inferenceContext.asInstType(resultInfo.pt, types));
    1.83 +                        check(tree, inferenceContext.asInstType(found, types), ownkind, pendingResult);
    1.84 +                    }
    1.85 +                });
    1.86 +                return tree.type = resultInfo.pt;
    1.87              } else {
    1.88 -                log.error(tree.pos(), "unexpected.type",
    1.89 -                          kindNames(resultInfo.pkind),
    1.90 -                          kindName(ownkind));
    1.91 -                owntype = types.createErrorType(owntype);
    1.92 +                if ((ownkind & ~resultInfo.pkind) == 0) {
    1.93 +                    owntype = resultInfo.check(tree, owntype);
    1.94 +                } else {
    1.95 +                    log.error(tree.pos(), "unexpected.type",
    1.96 +                            kindNames(resultInfo.pkind),
    1.97 +                            kindName(ownkind));
    1.98 +                    owntype = types.createErrorType(owntype);
    1.99 +                }
   1.100              }
   1.101          }
   1.102          tree.type = owntype;
   1.103 @@ -297,8 +321,6 @@
   1.104              } else {
   1.105                  log.error(pos, "cant.assign.val.to.final.var", v);
   1.106              }
   1.107 -        } else if ((v.flags() & EFFECTIVELY_FINAL) != 0) {
   1.108 -            v.flags_field &= ~EFFECTIVELY_FINAL;
   1.109          }
   1.110      }
   1.111  
   1.112 @@ -431,14 +453,38 @@
   1.113          static final long serialVersionUID = -6924771130405446405L;
   1.114          private Env<AttrContext> env;
   1.115          private BreakAttr(Env<AttrContext> env) {
   1.116 -            this.env = env;
   1.117 +            this.env = copyEnv(env);
   1.118 +        }
   1.119 +
   1.120 +        private Env<AttrContext> copyEnv(Env<AttrContext> env) {
   1.121 +            Env<AttrContext> newEnv =
   1.122 +                    env.dup(env.tree, env.info.dup(copyScope(env.info.scope)));
   1.123 +            if (newEnv.outer != null) {
   1.124 +                newEnv.outer = copyEnv(newEnv.outer);
   1.125 +            }
   1.126 +            return newEnv;
   1.127 +        }
   1.128 +
   1.129 +        private Scope copyScope(Scope sc) {
   1.130 +            Scope newScope = new Scope(sc.owner);
   1.131 +            List<Symbol> elemsList = List.nil();
   1.132 +            while (sc != null) {
   1.133 +                for (Scope.Entry e = sc.elems ; e != null ; e = e.sibling) {
   1.134 +                    elemsList = elemsList.prepend(e.sym);
   1.135 +                }
   1.136 +                sc = sc.next;
   1.137 +            }
   1.138 +            for (Symbol s : elemsList) {
   1.139 +                newScope.enter(s);
   1.140 +            }
   1.141 +            return newScope;
   1.142          }
   1.143      }
   1.144  
   1.145      class ResultInfo {
   1.146 -        int pkind;
   1.147 -        Type pt;
   1.148 -        CheckContext checkContext;
   1.149 +        final int pkind;
   1.150 +        final Type pt;
   1.151 +        final CheckContext checkContext;
   1.152  
   1.153          ResultInfo(int pkind, Type pt) {
   1.154              this(pkind, pt, chk.basicHandler);
   1.155 @@ -450,15 +496,19 @@
   1.156              this.checkContext = checkContext;
   1.157          }
   1.158  
   1.159 -        protected Type check(DiagnosticPosition pos, Type found) {
   1.160 +        protected Type check(final DiagnosticPosition pos, final Type found) {
   1.161              return chk.checkType(pos, found, pt, checkContext);
   1.162          }
   1.163 +
   1.164 +        protected ResultInfo dup(Type newPt) {
   1.165 +            return new ResultInfo(pkind, newPt, checkContext);
   1.166 +        }
   1.167      }
   1.168  
   1.169 -    private final ResultInfo statInfo;
   1.170 -    private final ResultInfo varInfo;
   1.171 -    private final ResultInfo unknownExprInfo;
   1.172 -    private final ResultInfo unknownTypeInfo;
   1.173 +    final ResultInfo statInfo;
   1.174 +    final ResultInfo varInfo;
   1.175 +    final ResultInfo unknownExprInfo;
   1.176 +    final ResultInfo unknownTypeInfo;
   1.177  
   1.178      Type pt() {
   1.179          return resultInfo.pt;
   1.180 @@ -491,7 +541,7 @@
   1.181       *  @param env     The environment visitor argument.
   1.182       *  @param resultInfo   The result info visitor argument.
   1.183       */
   1.184 -    private Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
   1.185 +    Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
   1.186          Env<AttrContext> prevEnv = this.env;
   1.187          ResultInfo prevResult = this.resultInfo;
   1.188          try {
   1.189 @@ -563,9 +613,12 @@
   1.190       */
   1.191      List<Type> attribArgs(List<JCExpression> trees, Env<AttrContext> env) {
   1.192          ListBuffer<Type> argtypes = new ListBuffer<Type>();
   1.193 -        for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
   1.194 -            argtypes.append(chk.checkNonVoid(
   1.195 -                l.head.pos(), types.upperBound(attribExpr(l.head, env, Infer.anyPoly))));
   1.196 +        for (JCExpression arg : trees) {
   1.197 +            Type argtype = allowPoly && TreeInfo.isPoly(arg, env.tree) ?
   1.198 +                    deferredAttr.new DeferredType(arg, env) :
   1.199 +                    chk.checkNonVoid(arg, attribExpr(arg, env, Infer.anyPoly));
   1.200 +            argtypes.append(argtype);
   1.201 +        }
   1.202          return argtypes.toList();
   1.203      }
   1.204  
   1.205 @@ -979,8 +1032,11 @@
   1.206              // Create a new local environment with a local scope.
   1.207              Env<AttrContext> localEnv =
   1.208                  env.dup(tree, env.info.dup(env.info.scope.dup()));
   1.209 -            attribStats(tree.stats, localEnv);
   1.210 -            localEnv.info.scope.leave();
   1.211 +            try {
   1.212 +                attribStats(tree.stats, localEnv);
   1.213 +            } finally {
   1.214 +                localEnv.info.scope.leave();
   1.215 +            }
   1.216          }
   1.217          result = null;
   1.218      }
   1.219 @@ -1000,43 +1056,51 @@
   1.220      public void visitForLoop(JCForLoop tree) {
   1.221          Env<AttrContext> loopEnv =
   1.222              env.dup(env.tree, env.info.dup(env.info.scope.dup()));
   1.223 -        attribStats(tree.init, loopEnv);
   1.224 -        if (tree.cond != null) attribExpr(tree.cond, loopEnv, syms.booleanType);
   1.225 -        loopEnv.tree = tree; // before, we were not in loop!
   1.226 -        attribStats(tree.step, loopEnv);
   1.227 -        attribStat(tree.body, loopEnv);
   1.228 -        loopEnv.info.scope.leave();
   1.229 -        result = null;
   1.230 +        try {
   1.231 +            attribStats(tree.init, loopEnv);
   1.232 +            if (tree.cond != null) attribExpr(tree.cond, loopEnv, syms.booleanType);
   1.233 +            loopEnv.tree = tree; // before, we were not in loop!
   1.234 +            attribStats(tree.step, loopEnv);
   1.235 +            attribStat(tree.body, loopEnv);
   1.236 +            result = null;
   1.237 +        }
   1.238 +        finally {
   1.239 +            loopEnv.info.scope.leave();
   1.240 +        }
   1.241      }
   1.242  
   1.243      public void visitForeachLoop(JCEnhancedForLoop tree) {
   1.244          Env<AttrContext> loopEnv =
   1.245              env.dup(env.tree, env.info.dup(env.info.scope.dup()));
   1.246 -        attribStat(tree.var, loopEnv);
   1.247 -        Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv));
   1.248 -        chk.checkNonVoid(tree.pos(), exprType);
   1.249 -        Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
   1.250 -        if (elemtype == null) {
   1.251 -            // or perhaps expr implements Iterable<T>?
   1.252 -            Type base = types.asSuper(exprType, syms.iterableType.tsym);
   1.253 -            if (base == null) {
   1.254 -                log.error(tree.expr.pos(),
   1.255 -                        "foreach.not.applicable.to.type",
   1.256 -                        exprType,
   1.257 -                        diags.fragment("type.req.array.or.iterable"));
   1.258 -                elemtype = types.createErrorType(exprType);
   1.259 -            } else {
   1.260 -                List<Type> iterableParams = base.allparams();
   1.261 -                elemtype = iterableParams.isEmpty()
   1.262 -                    ? syms.objectType
   1.263 -                    : types.upperBound(iterableParams.head);
   1.264 +        try {
   1.265 +            attribStat(tree.var, loopEnv);
   1.266 +            Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv));
   1.267 +            chk.checkNonVoid(tree.pos(), exprType);
   1.268 +            Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
   1.269 +            if (elemtype == null) {
   1.270 +                // or perhaps expr implements Iterable<T>?
   1.271 +                Type base = types.asSuper(exprType, syms.iterableType.tsym);
   1.272 +                if (base == null) {
   1.273 +                    log.error(tree.expr.pos(),
   1.274 +                            "foreach.not.applicable.to.type",
   1.275 +                            exprType,
   1.276 +                            diags.fragment("type.req.array.or.iterable"));
   1.277 +                    elemtype = types.createErrorType(exprType);
   1.278 +                } else {
   1.279 +                    List<Type> iterableParams = base.allparams();
   1.280 +                    elemtype = iterableParams.isEmpty()
   1.281 +                        ? syms.objectType
   1.282 +                        : types.upperBound(iterableParams.head);
   1.283 +                }
   1.284              }
   1.285 +            chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
   1.286 +            loopEnv.tree = tree; // before, we were not in loop!
   1.287 +            attribStat(tree.body, loopEnv);
   1.288 +            result = null;
   1.289          }
   1.290 -        chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
   1.291 -        loopEnv.tree = tree; // before, we were not in loop!
   1.292 -        attribStat(tree.body, loopEnv);
   1.293 -        loopEnv.info.scope.leave();
   1.294 -        result = null;
   1.295 +        finally {
   1.296 +            loopEnv.info.scope.leave();
   1.297 +        }
   1.298      }
   1.299  
   1.300      public void visitLabelled(JCLabeledStatement tree) {
   1.301 @@ -1062,61 +1126,69 @@
   1.302          Env<AttrContext> switchEnv =
   1.303              env.dup(tree, env.info.dup(env.info.scope.dup()));
   1.304  
   1.305 -        boolean enumSwitch =
   1.306 -            allowEnums &&
   1.307 -            (seltype.tsym.flags() & Flags.ENUM) != 0;
   1.308 -        boolean stringSwitch = false;
   1.309 -        if (types.isSameType(seltype, syms.stringType)) {
   1.310 -            if (allowStringsInSwitch) {
   1.311 -                stringSwitch = true;
   1.312 -            } else {
   1.313 -                log.error(tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
   1.314 +        try {
   1.315 +
   1.316 +            boolean enumSwitch =
   1.317 +                allowEnums &&
   1.318 +                (seltype.tsym.flags() & Flags.ENUM) != 0;
   1.319 +            boolean stringSwitch = false;
   1.320 +            if (types.isSameType(seltype, syms.stringType)) {
   1.321 +                if (allowStringsInSwitch) {
   1.322 +                    stringSwitch = true;
   1.323 +                } else {
   1.324 +                    log.error(tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
   1.325 +                }
   1.326              }
   1.327 +            if (!enumSwitch && !stringSwitch)
   1.328 +                seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType);
   1.329 +
   1.330 +            // Attribute all cases and
   1.331 +            // check that there are no duplicate case labels or default clauses.
   1.332 +            Set<Object> labels = new HashSet<Object>(); // The set of case labels.
   1.333 +            boolean hasDefault = false;      // Is there a default label?
   1.334 +            for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
   1.335 +                JCCase c = l.head;
   1.336 +                Env<AttrContext> caseEnv =
   1.337 +                    switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup()));
   1.338 +                try {
   1.339 +                    if (c.pat != null) {
   1.340 +                        if (enumSwitch) {
   1.341 +                            Symbol sym = enumConstant(c.pat, seltype);
   1.342 +                            if (sym == null) {
   1.343 +                                log.error(c.pat.pos(), "enum.label.must.be.unqualified.enum");
   1.344 +                            } else if (!labels.add(sym)) {
   1.345 +                                log.error(c.pos(), "duplicate.case.label");
   1.346 +                            }
   1.347 +                        } else {
   1.348 +                            Type pattype = attribExpr(c.pat, switchEnv, seltype);
   1.349 +                            if (pattype.tag != ERROR) {
   1.350 +                                if (pattype.constValue() == null) {
   1.351 +                                    log.error(c.pat.pos(),
   1.352 +                                              (stringSwitch ? "string.const.req" : "const.expr.req"));
   1.353 +                                } else if (labels.contains(pattype.constValue())) {
   1.354 +                                    log.error(c.pos(), "duplicate.case.label");
   1.355 +                                } else {
   1.356 +                                    labels.add(pattype.constValue());
   1.357 +                                }
   1.358 +                            }
   1.359 +                        }
   1.360 +                    } else if (hasDefault) {
   1.361 +                        log.error(c.pos(), "duplicate.default.label");
   1.362 +                    } else {
   1.363 +                        hasDefault = true;
   1.364 +                    }
   1.365 +                    attribStats(c.stats, caseEnv);
   1.366 +                } finally {
   1.367 +                    caseEnv.info.scope.leave();
   1.368 +                    addVars(c.stats, switchEnv.info.scope);
   1.369 +                }
   1.370 +            }
   1.371 +
   1.372 +            result = null;
   1.373          }
   1.374 -        if (!enumSwitch && !stringSwitch)
   1.375 -            seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType);
   1.376 -
   1.377 -        // Attribute all cases and
   1.378 -        // check that there are no duplicate case labels or default clauses.
   1.379 -        Set<Object> labels = new HashSet<Object>(); // The set of case labels.
   1.380 -        boolean hasDefault = false;      // Is there a default label?
   1.381 -        for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
   1.382 -            JCCase c = l.head;
   1.383 -            Env<AttrContext> caseEnv =
   1.384 -                switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup()));
   1.385 -            if (c.pat != null) {
   1.386 -                if (enumSwitch) {
   1.387 -                    Symbol sym = enumConstant(c.pat, seltype);
   1.388 -                    if (sym == null) {
   1.389 -                        log.error(c.pat.pos(), "enum.label.must.be.unqualified.enum");
   1.390 -                    } else if (!labels.add(sym)) {
   1.391 -                        log.error(c.pos(), "duplicate.case.label");
   1.392 -                    }
   1.393 -                } else {
   1.394 -                    Type pattype = attribExpr(c.pat, switchEnv, seltype);
   1.395 -                    if (pattype.tag != ERROR) {
   1.396 -                        if (pattype.constValue() == null) {
   1.397 -                            log.error(c.pat.pos(),
   1.398 -                                      (stringSwitch ? "string.const.req" : "const.expr.req"));
   1.399 -                        } else if (labels.contains(pattype.constValue())) {
   1.400 -                            log.error(c.pos(), "duplicate.case.label");
   1.401 -                        } else {
   1.402 -                            labels.add(pattype.constValue());
   1.403 -                        }
   1.404 -                    }
   1.405 -                }
   1.406 -            } else if (hasDefault) {
   1.407 -                log.error(c.pos(), "duplicate.default.label");
   1.408 -            } else {
   1.409 -                hasDefault = true;
   1.410 -            }
   1.411 -            attribStats(c.stats, caseEnv);
   1.412 -            caseEnv.info.scope.leave();
   1.413 -            addVars(c.stats, switchEnv.info.scope);
   1.414 +        finally {
   1.415 +            switchEnv.info.scope.leave();
   1.416          }
   1.417 -
   1.418 -        switchEnv.info.scope.leave();
   1.419 -        result = null;
   1.420      }
   1.421      // where
   1.422          /** Add any variables defined in stats to the switch scope. */
   1.423 @@ -1158,63 +1230,72 @@
   1.424      public void visitTry(JCTry tree) {
   1.425          // Create a new local environment with a local
   1.426          Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
   1.427 -        boolean isTryWithResource = tree.resources.nonEmpty();
   1.428 -        // Create a nested environment for attributing the try block if needed
   1.429 -        Env<AttrContext> tryEnv = isTryWithResource ?
   1.430 -            env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
   1.431 -            localEnv;
   1.432 -        // Attribute resource declarations
   1.433 -        for (JCTree resource : tree.resources) {
   1.434 -            CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
   1.435 -                @Override
   1.436 -                public void report(DiagnosticPosition pos, JCDiagnostic details) {
   1.437 -                    chk.basicHandler.report(pos, diags.fragment("try.not.applicable.to.type", details));
   1.438 +        try {
   1.439 +            boolean isTryWithResource = tree.resources.nonEmpty();
   1.440 +            // Create a nested environment for attributing the try block if needed
   1.441 +            Env<AttrContext> tryEnv = isTryWithResource ?
   1.442 +                env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
   1.443 +                localEnv;
   1.444 +            try {
   1.445 +                // Attribute resource declarations
   1.446 +                for (JCTree resource : tree.resources) {
   1.447 +                    CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
   1.448 +                        @Override
   1.449 +                        public void report(DiagnosticPosition pos, JCDiagnostic details) {
   1.450 +                            chk.basicHandler.report(pos, diags.fragment("try.not.applicable.to.type", details));
   1.451 +                        }
   1.452 +                    };
   1.453 +                    ResultInfo twrResult = new ResultInfo(VAL, syms.autoCloseableType, twrContext);
   1.454 +                    if (resource.hasTag(VARDEF)) {
   1.455 +                        attribStat(resource, tryEnv);
   1.456 +                        twrResult.check(resource, resource.type);
   1.457 +
   1.458 +                        //check that resource type cannot throw InterruptedException
   1.459 +                        checkAutoCloseable(resource.pos(), localEnv, resource.type);
   1.460 +
   1.461 +                        VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
   1.462 +                        var.setData(ElementKind.RESOURCE_VARIABLE);
   1.463 +                    } else {
   1.464 +                        attribTree(resource, tryEnv, twrResult);
   1.465 +                    }
   1.466                  }
   1.467 -            };
   1.468 -            ResultInfo twrResult = new ResultInfo(VAL, syms.autoCloseableType, twrContext);
   1.469 -            if (resource.hasTag(VARDEF)) {
   1.470 -                attribStat(resource, tryEnv);
   1.471 -                twrResult.check(resource, resource.type);
   1.472 -
   1.473 -                //check that resource type cannot throw InterruptedException
   1.474 -                checkAutoCloseable(resource.pos(), localEnv, resource.type);
   1.475 -
   1.476 -                VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
   1.477 -                var.setData(ElementKind.RESOURCE_VARIABLE);
   1.478 -            } else {
   1.479 -                attribTree(resource, tryEnv, twrResult);
   1.480 +                // Attribute body
   1.481 +                attribStat(tree.body, tryEnv);
   1.482 +            } finally {
   1.483 +                if (isTryWithResource)
   1.484 +                    tryEnv.info.scope.leave();
   1.485              }
   1.486 +
   1.487 +            // Attribute catch clauses
   1.488 +            for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
   1.489 +                JCCatch c = l.head;
   1.490 +                Env<AttrContext> catchEnv =
   1.491 +                    localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
   1.492 +                try {
   1.493 +                    Type ctype = attribStat(c.param, catchEnv);
   1.494 +                    if (TreeInfo.isMultiCatch(c)) {
   1.495 +                        //multi-catch parameter is implicitly marked as final
   1.496 +                        c.param.sym.flags_field |= FINAL | UNION;
   1.497 +                    }
   1.498 +                    if (c.param.sym.kind == Kinds.VAR) {
   1.499 +                        c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
   1.500 +                    }
   1.501 +                    chk.checkType(c.param.vartype.pos(),
   1.502 +                                  chk.checkClassType(c.param.vartype.pos(), ctype),
   1.503 +                                  syms.throwableType);
   1.504 +                    attribStat(c.body, catchEnv);
   1.505 +                } finally {
   1.506 +                    catchEnv.info.scope.leave();
   1.507 +                }
   1.508 +            }
   1.509 +
   1.510 +            // Attribute finalizer
   1.511 +            if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
   1.512 +            result = null;
   1.513          }
   1.514 -        // Attribute body
   1.515 -        attribStat(tree.body, tryEnv);
   1.516 -        if (isTryWithResource)
   1.517 -            tryEnv.info.scope.leave();
   1.518 -
   1.519 -        // Attribute catch clauses
   1.520 -        for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
   1.521 -            JCCatch c = l.head;
   1.522 -            Env<AttrContext> catchEnv =
   1.523 -                localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
   1.524 -            Type ctype = attribStat(c.param, catchEnv);
   1.525 -            if (TreeInfo.isMultiCatch(c)) {
   1.526 -                //multi-catch parameter is implicitly marked as final
   1.527 -                c.param.sym.flags_field |= FINAL | UNION;
   1.528 -            }
   1.529 -            if (c.param.sym.kind == Kinds.VAR) {
   1.530 -                c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
   1.531 -            }
   1.532 -            chk.checkType(c.param.vartype.pos(),
   1.533 -                          chk.checkClassType(c.param.vartype.pos(), ctype),
   1.534 -                          syms.throwableType);
   1.535 -            attribStat(c.body, catchEnv);
   1.536 -            catchEnv.info.scope.leave();
   1.537 +        finally {
   1.538 +            localEnv.info.scope.leave();
   1.539          }
   1.540 -
   1.541 -        // Attribute finalizer
   1.542 -        if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
   1.543 -
   1.544 -        localEnv.info.scope.leave();
   1.545 -        result = null;
   1.546      }
   1.547  
   1.548      void checkAutoCloseable(DiagnosticPosition pos, Env<AttrContext> env, Type resource) {
   1.549 @@ -1222,10 +1303,10 @@
   1.550              types.asSuper(resource, syms.autoCloseableType.tsym) != null &&
   1.551              !types.isSameType(resource, syms.autoCloseableType)) { // Don't emit warning for AutoCloseable itself
   1.552              Symbol close = syms.noSymbol;
   1.553 -            boolean prevDeferDiags = log.deferDiagnostics;
   1.554 +            Filter<JCDiagnostic> prevDeferDiagsFilter = log.deferredDiagFilter;
   1.555              Queue<JCDiagnostic> prevDeferredDiags = log.deferredDiagnostics;
   1.556              try {
   1.557 -                log.deferDiagnostics = true;
   1.558 +                log.deferAll();
   1.559                  log.deferredDiagnostics = ListBuffer.lb();
   1.560                  close = rs.resolveQualifiedMethod(pos,
   1.561                          env,
   1.562 @@ -1235,7 +1316,7 @@
   1.563                          List.<Type>nil());
   1.564              }
   1.565              finally {
   1.566 -                log.deferDiagnostics = prevDeferDiags;
   1.567 +                log.deferredDiagFilter = prevDeferDiagsFilter;
   1.568                  log.deferredDiagnostics = prevDeferredDiags;
   1.569              }
   1.570              if (close.kind == MTH &&
   1.571 @@ -1248,50 +1329,71 @@
   1.572      }
   1.573  
   1.574      public void visitConditional(JCConditional tree) {
   1.575 -        attribExpr(tree.cond, env, syms.booleanType);
   1.576 -        attribExpr(tree.truepart, env);
   1.577 -        attribExpr(tree.falsepart, env);
   1.578 -        result = check(tree,
   1.579 -                       capture(condType(tree.pos(), tree.cond.type,
   1.580 -                                        tree.truepart.type, tree.falsepart.type)),
   1.581 -                       VAL, resultInfo);
   1.582 +        Type condtype = attribExpr(tree.cond, env, syms.booleanType);
   1.583 +
   1.584 +        boolean standaloneConditional = !allowPoly ||
   1.585 +                pt().tag == NONE && pt() != Type.recoveryType ||
   1.586 +                isBooleanOrNumeric(env, tree);
   1.587 +
   1.588 +        if (!standaloneConditional && resultInfo.pt.tag == VOID) {
   1.589 +            //cannot get here (i.e. it means we are returning from void method - which is already an error)
   1.590 +            result = tree.type = types.createErrorType(resultInfo.pt);
   1.591 +            return;
   1.592 +        }
   1.593 +
   1.594 +        ResultInfo condInfo = standaloneConditional ?
   1.595 +                unknownExprInfo :
   1.596 +                new ResultInfo(VAL, pt(), new Check.NestedCheckContext(resultInfo.checkContext) {
   1.597 +                    //this will use enclosing check context to check compatibility of
   1.598 +                    //subexpression against target type; if we are in a method check context,
   1.599 +                    //depending on whether boxing is allowed, we could have incompatibilities
   1.600 +                    @Override
   1.601 +                    public void report(DiagnosticPosition pos, JCDiagnostic details) {
   1.602 +                        enclosingContext.report(pos, diags.fragment("incompatible.type.in.conditional", details));
   1.603 +                    }
   1.604 +                });
   1.605 +
   1.606 +        Type truetype = attribTree(tree.truepart, env, condInfo);
   1.607 +        Type falsetype = attribTree(tree.falsepart, env, condInfo);
   1.608 +
   1.609 +        Type owntype = standaloneConditional ? condType(tree, truetype, falsetype) : pt();
   1.610 +        if (condtype.constValue() != null &&
   1.611 +                truetype.constValue() != null &&
   1.612 +                falsetype.constValue() != null) {
   1.613 +            //constant folding
   1.614 +            owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype);
   1.615 +        }
   1.616 +        result = check(tree, owntype, VAL, resultInfo);
   1.617      }
   1.618      //where
   1.619 +        @SuppressWarnings("fallthrough")
   1.620 +        private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
   1.621 +            switch (tree.getTag()) {
   1.622 +                case LITERAL: return ((JCLiteral)tree).typetag < CLASS;
   1.623 +                case LAMBDA: case REFERENCE: return false;
   1.624 +                case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr);
   1.625 +                case CONDEXPR:
   1.626 +                    JCConditional condTree = (JCConditional)tree;
   1.627 +                    return isBooleanOrNumeric(env, condTree.truepart) &&
   1.628 +                            isBooleanOrNumeric(env, condTree.falsepart);
   1.629 +                default:
   1.630 +                    Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
   1.631 +                    speculativeType = types.unboxedTypeOrType(speculativeType);
   1.632 +                    return speculativeType.tag <= BOOLEAN;
   1.633 +            }
   1.634 +        }
   1.635 +
   1.636          /** Compute the type of a conditional expression, after
   1.637 -         *  checking that it exists. See Spec 15.25.
   1.638 -         *
   1.639 -         *  @param pos      The source position to be used for
   1.640 -         *                  error diagnostics.
   1.641 -         *  @param condtype The type of the expression's condition.
   1.642 -         *  @param thentype The type of the expression's then-part.
   1.643 -         *  @param elsetype The type of the expression's else-part.
   1.644 -         */
   1.645 -        private Type condType(DiagnosticPosition pos,
   1.646 -                              Type condtype,
   1.647 -                              Type thentype,
   1.648 -                              Type elsetype) {
   1.649 -            Type ctype = condType1(pos, condtype, thentype, elsetype);
   1.650 -
   1.651 -            // If condition and both arms are numeric constants,
   1.652 -            // evaluate at compile-time.
   1.653 -            return ((condtype.constValue() != null) &&
   1.654 -                    (thentype.constValue() != null) &&
   1.655 -                    (elsetype.constValue() != null))
   1.656 -                ? cfolder.coerce(condtype.isTrue()?thentype:elsetype, ctype)
   1.657 -                : ctype;
   1.658 -        }
   1.659 -        /** Compute the type of a conditional expression, after
   1.660 -         *  checking that it exists.  Does not take into
   1.661 +         *  checking that it exists.  See JLS 15.25. Does not take into
   1.662           *  account the special case where condition and both arms
   1.663           *  are constants.
   1.664           *
   1.665           *  @param pos      The source position to be used for error
   1.666           *                  diagnostics.
   1.667 -         *  @param condtype The type of the expression's condition.
   1.668           *  @param thentype The type of the expression's then-part.
   1.669           *  @param elsetype The type of the expression's else-part.
   1.670           */
   1.671 -        private Type condType1(DiagnosticPosition pos, Type condtype,
   1.672 +        private Type condType(DiagnosticPosition pos,
   1.673                                 Type thentype, Type elsetype) {
   1.674              // If same type, that is the result
   1.675              if (types.isSameType(thentype, elsetype))
   1.676 @@ -1445,22 +1547,19 @@
   1.677      public void visitReturn(JCReturn tree) {
   1.678          // Check that there is an enclosing method which is
   1.679          // nested within than the enclosing class.
   1.680 -        if (env.enclMethod == null ||
   1.681 -            env.enclMethod.sym.owner != env.enclClass.sym) {
   1.682 +        if (env.info.returnResult == null) {
   1.683              log.error(tree.pos(), "ret.outside.meth");
   1.684 -
   1.685          } else {
   1.686              // Attribute return expression, if it exists, and check that
   1.687              // it conforms to result type of enclosing method.
   1.688 -            Symbol m = env.enclMethod.sym;
   1.689 -            if (m.type.getReturnType().tag == VOID) {
   1.690 -                if (tree.expr != null)
   1.691 +            if (tree.expr != null) {
   1.692 +                if (env.info.returnResult.pt.tag == VOID) {
   1.693                      log.error(tree.expr.pos(),
   1.694                                "cant.ret.val.from.meth.decl.void");
   1.695 -            } else if (tree.expr == null) {
   1.696 +                }
   1.697 +                attribTree(tree.expr, env, env.info.returnResult);
   1.698 +            } else if (env.info.returnResult.pt.tag != VOID) {
   1.699                  log.error(tree.pos(), "missing.ret.val");
   1.700 -            } else {
   1.701 -                attribExpr(tree.expr, env, m.type.getReturnType());
   1.702              }
   1.703          }
   1.704          result = null;
   1.705 @@ -1562,7 +1661,7 @@
   1.706                      // current instance (JLS ???).
   1.707                      boolean selectSuperPrev = localEnv.info.selectSuper;
   1.708                      localEnv.info.selectSuper = true;
   1.709 -                    localEnv.info.varArgs = false;
   1.710 +                    localEnv.info.pendingResolutionPhase = null;
   1.711                      Symbol sym = rs.resolveConstructor(
   1.712                          tree.meth.pos(), localEnv, site, argtypes, typeargtypes);
   1.713                      localEnv.info.selectSuper = selectSuperPrev;
   1.714 @@ -1573,8 +1672,7 @@
   1.715                      // ...and check that it is legal in the current context.
   1.716                      // (this will also set the tree's type)
   1.717                      Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
   1.718 -                    checkId(tree.meth, site, sym, localEnv, new ResultInfo(MTH, mpt),
   1.719 -                            tree.varargsElement != null);
   1.720 +                    checkId(tree.meth, site, sym, localEnv, new ResultInfo(MTH, mpt));
   1.721                  }
   1.722                  // Otherwise, `site' is an error type and we do nothing
   1.723              }
   1.724 @@ -1589,8 +1687,8 @@
   1.725              // whose formal argument types is exactly the list of actual
   1.726              // arguments (this will also set the method symbol).
   1.727              Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
   1.728 -            localEnv.info.varArgs = false;
   1.729 -            Type mtype = attribExpr(tree.meth, localEnv, mpt);
   1.730 +            localEnv.info.pendingResolutionPhase = null;
   1.731 +            Type mtype = attribTree(tree.meth, localEnv, new ResultInfo(VAL, mpt, resultInfo.checkContext));
   1.732  
   1.733              // Compute the result type.
   1.734              Type restype = mtype.getReturnType();
   1.735 @@ -1625,7 +1723,7 @@
   1.736              // current context.  Also, capture the return type
   1.737              result = check(tree, capture(restype), VAL, resultInfo);
   1.738  
   1.739 -            if (localEnv.info.varArgs)
   1.740 +            if (localEnv.info.lastResolveVarargs())
   1.741                  Assert.check(result.isErroneous() || tree.varargsElement != null);
   1.742          }
   1.743          chk.validate(tree.typeargs, localEnv);
   1.744 @@ -1652,11 +1750,11 @@
   1.745          /** Obtain a method type with given argument types.
   1.746           */
   1.747          Type newMethodTemplate(Type restype, List<Type> argtypes, List<Type> typeargtypes) {
   1.748 -            MethodType mt = new MethodType(argtypes, restype, null, syms.methodClass);
   1.749 +            MethodType mt = new MethodType(argtypes, restype, List.<Type>nil(), syms.methodClass);
   1.750              return (typeargtypes == null) ? mt : (Type)new ForAll(typeargtypes, mt);
   1.751          }
   1.752  
   1.753 -    public void visitNewClass(JCNewClass tree) {
   1.754 +    public void visitNewClass(final JCNewClass tree) {
   1.755          Type owntype = types.createErrorType(tree.type);
   1.756  
   1.757          // The local environment of a class creation is
   1.758 @@ -1729,19 +1827,6 @@
   1.759          List<Type> argtypes = attribArgs(tree.args, localEnv);
   1.760          List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
   1.761  
   1.762 -        if (TreeInfo.isDiamond(tree) && !clazztype.isErroneous()) {
   1.763 -            Pair<Symbol, Type> diamondResult =
   1.764 -                    attribDiamond(localEnv, tree, clazztype, argtypes, typeargtypes);
   1.765 -            tree.clazz.type = types.createErrorType(clazztype);
   1.766 -            tree.constructor = diamondResult.fst;
   1.767 -            tree.constructorType = diamondResult.snd;
   1.768 -            if (!diamondResult.snd.isErroneous()) {
   1.769 -                tree.clazz.type = clazztype = diamondResult.snd.getReturnType();
   1.770 -                tree.constructorType = types.createMethodTypeWithReturn(diamondResult.snd, syms.voidType);
   1.771 -            }
   1.772 -            clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true);
   1.773 -        }
   1.774 -
   1.775          // If we have made no mistakes in the class type...
   1.776          if (clazztype.tag == CLASS) {
   1.777              // Enums may not be instantiated except implicitly
   1.778 @@ -1768,18 +1853,57 @@
   1.779                  // Error recovery: pretend no arguments were supplied.
   1.780                  argtypes = List.nil();
   1.781                  typeargtypes = List.nil();
   1.782 +            } else if (TreeInfo.isDiamond(tree)) {
   1.783 +                ClassType site = new ClassType(clazztype.getEnclosingType(),
   1.784 +                            clazztype.tsym.type.getTypeArguments(),
   1.785 +                            clazztype.tsym);
   1.786 +
   1.787 +                Env<AttrContext> diamondEnv = localEnv.dup(tree);
   1.788 +                diamondEnv.info.selectSuper = cdef != null;
   1.789 +                diamondEnv.info.pendingResolutionPhase = null;
   1.790 +
   1.791 +                //if the type of the instance creation expression is a class type
   1.792 +                //apply method resolution inference (JLS 15.12.2.7). The return type
   1.793 +                //of the resolved constructor will be a partially instantiated type
   1.794 +                Symbol constructor = rs.resolveDiamond(tree.pos(),
   1.795 +                            diamondEnv,
   1.796 +                            site,
   1.797 +                            argtypes,
   1.798 +                            typeargtypes);
   1.799 +                tree.constructor = constructor.baseSymbol();
   1.800 +
   1.801 +                final TypeSymbol csym = clazztype.tsym;
   1.802 +                ResultInfo diamondResult = new ResultInfo(MTH, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes), new Check.NestedCheckContext(resultInfo.checkContext) {
   1.803 +                    @Override
   1.804 +                    public void report(DiagnosticPosition _unused, JCDiagnostic details) {
   1.805 +                        enclosingContext.report(tree.clazz,
   1.806 +                                diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", csym), details));
   1.807 +                    }
   1.808 +                });
   1.809 +                Type constructorType = tree.constructorType = types.createErrorType(clazztype);
   1.810 +                constructorType = checkId(tree, site,
   1.811 +                        constructor,
   1.812 +                        diamondEnv,
   1.813 +                        diamondResult);
   1.814 +
   1.815 +                tree.clazz.type = types.createErrorType(clazztype);
   1.816 +                if (!constructorType.isErroneous()) {
   1.817 +                    tree.clazz.type = clazztype = constructorType.getReturnType();
   1.818 +                    tree.constructorType = types.createMethodTypeWithReturn(constructorType, syms.voidType);
   1.819 +                }
   1.820 +                clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true);
   1.821              }
   1.822  
   1.823              // Resolve the called constructor under the assumption
   1.824              // that we are referring to a superclass instance of the
   1.825              // current instance (JLS ???).
   1.826 -            else if (!TreeInfo.isDiamond(tree)) {
   1.827 +            else {
   1.828                  //the following code alters some of the fields in the current
   1.829                  //AttrContext - hence, the current context must be dup'ed in
   1.830                  //order to avoid downstream failures
   1.831                  Env<AttrContext> rsEnv = localEnv.dup(tree);
   1.832                  rsEnv.info.selectSuper = cdef != null;
   1.833 -                rsEnv.info.varArgs = false;
   1.834 +                rsEnv.info.pendingResolutionPhase = null;
   1.835                  tree.constructor = rs.resolveConstructor(
   1.836                      tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
   1.837                  if (cdef == null) { //do not check twice!
   1.838 @@ -1787,42 +1911,11 @@
   1.839                              clazztype,
   1.840                              tree.constructor,
   1.841                              rsEnv,
   1.842 -                            new ResultInfo(MTH, newMethodTemplate(syms.voidType, argtypes, typeargtypes)),
   1.843 -                            rsEnv.info.varArgs);
   1.844 -                    if (rsEnv.info.varArgs)
   1.845 +                            new ResultInfo(MTH, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
   1.846 +                    if (rsEnv.info.lastResolveVarargs())
   1.847                          Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
   1.848                  }
   1.849 -                if (tree.def == null &&
   1.850 -                        !clazztype.isErroneous() &&
   1.851 -                        clazztype.getTypeArguments().nonEmpty() &&
   1.852 -                        findDiamonds) {
   1.853 -                    boolean prevDeferDiags = log.deferDiagnostics;
   1.854 -                    Queue<JCDiagnostic> prevDeferredDiags = log.deferredDiagnostics;
   1.855 -                    Type inferred = null;
   1.856 -                    try {
   1.857 -                        //disable diamond-related diagnostics
   1.858 -                        log.deferDiagnostics = true;
   1.859 -                        log.deferredDiagnostics = ListBuffer.lb();
   1.860 -                        inferred = attribDiamond(localEnv,
   1.861 -                                tree,
   1.862 -                                clazztype,
   1.863 -                                argtypes,
   1.864 -                                typeargtypes).snd;
   1.865 -                    } finally {
   1.866 -                        log.deferDiagnostics = prevDeferDiags;
   1.867 -                        log.deferredDiagnostics = prevDeferredDiags;
   1.868 -                    }
   1.869 -                    if (!inferred.isErroneous()) {
   1.870 -                        inferred = inferred.getReturnType();
   1.871 -                    }
   1.872 -                    if (inferred != null &&
   1.873 -                            types.isAssignable(inferred, pt().tag == NONE ? syms.objectType : pt(), Warner.noWarnings)) {
   1.874 -                        String key = types.isSameType(clazztype, inferred) ?
   1.875 -                            "diamond.redundant.args" :
   1.876 -                            "diamond.redundant.args.1";
   1.877 -                        log.warning(tree.clazz.pos(), key, clazztype, inferred);
   1.878 -                    }
   1.879 -                }
   1.880 +                findDiamondIfNeeded(localEnv, tree, clazztype);
   1.881              }
   1.882  
   1.883              if (cdef != null) {
   1.884 @@ -1887,8 +1980,7 @@
   1.885                      clazztype,
   1.886                      tree.constructor,
   1.887                      localEnv,
   1.888 -                    new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes)),
   1.889 -                    localEnv.info.varArgs);
   1.890 +                    new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
   1.891              }
   1.892  
   1.893              if (tree.constructor != null && tree.constructor.kind == MTH)
   1.894 @@ -1897,53 +1989,33 @@
   1.895          result = check(tree, owntype, VAL, resultInfo);
   1.896          chk.validate(tree.typeargs, localEnv);
   1.897      }
   1.898 -
   1.899 -    Pair<Symbol, Type> attribDiamond(Env<AttrContext> env,
   1.900 -                        final JCNewClass tree,
   1.901 -                        final Type clazztype,
   1.902 -                        List<Type> argtypes,
   1.903 -                        List<Type> typeargtypes) {
   1.904 -        if (clazztype.isErroneous() ||
   1.905 -                clazztype.isInterface()) {
   1.906 -            //if the type of the instance creation expression is erroneous,
   1.907 -            //or if it's an interface, or if something prevented us to form a valid
   1.908 -            //mapping, return the (possibly erroneous) type unchanged
   1.909 -            return new Pair<Symbol, Type>(syms.noSymbol, clazztype);
   1.910 +    //where
   1.911 +        void findDiamondIfNeeded(Env<AttrContext> env, JCNewClass tree, Type clazztype) {
   1.912 +            if (tree.def == null &&
   1.913 +                    !clazztype.isErroneous() &&
   1.914 +                    clazztype.getTypeArguments().nonEmpty() &&
   1.915 +                    findDiamonds) {
   1.916 +                JCTypeApply ta = (JCTypeApply)tree.clazz;
   1.917 +                List<JCExpression> prevTypeargs = ta.arguments;
   1.918 +                try {
   1.919 +                    //create a 'fake' diamond AST node by removing type-argument trees
   1.920 +                    ta.arguments = List.nil();
   1.921 +                    ResultInfo findDiamondResult = new ResultInfo(VAL,
   1.922 +                            resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt());
   1.923 +                    Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type;
   1.924 +                    if (!inferred.isErroneous() &&
   1.925 +                        types.isAssignable(inferred, pt().tag == NONE ? syms.objectType : pt(), Warner.noWarnings)) {
   1.926 +                        String key = types.isSameType(clazztype, inferred) ?
   1.927 +                            "diamond.redundant.args" :
   1.928 +                            "diamond.redundant.args.1";
   1.929 +                        log.warning(tree.clazz.pos(), key, clazztype, inferred);
   1.930 +                    }
   1.931 +                } finally {
   1.932 +                    ta.arguments = prevTypeargs;
   1.933 +                }
   1.934 +            }
   1.935          }
   1.936  
   1.937 -        //dup attribution environment and augment the set of inference variables
   1.938 -        Env<AttrContext> localEnv = env.dup(tree);
   1.939 -
   1.940 -        ClassType site = new ClassType(clazztype.getEnclosingType(),
   1.941 -                    clazztype.tsym.type.getTypeArguments(),
   1.942 -                    clazztype.tsym);
   1.943 -
   1.944 -        //if the type of the instance creation expression is a class type
   1.945 -        //apply method resolution inference (JLS 15.12.2.7). The return type
   1.946 -        //of the resolved constructor will be a partially instantiated type
   1.947 -        Symbol constructor = rs.resolveDiamond(tree.pos(),
   1.948 -                    localEnv,
   1.949 -                    site,
   1.950 -                    argtypes,
   1.951 -                    typeargtypes);
   1.952 -
   1.953 -        Type constructorType = types.createErrorType(clazztype);
   1.954 -        ResultInfo diamondResult = new ResultInfo(MTH, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes), new Check.NestedCheckContext(resultInfo.checkContext) {
   1.955 -            @Override
   1.956 -            public void report(DiagnosticPosition _unused, JCDiagnostic details) {
   1.957 -                enclosingContext.report(tree.clazz,
   1.958 -                        diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", clazztype.tsym), details));
   1.959 -            }
   1.960 -        });
   1.961 -        constructorType = checkId(tree, site,
   1.962 -                constructor,
   1.963 -                localEnv,
   1.964 -                diamondResult,
   1.965 -                localEnv.info.varArgs);
   1.966 -
   1.967 -        return new Pair<Symbol, Type>(constructor.baseSymbol(), constructorType);
   1.968 -    }
   1.969 -
   1.970      /** Make an attributed null check tree.
   1.971       */
   1.972      public JCExpression makeNullCheck(JCExpression arg) {
   1.973 @@ -1960,13 +2032,14 @@
   1.974  
   1.975      public void visitNewArray(JCNewArray tree) {
   1.976          Type owntype = types.createErrorType(tree.type);
   1.977 +        Env<AttrContext> localEnv = env.dup(tree);
   1.978          Type elemtype;
   1.979          if (tree.elemtype != null) {
   1.980 -            elemtype = attribType(tree.elemtype, env);
   1.981 -            chk.validate(tree.elemtype, env);
   1.982 +            elemtype = attribType(tree.elemtype, localEnv);
   1.983 +            chk.validate(tree.elemtype, localEnv);
   1.984              owntype = elemtype;
   1.985              for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
   1.986 -                attribExpr(l.head, env, syms.intType);
   1.987 +                attribExpr(l.head, localEnv, syms.intType);
   1.988                  owntype = new ArrayType(owntype, syms.arrayClass);
   1.989              }
   1.990          } else {
   1.991 @@ -1983,7 +2056,7 @@
   1.992              }
   1.993          }
   1.994          if (tree.elems != null) {
   1.995 -            attribExprs(tree.elems, env, elemtype);
   1.996 +            attribExprs(tree.elems, localEnv, elemtype);
   1.997              owntype = new ArrayType(elemtype, syms.arrayClass);
   1.998          }
   1.999          if (!types.isReifiable(elemtype))
  1.1000 @@ -2132,18 +2205,34 @@
  1.1001          result = check(tree, owntype, VAL, resultInfo);
  1.1002      }
  1.1003  
  1.1004 -    public void visitTypeCast(JCTypeCast tree) {
  1.1005 +    public void visitTypeCast(final JCTypeCast tree) {
  1.1006          Type clazztype = attribType(tree.clazz, env);
  1.1007          chk.validate(tree.clazz, env, false);
  1.1008          //a fresh environment is required for 292 inference to work properly ---
  1.1009          //see Infer.instantiatePolymorphicSignatureInstance()
  1.1010          Env<AttrContext> localEnv = env.dup(tree);
  1.1011 -        Type exprtype = attribExpr(tree.expr, localEnv, Infer.anyPoly);
  1.1012 -        Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
  1.1013 +        //should we propagate the target type?
  1.1014 +        final ResultInfo castInfo;
  1.1015 +        final boolean isPoly = TreeInfo.isPoly(tree.expr, tree);
  1.1016 +        if (isPoly) {
  1.1017 +            //expression is a poly - we need to propagate target type info
  1.1018 +            castInfo = new ResultInfo(VAL, clazztype, new Check.NestedCheckContext(resultInfo.checkContext) {
  1.1019 +                @Override
  1.1020 +                public boolean compatible(Type found, Type req, Warner warn) {
  1.1021 +                    return types.isCastable(found, req, warn);
  1.1022 +                }
  1.1023 +            });
  1.1024 +        } else {
  1.1025 +            //standalone cast - target-type info is not propagated
  1.1026 +            castInfo = unknownExprInfo;
  1.1027 +        }
  1.1028 +        Type exprtype = attribTree(tree.expr, localEnv, castInfo);
  1.1029 +        Type owntype = isPoly ? clazztype : chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
  1.1030          if (exprtype.constValue() != null)
  1.1031              owntype = cfolder.coerce(exprtype, owntype);
  1.1032          result = check(tree, capture(owntype), VAL, resultInfo);
  1.1033 -        chk.checkRedundantCast(localEnv, tree);
  1.1034 +        if (!isPoly)
  1.1035 +            chk.checkRedundantCast(localEnv, tree);
  1.1036      }
  1.1037  
  1.1038      public void visitTypeTest(JCInstanceOf tree) {
  1.1039 @@ -2170,15 +2259,13 @@
  1.1040  
  1.1041      public void visitIdent(JCIdent tree) {
  1.1042          Symbol sym;
  1.1043 -        boolean varArgs = false;
  1.1044  
  1.1045          // Find symbol
  1.1046          if (pt().tag == METHOD || pt().tag == FORALL) {
  1.1047              // If we are looking for a method, the prototype `pt' will be a
  1.1048              // method type with the type of the call's arguments as parameters.
  1.1049 -            env.info.varArgs = false;
  1.1050 +            env.info.pendingResolutionPhase = null;
  1.1051              sym = rs.resolveMethod(tree.pos(), env, tree.name, pt().getParameterTypes(), pt().getTypeArguments());
  1.1052 -            varArgs = env.info.varArgs;
  1.1053          } else if (tree.sym != null && tree.sym.kind != VAR) {
  1.1054              sym = tree.sym;
  1.1055          } else {
  1.1056 @@ -2240,7 +2327,7 @@
  1.1057              while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym))
  1.1058                  env1 = env1.outer;
  1.1059          }
  1.1060 -        result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo, varArgs);
  1.1061 +        result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
  1.1062      }
  1.1063  
  1.1064      public void visitSelect(JCFieldAccess tree) {
  1.1065 @@ -2283,13 +2370,13 @@
  1.1066              sitesym.name == names._super;
  1.1067  
  1.1068          // Determine the symbol represented by the selection.
  1.1069 -        env.info.varArgs = false;
  1.1070 +        env.info.pendingResolutionPhase = null;
  1.1071          Symbol sym = selectSym(tree, sitesym, site, env, resultInfo);
  1.1072          if (sym.exists() && !isType(sym) && (pkind() & (PCK | TYP)) != 0) {
  1.1073              site = capture(site);
  1.1074              sym = selectSym(tree, sitesym, site, env, resultInfo);
  1.1075          }
  1.1076 -        boolean varArgs = env.info.varArgs;
  1.1077 +        boolean varArgs = env.info.lastResolveVarargs();
  1.1078          tree.sym = sym;
  1.1079  
  1.1080          if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) {
  1.1081 @@ -2340,7 +2427,7 @@
  1.1082                  if ((sym.flags() & STATIC) == 0 &&
  1.1083                      sym.name != names._super &&
  1.1084                      (sym.kind == VAR || sym.kind == MTH)) {
  1.1085 -                    rs.access(rs.new StaticError(sym),
  1.1086 +                    rs.accessBase(rs.new StaticError(sym),
  1.1087                                tree.pos(), site, sym.name, true);
  1.1088                  }
  1.1089              }
  1.1090 @@ -2364,7 +2451,7 @@
  1.1091          }
  1.1092  
  1.1093          env.info.selectSuper = selectSuperPrev;
  1.1094 -        result = checkId(tree, site, sym, env, resultInfo, varArgs);
  1.1095 +        result = checkId(tree, site, sym, env, resultInfo);
  1.1096      }
  1.1097      //where
  1.1098          /** Determine symbol referenced by a Select expression,
  1.1099 @@ -2383,7 +2470,7 @@
  1.1100              Name name = tree.name;
  1.1101              switch (site.tag) {
  1.1102              case PACKAGE:
  1.1103 -                return rs.access(
  1.1104 +                return rs.accessBase(
  1.1105                      rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind),
  1.1106                      pos, location, site, name, true);
  1.1107              case ARRAY:
  1.1108 @@ -2407,7 +2494,7 @@
  1.1109                      // We are seeing a plain identifier as selector.
  1.1110                      Symbol sym = rs.findIdentInType(env, site, name, resultInfo.pkind);
  1.1111                      if ((resultInfo.pkind & ERRONEOUS) == 0)
  1.1112 -                        sym = rs.access(sym, pos, location, site, name, true);
  1.1113 +                        sym = rs.accessBase(sym, pos, location, site, name, true);
  1.1114                      return sym;
  1.1115                  }
  1.1116              case WILDCARD:
  1.1117 @@ -2429,7 +2516,7 @@
  1.1118                      Symbol sym2 = (sym.flags() & Flags.PRIVATE) != 0 ?
  1.1119                          rs.new AccessError(env, site, sym) :
  1.1120                                  sym;
  1.1121 -                    rs.access(sym2, pos, location, site, name, true);
  1.1122 +                    rs.accessBase(sym2, pos, location, site, name, true);
  1.1123                      return sym;
  1.1124                  }
  1.1125              case ERROR:
  1.1126 @@ -2480,9 +2567,18 @@
  1.1127                       Type site,
  1.1128                       Symbol sym,
  1.1129                       Env<AttrContext> env,
  1.1130 -                     ResultInfo resultInfo,
  1.1131 -                     boolean useVarargs) {
  1.1132 -            if (resultInfo.pt.isErroneous()) return types.createErrorType(site);
  1.1133 +                     ResultInfo resultInfo) {
  1.1134 +            Type pt = resultInfo.pt.tag == FORALL || resultInfo.pt.tag == METHOD ?
  1.1135 +                    resultInfo.pt.map(deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase)) :
  1.1136 +                    resultInfo.pt;
  1.1137 +
  1.1138 +            DeferredAttr.DeferredTypeMap recoveryMap =
  1.1139 +                    deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
  1.1140 +
  1.1141 +            if (pt.isErroneous()) {
  1.1142 +                Type.map(resultInfo.pt.getParameterTypes(), recoveryMap);
  1.1143 +                return types.createErrorType(site);
  1.1144 +            }
  1.1145              Type owntype; // The computed type of this identifier occurrence.
  1.1146              switch (sym.kind) {
  1.1147              case TYP:
  1.1148 @@ -2560,10 +2656,11 @@
  1.1149                  owntype = checkMethod(site, sym,
  1.1150                          new ResultInfo(VAL, resultInfo.pt.getReturnType(), resultInfo.checkContext),
  1.1151                          env, TreeInfo.args(env.tree), resultInfo.pt.getParameterTypes(),
  1.1152 -                        resultInfo.pt.getTypeArguments(), env.info.varArgs);
  1.1153 +                        resultInfo.pt.getTypeArguments());
  1.1154                  break;
  1.1155              }
  1.1156              case PCK: case ERR:
  1.1157 +                Type.map(resultInfo.pt.getParameterTypes(), recoveryMap);
  1.1158                  owntype = sym.type;
  1.1159                  break;
  1.1160              default:
  1.1161 @@ -2703,8 +2800,7 @@
  1.1162                              Env<AttrContext> env,
  1.1163                              final List<JCExpression> argtrees,
  1.1164                              List<Type> argtypes,
  1.1165 -                            List<Type> typeargtypes,
  1.1166 -                            boolean useVarargs) {
  1.1167 +                            List<Type> typeargtypes) {
  1.1168          // Test (5): if symbol is an instance method of a raw type, issue
  1.1169          // an unchecked warning if its argument types change under erasure.
  1.1170          if (allowGenerics &&
  1.1171 @@ -2726,18 +2822,16 @@
  1.1172          // any type arguments and value arguments.
  1.1173          noteWarner.clear();
  1.1174          try {
  1.1175 -            Type owntype = rs.rawInstantiate(
  1.1176 +            Type owntype = rs.checkMethod(
  1.1177                      env,
  1.1178                      site,
  1.1179                      sym,
  1.1180                      resultInfo,
  1.1181                      argtypes,
  1.1182                      typeargtypes,
  1.1183 -                    allowBoxing,
  1.1184 -                    useVarargs,
  1.1185                      noteWarner);
  1.1186  
  1.1187 -            return chk.checkMethod(owntype, sym, env, argtrees, argtypes, useVarargs,
  1.1188 +            return chk.checkMethod(owntype, sym, env, argtrees, argtypes, env.info.lastResolveVarargs(),
  1.1189                      noteWarner.hasNonSilentLint(LintCategory.UNCHECKED));
  1.1190          } catch (Infer.InferenceException ex) {
  1.1191              //invalid target type - propagate exception outwards or report error
  1.1192 @@ -2745,7 +2839,7 @@
  1.1193              resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic());
  1.1194              return types.createErrorType(site);
  1.1195          } catch (Resolve.InapplicableMethodException ex) {
  1.1196 -            Assert.error();
  1.1197 +            Assert.error(ex.getDiagnostic().getMessage(Locale.getDefault()));
  1.1198              return null;
  1.1199          }
  1.1200      }
  1.1201 @@ -3053,8 +3147,10 @@
  1.1202  
  1.1203              Lint prevLint = chk.setLint(env.info.lint);
  1.1204              JavaFileObject prev = log.useSource(c.sourcefile);
  1.1205 +            ResultInfo prevReturnRes = env.info.returnResult;
  1.1206  
  1.1207              try {
  1.1208 +                env.info.returnResult = null;
  1.1209                  // java.lang.Enum may not be subclassed by a non-enum
  1.1210                  if (st.tsym == syms.enumSym &&
  1.1211                      ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
  1.1212 @@ -3071,6 +3167,7 @@
  1.1213  
  1.1214                  chk.checkDeprecatedAnnotation(env.tree.pos(), c);
  1.1215              } finally {
  1.1216 +                env.info.returnResult = prevReturnRes;
  1.1217                  log.useSource(prev);
  1.1218                  chk.setLint(prevLint);
  1.1219              }

mercurial