diff -r ddec8c712e85 -r f5b5112ee1cc src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Mar 29 16:40:31 2011 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Mar 29 16:40:51 2011 +0100 @@ -1580,7 +1580,7 @@ // Attribute clazz expression and store // symbol + type back into the attributed tree. Type clazztype = attribType(clazz, env); - Pair mapping = getSyntheticScopeMapping(clazztype, cdef != null); + Pair mapping = getSyntheticScopeMapping(clazztype); clazztype = chk.checkDiamond(tree, clazztype); chk.validate(clazz, localEnv); if (tree.encl != null) { @@ -1778,62 +1778,48 @@ Pair mapping, List argtypes, List typeargtypes) { - if (clazztype.isErroneous() || mapping == erroneousMapping) { + if (clazztype.isErroneous() || + clazztype.isInterface() || + mapping == erroneousMapping) { //if the type of the instance creation expression is erroneous, - //or something prevented us to form a valid mapping, return the - //(possibly erroneous) type unchanged + //or if it's an interface, or if something prevented us to form a valid + //mapping, return the (possibly erroneous) type unchanged return clazztype; } - else if (clazztype.isInterface()) { - //if the type of the instance creation expression is an interface - //skip the method resolution step (JLS 15.12.2.7). The type to be - //inferred is of the kind C - clazztype = new ForAll(clazztype.tsym.type.allparams(), clazztype.tsym.type) { - @Override - public List getConstraints(TypeVar tv, ConstraintKind ck) { - switch (ck) { - case EXTENDS: return types.getBounds(tv); - default: return List.nil(); - } - } - @Override - public Type inst(List inferred, Types types) throws Infer.NoInstanceException { - // check that inferred bounds conform to their bounds - infer.checkWithinBounds(tvars, - types.subst(tvars, tvars, inferred), Warner.noWarnings); - return super.inst(inferred, types); - } - }; + + //dup attribution environment and augment the set of inference variables + Env localEnv = env.dup(tree); + localEnv.info.tvars = clazztype.tsym.type.getTypeArguments(); + + //if the type of the instance creation expression is a class type + //apply method resolution inference (JLS 15.12.2.7). The return type + //of the resolved constructor will be a partially instantiated type + ((ClassSymbol) clazztype.tsym).members_field = mapping.snd; + Symbol constructor; + try { + constructor = rs.resolveDiamond(tree.pos(), + localEnv, + clazztype.tsym.type, + argtypes, + typeargtypes); + } finally { + ((ClassSymbol) clazztype.tsym).members_field = mapping.fst; + } + if (constructor.kind == MTH) { + ClassType ct = new ClassType(clazztype.getEnclosingType(), + clazztype.tsym.type.getTypeArguments(), + clazztype.tsym); + clazztype = checkMethod(ct, + constructor, + localEnv, + tree.args, + argtypes, + typeargtypes, + localEnv.info.varArgs).getReturnType(); } else { - //if the type of the instance creation expression is a class type - //apply method resolution inference (JLS 15.12.2.7). The return type - //of the resolved constructor will be a partially instantiated type - ((ClassSymbol) clazztype.tsym).members_field = mapping.snd; - Symbol constructor; - try { - constructor = rs.resolveDiamond(tree.pos(), - env, - clazztype.tsym.type, - argtypes, - typeargtypes); - } finally { - ((ClassSymbol) clazztype.tsym).members_field = mapping.fst; - } - if (constructor.kind == MTH) { - ClassType ct = new ClassType(clazztype.getEnclosingType(), - clazztype.tsym.type.getTypeArguments(), - clazztype.tsym); - clazztype = checkMethod(ct, - constructor, - env, - tree.args, - argtypes, - typeargtypes, - env.info.varArgs).getReturnType(); - } else { - clazztype = syms.errType; - } + clazztype = syms.errType; } + if (clazztype.tag == FORALL && !pt.isErroneous()) { //if the resolved constructor's return type has some uninferred //type-variables, infer them using the expected type and declared @@ -1863,34 +1849,28 @@ * inference. The inferred return type of the synthetic constructor IS * the inferred type for the diamond operator. */ - private Pair getSyntheticScopeMapping(Type ctype, boolean overrideProtectedAccess) { + private Pair getSyntheticScopeMapping(Type ctype) { if (ctype.tag != CLASS) { return erroneousMapping; } + Pair mapping = new Pair(ctype.tsym.members(), new Scope(ctype.tsym)); - List typevars = ctype.tsym.type.getTypeArguments(); + + //for each constructor in the original scope, create a synthetic constructor + //whose return type is the type of the class in which the constructor is + //declared, and insert it into the new scope. for (Scope.Entry e = mapping.fst.lookup(names.init); e.scope != null; e = e.next()) { - MethodSymbol newConstr = (MethodSymbol) e.sym.clone(ctype.tsym); - if (overrideProtectedAccess && (newConstr.flags() & PROTECTED) != 0) { - //make protected constructor public (this is required for - //anonymous inner class creation expressions using diamond) - newConstr.flags_field |= PUBLIC; - newConstr.flags_field &= ~PROTECTED; - } - newConstr.name = names.init; - List oldTypeargs = List.nil(); - if (newConstr.type.tag == FORALL) { - oldTypeargs = ((ForAll) newConstr.type).tvars; - } - newConstr.type = new MethodType(newConstr.type.getParameterTypes(), - new ClassType(ctype.getEnclosingType(), ctype.tsym.type.getTypeArguments(), ctype.tsym), - newConstr.type.getThrownTypes(), - syms.methodClass); - newConstr.type = new ForAll(typevars.prependList(oldTypeargs), newConstr.type); - mapping.snd.enter(newConstr); + Type synthRestype = new ClassType(ctype.getEnclosingType(), + ctype.tsym.type.getTypeArguments(), + ctype.tsym); + MethodSymbol synhConstr = new MethodSymbol(e.sym.flags(), + names.init, + types.createMethodTypeWithReturn(e.sym.type, synthRestype), + e.sym.owner); + mapping.snd.enter(synhConstr); } return mapping; }