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

changeset 3001
dcd12fa5b58a
parent 2904
14891e981af0
child 3002
0caab0d65a04
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Oct 27 10:35:14 2015 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Nov 12 21:20:49 2015 +0000
     1.3 @@ -156,6 +156,8 @@
     1.4          unknownTypeInfo = new ResultInfo(TYP, Type.noType);
     1.5          unknownTypeExprInfo = new ResultInfo(Kinds.TYP | Kinds.VAL, Type.noType);
     1.6          recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
     1.7 +
     1.8 +        noCheckTree = make.at(-1).Skip();
     1.9      }
    1.10  
    1.11      /** Switch: relax some constraints for retrofit mode.
    1.12 @@ -253,31 +255,34 @@
    1.13      Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) {
    1.14          InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
    1.15          Type owntype;
    1.16 -        if (!found.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
    1.17 -            if ((ownkind & ~resultInfo.pkind) != 0) {
    1.18 -                log.error(tree.pos(), "unexpected.type",
    1.19 +        boolean shouldCheck = !found.hasTag(ERROR) &&
    1.20 +                !resultInfo.pt.hasTag(METHOD) &&
    1.21 +                !resultInfo.pt.hasTag(FORALL);
    1.22 +        if (shouldCheck && (ownkind & ~resultInfo.pkind) != 0) {
    1.23 +            log.error(tree.pos(), "unexpected.type",
    1.24                          kindNames(resultInfo.pkind),
    1.25                          kindName(ownkind));
    1.26 -                owntype = types.createErrorType(found);
    1.27 -            } else if (allowPoly && inferenceContext.free(found)) {
    1.28 -                //delay the check if there are inference variables in the found type
    1.29 -                //this means we are dealing with a partially inferred poly expression
    1.30 -                owntype = resultInfo.pt;
    1.31 -                inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
    1.32 +            owntype = types.createErrorType(found);
    1.33 +        } else if (allowPoly && inferenceContext.free(found)) {
    1.34 +            //delay the check if there are inference variables in the found type
    1.35 +            //this means we are dealing with a partially inferred poly expression
    1.36 +            owntype = shouldCheck ? resultInfo.pt : found;
    1.37 +            inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
    1.38                      @Override
    1.39                      public void typesInferred(InferenceContext inferenceContext) {
    1.40                          ResultInfo pendingResult =
    1.41                                  resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
    1.42                          check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
    1.43                      }
    1.44 -                });
    1.45 -            } else {
    1.46 -                owntype = resultInfo.check(tree, found);
    1.47 -            }
    1.48 +            });
    1.49          } else {
    1.50 -            owntype = found;
    1.51 +            owntype = shouldCheck ?
    1.52 +            resultInfo.check(tree, found) :
    1.53 +            found;
    1.54          }
    1.55 -        tree.type = owntype;
    1.56 +        if (tree != noCheckTree) {
    1.57 +            tree.type = owntype;
    1.58 +        }
    1.59          return owntype;
    1.60      }
    1.61  
    1.62 @@ -550,6 +555,10 @@
    1.63       */
    1.64      Type result;
    1.65  
    1.66 +    /** Synthetic tree to be used during 'fake' checks.
    1.67 +     */
    1.68 +    JCTree noCheckTree;
    1.69 +
    1.70      /** Visitor method: attribute a tree, catching any completion failure
    1.71       *  exceptions. Return the tree's type.
    1.72       *
    1.73 @@ -2043,7 +2052,7 @@
    1.74                      }
    1.75                  });
    1.76                  Type constructorType = tree.constructorType = types.createErrorType(clazztype);
    1.77 -                constructorType = checkId(tree, site,
    1.78 +                constructorType = checkId(noCheckTree, site,
    1.79                          constructor,
    1.80                          diamondEnv,
    1.81                          diamondResult);
    1.82 @@ -2069,7 +2078,7 @@
    1.83                  tree.constructor = rs.resolveConstructor(
    1.84                      tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
    1.85                  if (cdef == null) { //do not check twice!
    1.86 -                    tree.constructorType = checkId(tree,
    1.87 +                    tree.constructorType = checkId(noCheckTree,
    1.88                              clazztype,
    1.89                              tree.constructor,
    1.90                              rsEnv,
    1.91 @@ -2150,7 +2159,7 @@
    1.92                      tree.pos(), localEnv, clazztype, argtypes, typeargtypes);
    1.93                  Assert.check(sym.kind < AMBIGUOUS);
    1.94                  tree.constructor = sym;
    1.95 -                tree.constructorType = checkId(tree,
    1.96 +                tree.constructorType = checkId(noCheckTree,
    1.97                      clazztype,
    1.98                      tree.constructor,
    1.99                      localEnv,
   1.100 @@ -2161,6 +2170,17 @@
   1.101                  owntype = clazztype;
   1.102          }
   1.103          result = check(tree, owntype, VAL, resultInfo);
   1.104 +        InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
   1.105 +        if (tree.constructorType != null && inferenceContext.free(tree.constructorType)) {
   1.106 +            //we need to wait for inference to finish and then replace inference vars in the constructor type
   1.107 +            inferenceContext.addFreeTypeListener(List.of(tree.constructorType),
   1.108 +                    new FreeTypeListener() {
   1.109 +                        @Override
   1.110 +                        public void typesInferred(InferenceContext instantiatedContext) {
   1.111 +                            tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
   1.112 +                        }
   1.113 +                    });
   1.114 +        }
   1.115          chk.validate(tree.typeargs, localEnv);
   1.116      }
   1.117      //where
   1.118 @@ -2388,6 +2408,7 @@
   1.119              preFlow(that);
   1.120              flow.analyzeLambda(env, that, make, isSpeculativeRound);
   1.121  
   1.122 +            that.type = currentTarget; //avoids recovery at this stage
   1.123              checkLambdaCompatible(that, lambdaType, resultInfo.checkContext);
   1.124  
   1.125              if (!isSpeculativeRound) {
   1.126 @@ -2826,7 +2847,7 @@
   1.127                          that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes),
   1.128                          new FunctionalReturnContext(resultInfo.checkContext));
   1.129  
   1.130 -            Type refType = checkId(that, lookupHelper.site, refSym, localEnv, checkInfo);
   1.131 +            Type refType = checkId(noCheckTree, lookupHelper.site, refSym, localEnv, checkInfo);
   1.132  
   1.133              if (that.kind.isUnbound() &&
   1.134                      resultInfo.checkContext.inferenceContext().free(argtypes.head)) {
   1.135 @@ -2848,6 +2869,8 @@
   1.136              //is a no-op (as this has been taken care during method applicability)
   1.137              boolean isSpeculativeRound =
   1.138                      resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
   1.139 +
   1.140 +            that.type = currentTarget; //avoids recovery at this stage
   1.141              checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound);
   1.142              if (!isSpeculativeRound) {
   1.143                  checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, currentTarget);
   1.144 @@ -3968,7 +3991,7 @@
   1.145                  all_multicatchTypes.append(ctype);
   1.146              }
   1.147          }
   1.148 -        Type t = check(tree, types.lub(multicatchTypes.toList()), TYP, resultInfo);
   1.149 +        Type t = check(noCheckTree, types.lub(multicatchTypes.toList()), TYP, resultInfo);
   1.150          if (t.hasTag(CLASS)) {
   1.151              List<Type> alternatives =
   1.152                  ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList();

mercurial