changeset 1050:495ee57deb1e

Improvements: *) Bring the compiler in sync with the latest method reference spec draft *) New inference algorithm for method/constructor references with elided arguments (elided arguments are now inferred from SAM descriptor) Bug fixes: *) Stack overflow in Lower caused by wrong attribution *) Spurious errors in generic method calls with explicit type-arguments (where one or more type-arguments are 'throws' type-vars)
author mcimadamore
date Thu, 23 Jun 2011 14:28:57 +0100
parents ee9b7df5f06b
children 33a9a25c7347
files src/share/classes/com/sun/source/tree/MemberReferenceTree.java src/share/classes/com/sun/source/util/TreeScanner.java src/share/classes/com/sun/tools/javac/code/Kinds.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Enter.java src/share/classes/com/sun/tools/javac/comp/Lower.java src/share/classes/com/sun/tools/javac/comp/Resolve.java src/share/classes/com/sun/tools/javac/jvm/Gen.java src/share/classes/com/sun/tools/javac/jvm/Pool.java src/share/classes/com/sun/tools/javac/parser/JavacParser.java src/share/classes/com/sun/tools/javac/resources/compiler.properties src/share/classes/com/sun/tools/javac/tree/JCTree.java src/share/classes/com/sun/tools/javac/tree/Pretty.java src/share/classes/com/sun/tools/javac/tree/TreeCopier.java src/share/classes/com/sun/tools/javac/tree/TreeMaker.java src/share/classes/com/sun/tools/javac/tree/TreeScanner.java test/tools/javac/diags/examples.not-yet.txt test/tools/javac/lambda/LambdaExpr07.java test/tools/javac/lambda/MethodReference02.java test/tools/javac/lambda/MethodReference02.out test/tools/javac/lambda/MethodReference09.out test/tools/javac/lambda/MethodReference20.out test/tools/javac/lambda/MethodReference22.java test/tools/javac/lambda/MethodReference22.out test/tools/javac/lambda/MethodReference23.java test/tools/javac/lambda/MethodReference23.out test/tools/javac/lambda/MethodReference24.java test/tools/javac/lambda/MethodReference25.java test/tools/javac/lambda/MethodReference26.java test/tools/javac/lambda/MethodReference26.out test/tools/javac/lambda/MethodReference27.java test/tools/javac/transparency/Neg04.java test/tools/javac/transparency/Neg04.out
diffstat 33 files changed, 843 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/source/tree/MemberReferenceTree.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/source/tree/MemberReferenceTree.java	Thu Jun 23 14:28:57 2011 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2011 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,10 @@
 
 package com.sun.source.tree;
 
+import java.util.List;
+
+import javax.lang.model.element.Name;
+
 /**
  * A tree node for a member reference expression.
  *
@@ -36,20 +40,20 @@
  * @see JSR 292
  *
  * @author John R. Rose
- * @since 1.7
+ * @author Maurizio Cimadamore
+ * @since 1.8
  */
 public interface MemberReferenceTree extends ExpressionTree {
     /** What kind of reference is this? */
     public enum ReferenceMode {
-        /** simple field reference x.&id; expr = x.id */
-        GET,
-        /** field reference for setting x.&=id; expr = x.id*/
-        SET,
         /** method reference x.&id(T...); expr = (x.id((T)>any<, ...)*/
         INVOKE,
         /** constructor reference new &id(T...); expr = (new id((T)>any<, ...)*/
         NEW
     }
     ReferenceMode getMode();
-    ExpressionTree getSelection();
+    ExpressionTree getQualifierExpression();
+    Name getName();
+    List<? extends ExpressionTree> getArguments();
+    List<? extends ExpressionTree> getTypeArguments();
 }
--- a/src/share/classes/com/sun/source/util/TreeScanner.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/source/util/TreeScanner.java	Thu Jun 23 14:28:57 2011 +0100
@@ -340,7 +340,10 @@
     }
 
     public R visitMemberReference(MemberReferenceTree node, P p) {
-        return scan(node.getSelection(), p);
+        R r = scan(node.getQualifierExpression(), p);
+        r = scanAndReduce(node.getArguments(), p, r);
+        r = scanAndReduce(node.getTypeArguments(), p, r);
+        return r;
     }
 
     public R visitIdentifier(IdentifierTree node, P p) {
--- a/src/share/classes/com/sun/tools/javac/code/Kinds.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Kinds.java	Thu Jun 23 14:28:57 2011 +0100
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.code;
 
+import com.sun.source.tree.MemberReferenceTree;
 import java.util.EnumSet;
 import java.util.Locale;
 
@@ -138,6 +139,14 @@
         }
     }
 
+    public static KindName kindName(MemberReferenceTree.ReferenceMode mode) {
+        switch (mode) {
+            case INVOKE: return KindName.METHOD;
+            case NEW: return KindName.CONSTRUCTOR;
+            default : throw new AssertionError("Unexpected mode: "+ mode);
+        }
+    }
+
     /** A KindName representing a given symbol
      */
     public static KindName kindName(Symbol sym) {
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jun 23 14:28:57 2011 +0100
@@ -46,6 +46,7 @@
 import com.sun.tools.javac.code.Type.*;
 
 import com.sun.source.tree.IdentifierTree;
+import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
 import com.sun.source.tree.MemberSelectTree;
 import com.sun.source.tree.TreeVisitor;
 import com.sun.source.util.SimpleTreeVisitor;
@@ -1620,7 +1621,13 @@
                 capture(restype) :
                 check(tree, capture(restype), VAL, pkind, pt);
         }
-        chk.validate(tree.typeargs, localEnv);
+        try {
+            localEnv.info.allowsDisjointTypes = true;
+            chk.validate(tree.typeargs, localEnv);
+        }
+        finally {
+            localEnv.info.allowsDisjointTypes = false;
+        }
     }
     //where
         /** Check that given application node appears as first statement
@@ -2597,19 +2604,36 @@
             result = that.type = syms.errType;
             return;
         }
+
+        //attribute member reference qualifier - if this is a constructor
+        //reference, the expected kind must be a type
+        final Type exprType = attribTree(that.expr,
+                env,
+                that.getMode() == ReferenceMode.INVOKE ? VAL | TYP : TYP,
+                Type.noType);
+
+        if (exprType.isErroneous()) {
+            //if the qualifier expression contains problems,
+            //give up atttribution of method reference
+            result = that.type = syms.errType;
+            return;
+        }
+
+        if (TreeInfo.isStaticSelector(that.expr, names)) {
+            //if the qualifier is a type, validate it
+            chk.validate(that.expr, env);
+        }
         
         Assert.check(that.mode == JCMemberReference.ReferenceMode.INVOKE ||
                 that.mode == JCMemberReference.ReferenceMode.NEW);
 
-        final JCMethodInvocation apply = (JCMethodInvocation) that.expr;
-
         final ForAll owntype = new SAMDeferredAttribution<JCMemberReference>(POLY_REFERENCE, env, that) {
 
             List<Type> initialParameterTypes;
 
             {
-                if (apply.args != null) {
-                    initialParameterTypes = complete(Type.noType, false, false).getParameterTypes();
+                if (that.args != null) {
+                    initialParameterTypes = attribAnyTypes(that.args, env);
                 }
             }
 
@@ -2623,48 +2647,87 @@
             Type deferredAttr(Env<AttrContext> attrEnv, JCMemberReference treeToCheck, Type pt, boolean allowBoxing, boolean check) {
                 return attribMethodReference(attrEnv, treeToCheck, pt, allowBoxing);
             }
+
+            @Override
+            Type instantiateSAM(Type to, List<Type> paramTypes) {
+                Types.SAMResult samRes = types.findSAM(to, env);
+                if (paramTypes != null && !samRes.isErroneous()) {
+                    Type samDesc = samRes.getTargetType();
+                    if (samDesc.getParameterTypes().size() - paramTypes.size() == 1) {
+                        //if number of explicit arguments does not match the
+                        //SAM descriptor arity, try to add a synthetic explicit
+                        //argument, whose type is the qualifier type
+                        paramTypes = paramTypes.prepend(exprType);
+                    }
+                }
+                return super.instantiateSAM(to, paramTypes);
+            }
         };
         result = check(that, owntype, VAL, pkind, pt);
     }
 
     //where
-    private Type attribMethodReference(Env<AttrContext> localEnv, final JCMemberReference tree, Type to, boolean allowBoxing) {
+    private Type attribMethodReference(Env<AttrContext> localEnv, JCMemberReference tree, Type to, boolean allowBoxing) {
         Assert.check(tree.mode == JCMemberReference.ReferenceMode.INVOKE ||
                 tree.mode == JCMemberReference.ReferenceMode.NEW);
-            
-        JCMethodInvocation apply = (JCMethodInvocation) tree.expr;
-        apply.type = attribExpr(apply, localEnv);
-        JCTree base = TreeInfo.getSelector(apply);
-        if (TreeInfo.isStaticSelector(base, names)) {
-            chk.validate(base, localEnv);
+
+        Types.SAMResult samRes = types.findSAM(to, localEnv);
+        Type samDesc = samRes.getTargetType();
+
+        //attrib type-arguments and receiver expr
+        List<Type> typeargtypes = List.nil();
+        if (tree.typeargs != null) {
+            typeargtypes = attribTypes(tree.typeargs, localEnv);
         }
-        tree.sym = TreeInfo.symbol(apply.meth);
-        Type mtype = apply.meth.type;
-        
-        if (apply.meth.type.isErroneous()) return apply.meth.type;
-
-        List<Type> args = mtype.getParameterTypes();
-        if (!tree.sym.isStatic() &&
-                !tree.sym.isConstructor() &&
-                TreeInfo.isStaticSelector(base, names)) {
-            args = args.prepend(base.type);
+        attribTree(tree.expr, localEnv, VAL | TYP, Type.noType);
+
+        List<Type> argtypes = tree.args != null ?
+            attribAnyTypes(tree.args, env) :
+            samDesc.getParameterTypes();
+
+        boolean prevDeferDiagnostics = log.deferDiagnostics;
+        Symbol refSym = syms.noSymbol;
+        try {
+            log.deferDiagnostics = true;
+            refSym = rs.resolveMemberReference(tree.pos(), localEnv, tree.expr.type,
+                    tree.name, argtypes, typeargtypes, tree.args == null,
+                    TreeInfo.isStaticSelector(tree.expr, names), allowBoxing);
         }
-
-        Type resType = tree.sym.isConstructor() ? base.type : mtype.getReturnType();
-
-        if (to.tag != NONE) {
-            //check mtype against sam descriptor
-            checkSAMCompatible(to, List.of(resType), args, mtype.getThrownTypes(), allowBoxing, true);
-            return to;
-        } else { //hack to support current inference strategy for method references
-            final List<Type> parameterTypes = args;
-            return new Type(NONE, syms.noSymbol) {
-                @Override
-                public List<Type> getParameterTypes() {
-                    return parameterTypes;
-                }
-            };
+        finally {
+            log.deferDiagnostics = prevDeferDiagnostics;
         }
+
+        if (refSym.kind != MTH) {
+            Name refName = tree.getMode() == ReferenceMode.INVOKE ?
+                tree.name :
+                tree.expr.type.tsym.name;
+            switch (refSym.kind) {
+                case ABSENT_MTH:
+                case WRONG_MTH:
+                case WRONG_MTHS:
+                    throw new Infer.InferenceException(diags)
+                            .setMessage("reference.not.found",
+                                        Kinds.kindName(tree.getMode()),
+                                        refName,
+                                        samDesc.getParameterTypes());
+                case AMBIGUOUS:
+                    Resolve.AmbiguityError err = (Resolve.AmbiguityError)refSym;
+                    throw new Infer.InferenceException(diags)
+                            .setMessage("reference.ambiguous",
+                                        Kinds.kindName(tree.getMode()),
+                                        refName,
+                                        err.sym.type.getParameterTypes(),
+                                        err.sym2.type.getParameterTypes());
+                default: Assert.error("unexpected result kind " + refSym.kind);
+            }
+        }
+
+        tree.sym = refSym;
+        Type mtype = types.memberType(tree.expr.type, tree.sym);
+        Type returnType = tree.getMode() == ReferenceMode.INVOKE ?
+                mtype.getReturnType() : tree.expr.type;
+        checkSAMCompatible(to, List.of(returnType), samDesc.getParameterTypes(), mtype.getThrownTypes(), allowBoxing, true);
+        return to;
     }
 
     /**
@@ -2742,7 +2805,7 @@
             if (completed) return qtype;
             Type targetType = null;
             try {
-                targetType = infer.inferSAM(env, to, getParameterTypes());
+                targetType = instantiateSAM(to, getParameterTypes());
             }
             catch (Infer.InferenceException ex) {
                 throw new Infer.InferenceException(diags).setMessage("no.suitable.sam.inst", to);
@@ -2778,6 +2841,10 @@
             }
         }
 
+        Type instantiateSAM(Type to, List<Type> paramTypes) {
+            return infer.inferSAM(env, to, paramTypes);
+        }
+
         abstract Type deferredAttr(Env<AttrContext> attrEnv, T t, Type pt, boolean allowBoxing, boolean check);
     }
 
--- a/src/share/classes/com/sun/tools/javac/comp/Enter.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu Jun 23 14:28:57 2011 +0100
@@ -422,8 +422,7 @@
             // (its "enclosing instance class"), provided such a class exists.
             Symbol owner1 = owner;
             while ((owner1.kind & (VAR | MTH)) != 0 &&
-                   (owner1.flags_field & STATIC) == 0 &&
-                   (owner1.flags_field & LAMBDA) == 0) {
+                   (owner1.flags_field & STATIC) == 0) {
                 owner1 = owner1.owner;
             }
             if (owner1.kind == TYP) {
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Jun 23 14:28:57 2011 +0100
@@ -2925,19 +2925,6 @@
         }
     }
 
-    @Override
-    public void visitReference(JCMemberReference tree) {
-        if (tree.expr.getTag() != JCTree.APPLY ||
-                !(tree.getMode() == ReferenceMode.INVOKE ||
-                tree.getMode() == ReferenceMode.NEW)) {
-            throw new AssertionError();
-        }
-        JCMethodInvocation apply = (JCMethodInvocation)tree.expr;
-        JCExpression translatedMeth = translate(apply.meth);
-        apply.meth = translatedMeth;
-        result = tree;
-    }
-
     public void visitApply(JCMethodInvocation tree) {
         Symbol meth = TreeInfo.symbol(tree.meth);
         if (meth.name == names.empty &&
@@ -4086,13 +4073,15 @@
     
     JCExpression makeMethodHandle(MethodSymbol msym) {
         if (useMethodHandleLDC) {
-            JCExpression lambdaRef = make.Select(make.QualIdent(currentClass), msym);
             ListBuffer<JCExpression> argtypes = ListBuffer.lb();
             for (Type paramType : msym.type.getParameterTypes()) {
                 argtypes.append(make.QualIdent(paramType.tsym).setType(paramType));
             }
-            JCMethodInvocation lambdaCall = make.Apply(List.<JCExpression>nil(), lambdaRef, argtypes.toList(), true).setType(syms.methodHandleType);
-            JCMemberReference handle = (JCMemberReference)make.Reference(ReferenceMode.INVOKE, lambdaCall).setType(syms.methodHandleType);
+            JCMemberReference handle = (JCMemberReference)make.Reference(ReferenceMode.INVOKE,
+                    msym.name,
+                    make.QualIdent(currentClass),
+                    argtypes.toList(),
+                    List.<JCExpression>nil()).setType(syms.methodHandleType);
             handle.sym = msym;
             return handle;
         }
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Jun 23 14:28:57 2011 +0100
@@ -358,9 +358,14 @@
                 actuals2.append(actual);
                 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
                                                 mt.getTypeArguments(), typeargtypes);
-                for (; bounds.nonEmpty(); bounds = bounds.tail)
+                for (; bounds.nonEmpty(); bounds = bounds.tail) {
                     if (!types.isSubtypeUnchecked(actual, bounds.head, warn))
                         throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
+                    if ((actuals.head.tsym.flags() & THROWS) != 0 &&
+                        (formals.head.tsym.flags() & THROWS) == 0) {
+                        throw inapplicableMethodException.setMessage("throws.typaram.not.allowed.here", actuals.head);
+                    }
+                }
                 formals = formals.tail;
                 actuals = actuals.tail;
             }
@@ -1818,6 +1823,145 @@
             currentResolutionContext = prevResolutionContext;
         }
     }
+    
+    /**
+     * Resolution of member references is typically done as a single
+     * overload resolution step, where the argument types A are either
+     * provided explicitly, or inferred fom the target SAM descriptor.
+     *
+     * There are however two cases in which resolution is done in a more
+     * convoluted two step-process:
+     *
+     * (a) - method reference with elided arguments with a type qualifier
+     * (b) - constructor reference with elided arguments involving a member inner class
+     *
+     * In the case of (a), two resolution steps are performed, one with the
+     * expected argument list A and one where the first element in A
+     * is discarded. The second step is only performed if the first element
+     * in the inferred argument list is a subtype of the qualifier expression type.
+     *
+     * In the case of (b), two resolution steps are performed, one with the
+     * expected argument list A and one where the first element in the inferred
+     * argument list is discarded. The first step is only performed if an
+     * implicit reference to an enclosing instance is available. The second
+     * step is only performed if the first element in the inferred argument
+     * list is a member of the enclosing type.
+     *
+     * When a multi-step resolution process is exploited, it is an error
+     * if two candidates are found (ambiguity).
+     */
+    Symbol resolveMemberReference(DiagnosticPosition pos,
+                                  Env<AttrContext> env,
+                                  Type site,
+                                  Name name, List<Type> argtypes,
+                                  List<Type> typeargtypes,
+                                  boolean implicitArgs,
+                                  boolean typeQualifier,
+                                  boolean allowBoxing) {
+
+        boolean isConstructorRef = name.equals(names.init);
+        boolean isMethodRef = !isConstructorRef;
+
+        Symbol bestSoFar = methodNotFound;
+
+        boolean needsMultiStepResolution = implicitArgs &&
+                (isMethodRef && typeQualifier ||
+                isConstructorRef && site.getEnclosingType().tag != NONE);
+        
+        if (needsMultiStepResolution) {
+
+            //first resolution step
+            if (!isConstructorRef ||
+                    !resolveImplicitThis(pos, env, site).isErroneous()) {
+                bestSoFar = findMemberReference(pos, env, site, name,
+                                                argtypes,typeargtypes,
+                                                isConstructorRef ? MemberReferenceFilter.ANY : MemberReferenceFilter.STATIC,
+                                                allowBoxing);
+            }
+
+            //second resolution step
+            if (argtypes.nonEmpty() &&
+                    ((isMethodRef && types.isSubtypeUnchecked(argtypes.head, site) ||
+                    (isConstructorRef && types.asEnclosingSuper(site, argtypes.head.tsym) != null)))) {
+                Symbol sym2 = methodNotFound;
+                sym2 = findMemberReference(pos, env, site, name,
+                                           argtypes.tail, typeargtypes,
+                                           isConstructorRef ? MemberReferenceFilter.ANY : MemberReferenceFilter.NON_STATIC,
+                                           allowBoxing);
+                if (sym2.kind == MTH) {
+                    bestSoFar = bestSoFar.kind == MTH ?
+                        ambiguityError(bestSoFar, sym2) : sym2;
+                }
+            }
+        } else {
+            //single resolution step
+            bestSoFar = findMemberReference(pos, env, site, name,
+                                            argtypes, typeargtypes,
+                                            MemberReferenceFilter.ANY, allowBoxing);
+        }
+
+        return bestSoFar;
+    }
+
+    /**
+     * Resolution step for member reference. This is based upon a standard
+     * ethod/constructor resolution step, with two important differences:
+     * (i) if the resolved symbol is of the wrong kind (i.e. static symbol
+     * found where non-static symbol was expected) an erroneous symbol is
+     * returned; (ii) boxing/unboxing can be turned on/off on demand.
+     */
+    Symbol findMemberReference(DiagnosticPosition pos,
+                               Env<AttrContext> env,
+                               Type site, Name name,
+                               List<Type> argtypes,
+                               List<Type> typeargtypes,
+                               MemberReferenceFilter refFilter,
+                               boolean allowBoxing) {
+        MethodResolutionContext prevResolutionContext = currentResolutionContext;
+        try {
+            currentResolutionContext = new MethodResolutionContext();
+            Symbol sym = methodNotFound;
+            List<MethodResolutionPhase> steps = allowBoxing ?
+                methodResolutionSteps :
+                List.of(MethodResolutionPhase.BASIC);
+            while (steps.nonEmpty() &&
+                   steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+                   sym.kind >= ERRONEOUS) {
+                currentResolutionContext.step = steps.head;
+                sym = name.equals(names.init) ?
+                    findConstructor(pos, env, site, argtypes, typeargtypes,
+                                    steps.head.isBoxingRequired(),
+                                    steps.head.isVarargsRequired()) :
+                    findMethod(env, site, name, argtypes, typeargtypes,
+                               steps.head.isBoxingRequired(),
+                               steps.head.isVarargsRequired(), false);
+                currentResolutionContext.resolutionCache.put(steps.head, sym);
+                steps = steps.tail;
+            }
+            return sym.kind == MTH && refFilter.accepts(sym) ? sym : methodNotFound;
+        }
+        finally {
+            currentResolutionContext = prevResolutionContext;
+        }
+    }
+
+    enum MemberReferenceFilter implements Filter<Symbol> {
+        STATIC(Flags.STATIC, Flags.STATIC),
+        NON_STATIC(Flags.STATIC, 0),
+        ANY(0, 0);
+
+        long flagsMask;
+        long expectedFlags;
+
+        private MemberReferenceFilter(long flagsMask, long expectedFlags) {
+            this.flagsMask = flagsMask;
+            this.expectedFlags = expectedFlags;
+        }
+
+        public boolean accepts(Symbol t) {
+            return (t.flags() & flagsMask) == expectedFlags;
+        }
+    }
 
     /** Resolve constructor.
      *  @param pos       The position to use for error reporting.
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Jun 23 14:28:57 2011 +0100
@@ -2182,17 +2182,9 @@
 
     public void visitReference(JCMemberReference tree) {
         Symbol refSym = tree.sym;
-        JCExpression base = TreeInfo.getSelector(tree.expr);
         final boolean isStatic = refSym.isStatic();
+        JCExpression base = tree.expr;
         switch (tree.mode) {
-            case GET:
-                refSym = binaryQualifier(refSym, base.type);
-                refSym = Pool.delegateSymbol((VarSymbol)refSym);
-                break;
-            case SET:
-                refSym = binaryQualifier(refSym, base.type);
-                refSym = Pool.delegateSymbol((VarSymbol)refSym);
-                break;
             case INVOKE:
                 refSym = binaryQualifier(refSym, base.type);
                 refSym = Pool.delegateSymbol((MethodSymbol)refSym);
@@ -2232,10 +2224,6 @@
     private int computeRefKind(JCMemberReference tree) {
         boolean isStatic = tree.sym.isStatic();
         switch (tree.mode) {
-            case GET:
-                return MemberReference.fieldRefKind(isStatic, false);
-            case SET:
-                return MemberReference.fieldRefKind(isStatic, true);
             case INVOKE:
             {
                 boolean isInterface = tree.sym.owner.isInterface();
@@ -2244,7 +2232,7 @@
                     return refKind;
                 if ((tree.sym.flags() & PRIVATE) != 0)
                     return ClassFile.REF_invokeSpecial;
-                JCExpression base = TreeInfo.getSelector(tree.expr);
+                JCExpression base = tree.expr;
                 if (base != null) {
                     Symbol bsym = TreeInfo.symbol(base);
                     // Are we selecting via super?
--- a/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Thu Jun 23 14:28:57 2011 +0100
@@ -205,12 +205,6 @@
                 refSym.type.hashCode();
         }
 
-        public static int fieldRefKind(boolean isStatic, boolean isSetter) {
-            if (!isSetter)
-                return isStatic ? ClassFile.REF_getStatic : ClassFile.REF_getField;
-            else
-                return isStatic ? ClassFile.REF_putStatic : ClassFile.REF_putField;
-        }
         public static int methodRefKind(boolean isStatic, boolean isInterface) {
             if (isStatic)
                 return ClassFile.REF_invokeStatic;
@@ -219,38 +213,30 @@
             else
                 return ClassFile.REF_invokeVirtual;
         }
+
         public static int specialRefKind(boolean isConstructor) {
             if (!isConstructor)
                 return ClassFile.REF_invokeSpecial;
             else
                 return ClassFile.REF_newInvokeSpecial;
         }
+
         private boolean isConsistent() {
             // Check consistency of reference kind and symbol.
             // Methods invoked, fields get/put; static must match, etc.
             boolean isStatic = refSym.isStatic();
             int expectedRefKind;
             switch (refSym.kind) {
-            case Kinds.VAR:
-                expectedRefKind = fieldRefKind(isStatic, false);
-                if (refKind == expectedRefKind)
-                    return true;
-                if ((refSym.flags() & Flags.FINAL) == 0) {
-                    // Could be a field setter.
-                    if (refKind == fieldRefKind(isStatic, true))
+                case Kinds.MTH:
+                    if (refSym.isConstructor())
+                        return (refKind == specialRefKind(true));
+                    expectedRefKind = methodRefKind(isStatic, refSym.owner.isInterface());
+                    if (refKind == expectedRefKind)
                         return true;
-                }
-                break;
-            case Kinds.MTH:
-                if (refSym.isConstructor())
-                    return (refKind == specialRefKind(true));
-                expectedRefKind = methodRefKind(isStatic, refSym.owner.isInterface());
-                if (refKind == expectedRefKind)
-                    return true;
-                if (expectedRefKind == ClassFile.REF_invokeVirtual
-                         && refKind == ClassFile.REF_invokeSpecial)
-                    return true;  // assume access is OK
-                break;
+                    if (expectedRefKind == ClassFile.REF_invokeVirtual
+                             && refKind == ClassFile.REF_invokeSpecial)
+                        return true;  // assume access is OK
+                    break;
             }
             return false;
         }
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Jun 23 14:28:57 2011 +0100
@@ -1613,16 +1613,11 @@
             refMode = ReferenceMode.INVOKE;
             refName = ident();
         }
-        t = toP(F.at(pos1).Select(t, refName));
-        int pos2 = S.pos();
+        List<JCExpression> args = null;
         if (S.token() == LPAREN) {
-            List<JCExpression> types = methodParameterTypes();
-            t = toP(F.at(pos2).Apply(typeArgs, t, types, true));
+            args = methodParameterTypes();
         }
-        else {
-            t = toP(F.at(pos2).Apply(typeArgs, t, null, true));
-        }
-        return toP(F.at(t.getStartPosition()).Reference(refMode, t));
+        return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, args, typeArgs));
     }
 
     /** MethodParameterTypes = "(" [ typeList ] ")"
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Jun 23 14:28:57 2011 +0100
@@ -202,6 +202,12 @@
 compiler.misc.no.suitable.sam.inst=\
     no instance of type {0} exists so that lambda expression can be type-checked
 
+compiler.misc.reference.not.found=\
+    cannot find {0} reference {1}({2})
+
+compiler.misc.reference.ambiguous=\
+    ambiguous {0} reference - both {1}({2}) and {1}({3}) match
+
 # 0: symbol
 compiler.err.cant.assign.val.to.final.var=\
     cannot assign a value to final variable {0}
@@ -909,6 +915,9 @@
 compiler.err.throws.typaram.not.allowed.here=\
     ''throws'' type-parameter not allowed here
 
+compiler.misc.throws.typaram.not.allowed.here=\
+    unexpected ''throws'' type-parameter {0}
+
 compiler.err.disjoint.type.not.allowed.here=\
     disjoint type argument not allowed here
 
--- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Jun 23 14:28:57 2011 +0100
@@ -1785,12 +1785,18 @@
      */
     public static class JCMemberReference extends JCExpression implements MemberReferenceTree {
         public ReferenceMode mode;
+        public Name name;
         public JCExpression expr;
+        public List<JCExpression> args;
+        public List<JCExpression> typeargs;
         public Symbol sym;
-        protected JCMemberReference(ReferenceMode mode, JCExpression expr, Symbol sym) {
+
+        protected JCMemberReference(ReferenceMode mode, Name name, JCExpression expr, List<JCExpression> args, List<JCExpression> typeargs) {
             this.mode = mode;
+            this.name = name;
             this.expr = expr;
-            this.sym = sym;
+            this.args = args;
+            this.typeargs = typeargs;
         }
         @Override
         public void accept(Visitor v) { v.visitReference(this); }
@@ -1799,7 +1805,14 @@
         @Override
         public ReferenceMode getMode() { return mode; }
         @Override
-        public JCExpression getSelection() { return expr; }
+        public JCExpression getQualifierExpression() { return expr; }
+        @Override
+        public Name getName() { return name; }
+        @Override
+        public List<JCExpression> getArguments() { return args; }
+        @Override
+        public List<JCExpression> getTypeArguments() { return typeargs; }
+
         @Override
         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
             return v.visitMemberReference(this, d);
--- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Thu Jun 23 14:28:57 2011 +0100
@@ -1102,7 +1102,23 @@
     public void visitReference(JCMemberReference tree) {
         switch (tree.mode) {
         case INVOKE:
-            printApply((JCMethodInvocation) tree.expr, "#");
+            try {
+                printExpr(tree.expr);
+                print("#");
+                if (tree.typeargs != null) {
+                    print("<");
+                    printExprs(tree.typeargs);
+                    print(">");
+                }
+                print(tree.name);
+                if (tree.args != null) {
+                    print("(");
+                    printExprs(tree.args);
+                    print(")");
+                }
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
             break;
         default:
             throw new AssertionError("Unexpected reference kind: " + tree.mode);
--- a/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Thu Jun 23 14:28:57 2011 +0100
@@ -299,7 +299,9 @@
     public JCTree visitMemberReference(MemberReferenceTree node, P p) {
         JCMemberReference t = (JCMemberReference) node;
         JCExpression expr = copy(t.expr, p);
-        return M.at(t.pos).Reference(t.mode, expr);
+        List<JCExpression> args = copy(t.args, p);
+        List<JCExpression> typeargs = copy(t.typeargs, p);
+        return M.at(t.pos).Reference(t.mode, t.name, expr, args, typeargs);
     }
 
     public JCTree visitEmptyStatement(EmptyStatementTree node, P p) {
--- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Jun 23 14:28:57 2011 +0100
@@ -413,8 +413,9 @@
         return tree;
     }
 
-    public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, JCExpression t) {
-        JCMemberReference tree = new JCMemberReference(mode, t, null);
+    public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name,
+            JCExpression expr, List<JCExpression> args, List<JCExpression> typeargs) {
+        JCMemberReference tree = new JCMemberReference(mode, name, expr, args, typeargs);
         tree.pos = pos;
         return tree;
     }
--- a/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Thu Jun 23 14:28:57 2011 +0100
@@ -261,6 +261,8 @@
 
     public void visitReference(JCMemberReference tree) {
         scan(tree.expr);
+        scan(tree.args);
+        scan(tree.typeargs);
     }
 
     public void visitIdent(JCIdent tree) {
--- a/test/tools/javac/diags/examples.not-yet.txt	Wed Jun 15 17:13:06 2011 +0100
+++ b/test/tools/javac/diags/examples.not-yet.txt	Thu Jun 23 14:28:57 2011 +0100
@@ -164,5 +164,8 @@
 compiler.misc.infer.incompatible.ret.types.in.lambda                             #LAMBDA
 compiler.misc.infer.incompatible.arg.types.in.lambda                             #LAMBDA
 compiler.misc.infer.incompatible.thrown.types.in.lambda                          #LAMBDA
+compiler.misc.reference.not.found                                                #LAMBDA
+compiler.misc.reference.ambiguous                                                #LAMBDA
+compiler.misc.throws.typaram.not.allowed.here                                    #LAMBDA
 compiler.note.potential.lambda.found                                             #LAMBDA
 compiler.warn.redundant.extension.keyword                                        #LAMBDA
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaExpr07.java	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check access to effectively final local variable from doubly nested lambda
+ * @run main LambdaExpr07
+ */
+
+public class LambdaExpr07 {
+
+    interface Block<A, R> {
+        R apply(A x);
+    }
+
+    static int assertionCount = 0;
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    String S = "A";
+
+    void test() {
+        Block<String, Block<String, String>> o = #{s1 -> #{s2 -> S + s1 + s2 } };
+        assertTrue(o.apply("B").apply("C").equals("ABC"));
+    }
+
+    public static void main(String[] args) {
+        new LambdaExpr07().test();
+        assertTrue(assertionCount == 1);
+    }
+}
--- a/test/tools/javac/lambda/MethodReference02.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/test/tools/javac/lambda/MethodReference02.java	Thu Jun 23 14:28:57 2011 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,9 @@
 
 /*
  * @test
- * @summary check that ambiguous method references are flagged as errors
+ * @summary check that seemingly ambiguous method references are resolved properly
  * @author  Maurizio Cimadamore
- * @compile/fail/ref=MethodReference02.out -XDrawDiagnostics MethodReference02.java
+ * @compile MethodReference02.java
  */
 
 class MethodReference02 {
@@ -36,6 +36,6 @@
     void m(Integer i) {}
     void m(Double d) {}
 
-    SAM s1 = this#m; //ambiguous
-    SAM s2 = this#m(Integer); //ok
+    SAM s1 = this#m; //ok, use target type to disambiguate
+    SAM s2 = this#m(Integer); //ok, explicit
 }
--- a/test/tools/javac/lambda/MethodReference02.out	Wed Jun 15 17:13:06 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-MethodReference02.java:39:18: compiler.err.ref.ambiguous: m, kindname.method, m(java.lang.Integer), MethodReference02, kindname.method, m(java.lang.Double), MethodReference02
-1 error
--- a/test/tools/javac/lambda/MethodReference09.out	Wed Jun 15 17:13:06 2011 +0100
+++ b/test/tools/javac/lambda/MethodReference09.out	Thu Jun 23 14:28:57 2011 +0100
@@ -1,4 +1,3 @@
 MethodReference09.java:42:23: compiler.err.non-static.cant.be.ref: kindname.method, getThis()
-MethodReference09.java:42:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.arg.types.in.lambda)), compiler.misc.type.mref, MethodReference09.SAM
 MethodReference09.java:43:20: compiler.err.non-static.cant.be.ref: kindname.variable, this
-3 errors
+2 errors
--- a/test/tools/javac/lambda/MethodReference20.out	Wed Jun 15 17:13:06 2011 +0100
+++ b/test/tools/javac/lambda/MethodReference20.out	Thu Jun 23 14:28:57 2011 +0100
@@ -1,5 +1,5 @@
-MethodReference20.java:42:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: MethodReference20<java.lang.String>)), compiler.misc.type.mref, MethodReference20.SAM<java.lang.Integer>
-MethodReference20.java:43:53: compiler.err.cant.apply.symbol.1: kindname.constructor, MethodReference20, java.lang.String, java.lang.Integer, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists: java.lang.Integer, java.lang.String, null)
-MethodReference20.java:44:9: compiler.err.cant.apply.symbol.1: kindname.method, test, MethodReference20.SAM<java.lang.Integer>, compiler.misc.type.mref, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference20.SAM<java.lang.Integer>, (compiler.misc.infer.incompatible.ret.types.in.lambda: MethodReference20<java.lang.String>))
-MethodReference20.java:45:40: compiler.err.cant.apply.symbol.1: kindname.constructor, MethodReference20, java.lang.String, java.lang.Integer, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists: java.lang.Integer, java.lang.String, null)
+MethodReference20.java:42:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.reference.not.found: kindname.constructor, MethodReference20, java.lang.Integer)), compiler.misc.type.mref, MethodReference20.SAM<java.lang.Integer>
+MethodReference20.java:43:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.reference.not.found: kindname.constructor, MethodReference20, java.lang.Integer)), compiler.misc.type.mref, MethodReference20.SAM<java.lang.Integer>
+MethodReference20.java:44:9: compiler.err.cant.apply.symbol.1: kindname.method, test, MethodReference20.SAM<java.lang.Integer>, compiler.misc.type.mref, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference20.SAM<java.lang.Integer>, (compiler.misc.reference.not.found: kindname.constructor, MethodReference20, java.lang.Integer))
+MethodReference20.java:45:9: compiler.err.cant.apply.symbol.1: kindname.method, test, MethodReference20.SAM<java.lang.Integer>, compiler.misc.type.mref, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference20.SAM<java.lang.Integer>, (compiler.misc.reference.not.found: kindname.constructor, MethodReference20, java.lang.Integer))
 4 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference22.java	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that pair of bound/non-bound method references checked correctly
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=MethodReference22.out -XDrawDiagnostics MethodReference22.java
+ */
+
+class MethodReference22 {
+
+    void m1(String x) { }
+    void m1(MethodReference22 rec, String x) { }
+
+    static void m2(String x) { }
+    static void m2(MethodReference22 rec, String x) { }
+
+    static void m3(String x) { }
+    void m3(MethodReference22 rec, String x) { }
+
+    void m4(String x) { }
+    static void m4(MethodReference22 rec, String x) { }
+
+    interface SAM1 {
+        void m(String x);
+    }
+
+    interface SAM2 {
+        void m(MethodReference22 rec, String x);
+    }
+
+    static void call1(SAM1 s) {   }
+
+    static void call2(SAM2 s) {   }
+
+    static void call3(SAM1 s) {   }
+    static void call3(SAM2 s) {   }
+
+    static void test1() {
+        SAM1 s1 = MethodReference22#m1; //fail
+        call1(MethodReference22#m1); //fail
+        SAM1 s2 = MethodReference22#m2; //ok
+        call1(MethodReference22#m2); //ok
+        SAM1 s3 = MethodReference22#m3; //ok
+        call1(MethodReference22#m3); //ok
+        SAM1 s4 = MethodReference22#m4; //fail
+        call1(MethodReference22#m4); //fail
+    }
+
+    static void test2() {
+        SAM2 s1 = MethodReference22#m1; //ok
+        call2(MethodReference22#m1); //ok
+        SAM2 s2 = MethodReference22#m2; //ok
+        call2(MethodReference22#m2); //ok
+        SAM2 s3 = MethodReference22#m3; //fail
+        call2(MethodReference22#m3); //fail
+        SAM2 s4 = MethodReference22#m4; //fail
+        call2(MethodReference22#m4); //fail
+    }
+
+    static void test3() {
+        call3(MethodReference22#m1); //ok
+        call3(MethodReference22#m2); //ambiguous
+        call3(MethodReference22#m3); //ok
+        call3(MethodReference22#m4); //fail
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference22.out	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,11 @@
+MethodReference22.java:61:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.reference.not.found: kindname.method, m1, java.lang.String)), compiler.misc.type.mref, MethodReference22.SAM1
+MethodReference22.java:62:9: compiler.err.cant.apply.symbol.1: kindname.method, call1, MethodReference22.SAM1, compiler.misc.type.mref, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference22.SAM1, (compiler.misc.reference.not.found: kindname.method, m1, java.lang.String))
+MethodReference22.java:67:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.reference.not.found: kindname.method, m4, java.lang.String)), compiler.misc.type.mref, MethodReference22.SAM1
+MethodReference22.java:68:9: compiler.err.cant.apply.symbol.1: kindname.method, call1, MethodReference22.SAM1, compiler.misc.type.mref, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference22.SAM1, (compiler.misc.reference.not.found: kindname.method, m4, java.lang.String))
+MethodReference22.java:76:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.reference.not.found: kindname.method, m3, MethodReference22,java.lang.String)), compiler.misc.type.mref, MethodReference22.SAM2
+MethodReference22.java:77:9: compiler.err.cant.apply.symbol.1: kindname.method, call2, MethodReference22.SAM2, compiler.misc.type.mref, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference22.SAM2, (compiler.misc.reference.not.found: kindname.method, m3, MethodReference22,java.lang.String))
+MethodReference22.java:78:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.reference.ambiguous: kindname.method, m4, MethodReference22,java.lang.String, java.lang.String)), compiler.misc.type.mref, MethodReference22.SAM2
+MethodReference22.java:79:9: compiler.err.cant.apply.symbol.1: kindname.method, call2, MethodReference22.SAM2, compiler.misc.type.mref, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference22.SAM2, (compiler.misc.reference.ambiguous: kindname.method, m4, MethodReference22,java.lang.String, java.lang.String))
+MethodReference22.java:84:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
+MethodReference22.java:86:9: compiler.err.cant.apply.symbols: kindname.method, call3, compiler.misc.type.mref,{(compiler.misc.inapplicable.method: kindname.method, MethodReference22, call3(MethodReference22.SAM2), (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference22.SAM2, (compiler.misc.reference.ambiguous: kindname.method, m4, MethodReference22,java.lang.String, java.lang.String))),(compiler.misc.inapplicable.method: kindname.method, MethodReference22, call3(MethodReference22.SAM1), (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference22.SAM1, (compiler.misc.reference.not.found: kindname.method, m4, java.lang.String)))}
+10 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference23.java	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that pair of bound/non-bound constructor references is flagged as ambiguous
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=MethodReference23.out -XDrawDiagnostics MethodReference23.java
+ */
+
+class MethodReference23 {
+
+    class Inner1 {
+        Inner1(MethodReference23 outer) {};
+        Inner1() {};
+    }
+
+    static class Inner2 {
+        Inner2(MethodReference23 outer) {};
+        Inner2() {};
+    }
+
+    interface SAM11 {
+        Inner1 m(MethodReference23 rec);
+    }
+
+    interface SAM12 {
+        Inner1 m();
+    }
+
+    interface SAM21 {
+        Inner2 m(MethodReference23 rec);
+    }
+
+    interface SAM22 {
+        Inner2 m();
+    }
+
+    static void call11(SAM11 s) {   }
+
+    static void call12(SAM12 s) {   }
+
+    static void call21(SAM21 s) {   }
+
+    static void call22(SAM22 s) {   }
+
+    static void call3(SAM11 s) {   }
+    static void call3(SAM12 s) {   }
+    static void call3(SAM21 s) {   }
+    static void call3(SAM22 s) {   }
+
+    static void test11() {
+        SAM11 s = MethodReference23.Inner1#new; //fail
+        call11(MethodReference23.Inner1#new); //fail
+    }
+
+    static void test12() {
+        SAM12 s = MethodReference23.Inner1#new; //ok
+        call12(MethodReference23.Inner1#new); //ok
+    }
+
+    static void test21() {
+        SAM21 s = MethodReference23.Inner2#new; //ok
+        call21(MethodReference23.Inner2#new); //ok
+    }
+
+    static void test22() {
+        SAM22 s = MethodReference23.Inner2#new; //ok
+        call22(MethodReference23.Inner2#new); //ok
+    }
+
+    static void test3() {
+        call3(MethodReference23.Inner2#new); //ambiguous
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference23.out	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,4 @@
+MethodReference23.java:73:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.reference.ambiguous: kindname.constructor, Inner1, MethodReference23, )), compiler.misc.type.mref, MethodReference23.SAM11
+MethodReference23.java:74:9: compiler.err.cant.apply.symbol.1: kindname.method, call11, MethodReference23.SAM11, compiler.misc.type.mref, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.mref, MethodReference23.SAM11, (compiler.misc.reference.ambiguous: kindname.constructor, Inner1, MethodReference23, ))
+MethodReference23.java:93:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference23.SAM21), MethodReference23, kindname.method, call3(MethodReference23.SAM22), MethodReference23
+3 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference24.java	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that non-boxing method references conversion has the precedence
+ * @run main MethodReference24
+ */
+
+public class MethodReference24 {
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    static int assertionCount = 0;
+
+    static void m(int i) { assertTrue(true); }
+    static void m(Integer i) { assertTrue(false); }
+
+    interface SAM {
+        void m(int x);
+    }
+
+    static void call(SAM s) { s.m(42); }
+
+    public static void main(String[] args) {
+        SAM s = MethodReference24#m; //resolves to m(int)
+        s.m(42);
+        call(MethodReference24#m); //resolves to m(int)
+        assertTrue(assertionCount == 2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference25.java	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that non-boxing method references conversion has the precedence
+ * @run main MethodReference25
+ */
+
+public class MethodReference25 {
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    static int assertionCount = 0;
+
+    static void m(Integer i) { assertTrue(true); }
+
+    interface SAM1 {
+        void m(int x);
+    }
+
+    interface SAM2 {
+        void m(Integer x);
+    }
+
+    static void call(int i, SAM1 s) { s.m(i); assertTrue(false); }
+    static void call(int i, SAM2 s) { s.m(i);  }
+
+    public static void main(String[] args) {
+        call(1, MethodReference25#m); //resolves to call(int, SAM2)
+        assertTrue(assertionCount == 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference26.java	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check strict method conversion does not allow loose method reference conversion
+ * @compile/fail/ref=MethodReference26.out -XDrawDiagnostics MethodReference26.java
+ */
+
+class MethodReference26 {
+
+    static void m(Integer i) { }
+
+    interface SAM {
+        void m(int x);
+    }
+
+    static void call(int i, SAM s) {   }
+    static void call(Integer i, SAM s) {   }
+
+    static void test() {
+        call(1, MethodReference26#m); //ambiguous
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference26.out	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,2 @@
+MethodReference26.java:42:9: compiler.err.ref.ambiguous: call, kindname.method, call(int,MethodReference26.SAM), MethodReference26, kindname.method, call(java.lang.Integer,MethodReference26.SAM), MethodReference26
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference27.java	Thu Jun 23 14:28:57 2011 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that non-boxing method references conversion has the precedence
+ * @run main MethodReference27
+ */
+
+public class MethodReference27 {
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    static int assertionCount = 0;
+
+    interface SAM {
+        void m(int i1, int i2);
+    }
+
+    static void m1(int i1, int i2) { assertTrue(true); }
+    static void m1(Integer i1, int i2) { assertTrue(false); }
+    static void m1(int i1, Integer i2) { assertTrue(false); }
+    static void m1(Integer i1, Integer i2) { assertTrue(false); }
+    static void m1(Integer... is) { assertTrue(false); }
+    
+    //the following are commented because of problem with MH.invokeWithArguments
+    //static void m2(int... is) { assertTrue(true); }
+    //static void m2(double... ds) { assertTrue(false); }
+
+    public static void main(String[] args) {
+        SAM s1 = MethodReference27#m1;
+        s1.m(42,42);
+        //the following are commented because of problem with MH.invokeWithArguments
+        //SAM s2 = MethodReference27#m2;
+        //s2.m(42,42);
+        assertTrue(assertionCount == 1);
+    }
+}
--- a/test/tools/javac/transparency/Neg04.java	Wed Jun 15 17:13:06 2011 +0100
+++ b/test/tools/javac/transparency/Neg04.java	Thu Jun 23 14:28:57 2011 +0100
@@ -44,4 +44,13 @@
     <throws F> void m8(Callable<String> x) throws F;     // Legal
     <throws F> F m9();                                   // Illegal
     <throws F> Splittable<String, F> m10();       // Legal
+
+    static class MethodTest {
+        <E extends Exception>  void m1() {}
+        <throws E>  void m2() {}
+        <throws E1> void test() {
+            this.<E1>m1(); //Illegal
+            this.<E1>m2(); //Legal
+        }
+    }
 }
--- a/test/tools/javac/transparency/Neg04.out	Wed Jun 15 17:13:06 2011 +0100
+++ b/test/tools/javac/transparency/Neg04.out	Thu Jun 23 14:28:57 2011 +0100
@@ -2,4 +2,5 @@
 Neg04.java:39:5: compiler.err.throws.typaram.not.allowed.here
 Neg04.java:42:24: compiler.err.throws.typaram.not.allowed.here
 Neg04.java:45:16: compiler.err.throws.typaram.not.allowed.here
-4 errors
+Neg04.java:52:17: compiler.err.cant.apply.symbol.1: kindname.method, m1, compiler.misc.no.args, compiler.misc.no.args, kindname.class, Neg04.MethodTest, (compiler.misc.throws.typaram.not.allowed.here: E1)
+5 errors