changeset 1509:7873d37f5b37

8005244: Implement overload resolution as per latest spec EDR Summary: Add support for stuck expressions and provisional applicability Reviewed-by: jjg
author mcimadamore
date Mon, 21 Jan 2013 20:13:56 +0000
parents 1985e35e97b2
children c7c41a044e7c
files src/share/classes/com/sun/tools/javac/code/Source.java src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java src/share/classes/com/sun/tools/javac/comp/Infer.java src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java src/share/classes/com/sun/tools/javac/comp/Resolve.java src/share/classes/com/sun/tools/javac/comp/TransTypes.java 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/TreeInfo.java test/tools/javac/Diagnostics/6722234/T6722234d_1.out test/tools/javac/Diagnostics/6722234/T6722234d_2.out test/tools/javac/diags/examples.not-yet.txt test/tools/javac/diags/examples/CyclicInference.java test/tools/javac/diags/examples/InferredDoNotConformToLower.java test/tools/javac/diags/examples/NoUniqueMaximalInstance.java test/tools/javac/diags/examples/WhereIntersection.java test/tools/javac/generics/diamond/T6939780.out test/tools/javac/generics/diamond/neg/Neg05.out test/tools/javac/generics/diamond/neg/Neg10.java test/tools/javac/generics/diamond/neg/Neg10.out test/tools/javac/generics/inference/6315770/T6315770.out test/tools/javac/generics/inference/6638712/T6638712b.out test/tools/javac/generics/inference/6650759/T6650759m.out test/tools/javac/lambda/MethodReference25.java test/tools/javac/lambda/MethodReference25.out test/tools/javac/lambda/MethodReference26.java test/tools/javac/lambda/MethodReference26.out test/tools/javac/lambda/MethodReference43.java test/tools/javac/lambda/TargetType01.java test/tools/javac/lambda/TargetType01.out test/tools/javac/lambda/TargetType06.java test/tools/javac/lambda/TargetType06.out test/tools/javac/lambda/TargetType10.out test/tools/javac/lambda/TargetType11.java test/tools/javac/lambda/TargetType11.out test/tools/javac/lambda/TargetType14.out test/tools/javac/lambda/TargetType21.java test/tools/javac/lambda/TargetType21.out test/tools/javac/lambda/TargetType26.out test/tools/javac/lambda/TargetType27.out test/tools/javac/lambda/TargetType28.out test/tools/javac/lambda/TargetType39.out test/tools/javac/lambda/TargetType45.java test/tools/javac/lambda/TargetType45.out test/tools/javac/lambda/TargetType50.out test/tools/javac/lambda/TargetType51.java test/tools/javac/lambda/TargetType52.java test/tools/javac/lambda/TargetType52.out test/tools/javac/lambda/VoidCompatibility.java test/tools/javac/lambda/VoidCompatibility.out test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java test/tools/javac/lambda/methodReference/SamConversion.java test/tools/javac/lambda/methodReference/SamConversionComboTest.java test/tools/javac/lambda/typeInference/InferenceTest_neg5.out test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java
diffstat 58 files changed, 797 insertions(+), 460 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Jan 21 20:13:56 2013 +0000
@@ -218,6 +218,12 @@
     public boolean allowIntersectionTypesInCast() {
         return compareTo(JDK1_8) >= 0;
     }
+    public boolean allowEarlyReturnConstraints() {
+        return compareTo(JDK1_8) >= 0;
+    }
+    public boolean allowStructuralMostSpecific() {
+        return compareTo(JDK1_8) >= 0;
+    }
     public static SourceVersion toSourceVersion(Source source) {
         switch(source) {
         case JDK1_2:
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Jan 21 20:13:56 2013 +0000
@@ -354,8 +354,29 @@
                 return descSym;
             }
 
-            public Type getType(Type origin) {
-                return memberType(origin, descSym);
+            public Type getType(Type site) {
+                if (capture(site) != site) {
+                    Type formalInterface = site.tsym.type;
+                    ListBuffer<Type> typeargs = ListBuffer.lb();
+                    List<Type> actualTypeargs = site.getTypeArguments();
+                    //simply replace the wildcards with its bound
+                    for (Type t : formalInterface.getTypeArguments()) {
+                        if (actualTypeargs.head.hasTag(WILDCARD)) {
+                            WildcardType wt = (WildcardType)actualTypeargs.head;
+                            typeargs.append(wt.type);
+                        } else {
+                            typeargs.append(actualTypeargs.head);
+                        }
+                        actualTypeargs = actualTypeargs.tail;
+                    }
+                    site = subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList());
+                    if (!chk.checkValidGenericType(site)) {
+                        //if the inferred functional interface type is not well-formed,
+                        //or if it's not a subtype of the original target, issue an error
+                        throw failure(diags.fragment("no.suitable.functional.intf.inst", site));
+                    }
+                }
+                return memberType(site, descSym);
             }
         }
 
@@ -553,6 +574,15 @@
             return false;
         }
     }
+
+    public boolean isFunctionalInterface(Type site) {
+        try {
+            findDescriptorType(site);
+            return true;
+        } catch (FunctionDescriptorLookupError ex) {
+            return false;
+        }
+    }
     // </editor-fold>
 
    /**
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jan 21 20:13:56 2013 +0000
@@ -48,6 +48,7 @@
 import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
@@ -1376,18 +1377,19 @@
     public void visitConditional(JCConditional tree) {
         Type condtype = attribExpr(tree.cond, env, syms.booleanType);
 
-        boolean standaloneConditional = !allowPoly ||
+        tree.polyKind = (!allowPoly ||
                 pt().hasTag(NONE) && pt() != Type.recoveryType ||
-                isBooleanOrNumeric(env, tree);
-
-        if (!standaloneConditional && resultInfo.pt.hasTag(VOID)) {
+                isBooleanOrNumeric(env, tree)) ?
+                PolyKind.STANDALONE : PolyKind.POLY;
+
+        if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) {
             //cannot get here (i.e. it means we are returning from void method - which is already an error)
             resultInfo.checkContext.report(tree, diags.fragment("conditional.target.cant.be.void"));
             result = tree.type = types.createErrorType(resultInfo.pt);
             return;
         }
 
-        ResultInfo condInfo = standaloneConditional ?
+        ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
                 unknownExprInfo :
                 resultInfo.dup(new Check.NestedCheckContext(resultInfo.checkContext) {
                     //this will use enclosing check context to check compatibility of
@@ -1402,7 +1404,7 @@
         Type truetype = attribTree(tree.truepart, env, condInfo);
         Type falsetype = attribTree(tree.falsepart, env, condInfo);
 
-        Type owntype = standaloneConditional ? condType(tree, truetype, falsetype) : pt();
+        Type owntype = (tree.polyKind == PolyKind.STANDALONE) ? condType(tree, truetype, falsetype) : pt();
         if (condtype.constValue() != null &&
                 truetype.constValue() != null &&
                 falsetype.constValue() != null &&
@@ -1424,12 +1426,30 @@
                     JCConditional condTree = (JCConditional)tree;
                     return isBooleanOrNumeric(env, condTree.truepart) &&
                             isBooleanOrNumeric(env, condTree.falsepart);
+                case APPLY:
+                    JCMethodInvocation speculativeMethodTree =
+                            (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
+                    Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType();
+                    return types.unboxedTypeOrType(owntype).isPrimitive();
+                case NEWCLASS:
+                    JCExpression className =
+                            removeClassParams.translate(((JCNewClass)tree).clazz);
+                    JCExpression speculativeNewClassTree =
+                            (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
+                    return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
                 default:
                     Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
                     speculativeType = types.unboxedTypeOrType(speculativeType);
                     return speculativeType.isPrimitive();
             }
         }
+        //where
+            TreeTranslator removeClassParams = new TreeTranslator() {
+                @Override
+                public void visitTypeApply(JCTypeApply tree) {
+                    result = translate(tree.clazz);
+                }
+            };
 
         /** Compute the type of a conditional expression, after
          *  checking that it exists.  See JLS 15.25. Does not take into
@@ -2173,17 +2193,18 @@
         boolean needsRecovery =
                 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
         try {
+            Type target = pt();
             List<Type> explicitParamTypes = null;
-            if (TreeInfo.isExplicitLambda(that)) {
+            if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
                 //attribute lambda parameters
                 attribStats(that.params, localEnv);
                 explicitParamTypes = TreeInfo.types(that.params);
+                target = infer.instantiateFunctionalInterface(that, target, explicitParamTypes, resultInfo.checkContext);
             }
 
-            Type target;
             Type lambdaType;
             if (pt() != Type.recoveryType) {
-                target = infer.instantiateFunctionalInterface(that, checkIntersectionTarget(that, resultInfo), explicitParamTypes, resultInfo.checkContext);
+                target = checkIntersectionTarget(that, target, resultInfo.checkContext);
                 lambdaType = types.findDescriptorType(target);
                 chk.checkFunctionalInterface(that, target);
             } else {
@@ -2191,6 +2212,8 @@
                 lambdaType = fallbackDescriptorType(that);
             }
 
+            setFunctionalInfo(that, pt(), lambdaType, resultInfo.checkContext.inferenceContext());
+
             if (lambdaType.hasTag(FORALL)) {
                 //lambda expression target desc cannot be a generic method
                 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
@@ -2199,7 +2222,7 @@
                 return;
             }
 
-            if (!TreeInfo.isExplicitLambda(that)) {
+            if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) {
                 //add param type info in the AST
                 List<Type> actuals = lambdaType.getParameterTypes();
                 List<JCVariableDecl> params = that.params;
@@ -2282,8 +2305,7 @@
         }
     }
 
-    private Type checkIntersectionTarget(DiagnosticPosition pos, ResultInfo resultInfo) {
-        Type pt = resultInfo.pt;
+    private Type checkIntersectionTarget(DiagnosticPosition pos, Type pt, CheckContext checkContext) {
         if (pt != Type.recoveryType && pt.isCompound()) {
             IntersectionClassType ict = (IntersectionClassType)pt;
             List<Type> bounds = ict.allInterfaces ?
@@ -2292,7 +2314,7 @@
             types.findDescriptorType(bounds.head); //propagate exception outwards!
             for (Type bound : bounds.tail) {
                 if (!types.isMarkerInterface(bound)) {
-                    resultInfo.checkContext.report(pos, diags.fragment("secondary.bound.must.be.marker.intf", bound));
+                    checkContext.report(pos, diags.fragment("secondary.bound.must.be.marker.intf", bound));
                 }
             }
             //for now (translation doesn't support intersection types)
@@ -2355,9 +2377,9 @@
             @Override
             public boolean compatible(Type found, Type req, Warner warn) {
                 //return type must be compatible in both current context and assignment context
-                return types.isAssignable(found, inferenceContext().asFree(req, types), warn) &&
-                        super.compatible(found, req, warn);
+                return chk.basicHandler.compatible(found, inferenceContext().asFree(req, types), warn);
             }
+
             @Override
             public void report(DiagnosticPosition pos, JCDiagnostic details) {
                 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details));
@@ -2473,7 +2495,7 @@
             Type target;
             Type desc;
             if (pt() != Type.recoveryType) {
-                target = infer.instantiateFunctionalInterface(that, checkIntersectionTarget(that, resultInfo), null, resultInfo.checkContext);
+                target = checkIntersectionTarget(that, pt(), resultInfo.checkContext);
                 desc = types.findDescriptorType(target);
                 chk.checkFunctionalInterface(that, target);
             } else {
@@ -2481,12 +2503,11 @@
                 desc = fallbackDescriptorType(that);
             }
 
+            setFunctionalInfo(that, pt(), desc, resultInfo.checkContext.inferenceContext());
             List<Type> argtypes = desc.getParameterTypes();
 
-            boolean allowBoxing =
-                    resultInfo.checkContext.deferredAttrContext().phase.isBoxingRequired();
             Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = rs.resolveMemberReference(that.pos(), localEnv, that,
-                    that.expr.type, that.name, argtypes, typeargtypes, allowBoxing);
+                    that.expr.type, that.name, argtypes, typeargtypes, true);
 
             Symbol refSym = refResult.fst;
             Resolve.ReferenceLookupHelper lookupHelper = refResult.snd;
@@ -2635,6 +2656,34 @@
         }
     }
 
+    /**
+     * Set functional type info on the underlying AST. Note: as the target descriptor
+     * might contain inference variables, we might need to register an hook in the
+     * current inference context.
+     */
+    private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, final Type descriptorType, InferenceContext inferenceContext) {
+        if (inferenceContext.free(descriptorType)) {
+            inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() {
+                public void typesInferred(InferenceContext inferenceContext) {
+                    setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType, types), inferenceContext);
+                }
+            });
+        } else {
+            ListBuffer<TypeSymbol> targets = ListBuffer.lb();
+            if (pt.hasTag(CLASS)) {
+                if (pt.isCompound()) {
+                    for (Type t : ((IntersectionClassType)pt()).interfaces_field) {
+                        targets.append(t.tsym);
+                    }
+                } else {
+                    targets.append(pt.tsym);
+                }
+            }
+            fExpr.targets = targets.toList();
+            fExpr.descriptorType = descriptorType;
+        }
+    }
+
     public void visitParens(JCParens tree) {
         Type owntype = attribTree(tree.expr, env, resultInfo);
         result = check(tree, owntype, pkind(), resultInfo);
@@ -4078,11 +4127,28 @@
         }
 
         @Override
+        public void visitLambda(JCLambda that) {
+            super.visitLambda(that);
+            if (that.descriptorType == null) {
+                that.descriptorType = syms.unknownType;
+            }
+            if (that.targets == null) {
+                that.targets = List.nil();
+            }
+        }
+
+        @Override
         public void visitReference(JCMemberReference that) {
             super.visitReference(that);
             if (that.sym == null) {
                 that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol);
             }
+            if (that.descriptorType == null) {
+                that.descriptorType = syms.unknownType;
+            }
+            if (that.targets == null) {
+                that.targets = List.nil();
+            }
         }
     }
     // </editor-fold>
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Jan 21 20:13:56 2013 +0000
@@ -36,7 +36,6 @@
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
 
-import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.code.Lint;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Type.*;
@@ -44,6 +43,8 @@
 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
 import com.sun.tools.javac.comp.Infer.InferenceContext;
 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.ANNOTATION;
@@ -900,7 +901,6 @@
                    syms.methodClass);
         }
         if (useVarargs) {
-            JCTree tree = env.tree;
             Type argtype = owntype.getParameterTypes().last();
             if (!types.isReifiable(argtype) &&
                     (!allowSimplifiedVarargs ||
@@ -911,22 +911,13 @@
                                   argtype);
             }
             if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) {
-                Type elemtype = types.elemtype(argtype);
-                switch (tree.getTag()) {
-                    case APPLY:
-                        ((JCMethodInvocation) tree).varargsElement = elemtype;
-                        break;
-                    case NEWCLASS:
-                        ((JCNewClass) tree).varargsElement = elemtype;
-                        break;
-                    case REFERENCE:
-                        ((JCMemberReference) tree).varargsElement = elemtype;
-                        break;
-                    default:
-                        throw new AssertionError(""+tree);
-                }
+                TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
             }
          }
+         PolyKind pkind = (sym.type.hasTag(FORALL) &&
+                 sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ?
+                 PolyKind.POLY : PolyKind.STANDALONE;
+         TreeInfo.setPolyKind(env.tree, pkind);
          return owntype;
     }
     //where
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Mon Jan 21 20:13:56 2013 +0000
@@ -65,6 +65,7 @@
 
     final Attr attr;
     final Check chk;
+    final JCDiagnostic.Factory diags;
     final Enter enter;
     final Infer infer;
     final Log log;
@@ -83,14 +84,20 @@
         context.put(deferredAttrKey, this);
         attr = Attr.instance(context);
         chk = Check.instance(context);
+        diags = JCDiagnostic.Factory.instance(context);
         enter = Enter.instance(context);
         infer = Infer.instance(context);
         log = Log.instance(context);
         syms = Symtab.instance(context);
         make = TreeMaker.instance(context);
         types = Types.instance(context);
+        Names names = Names.instance(context);
+        stuckTree = make.Ident(names.empty).setType(Type.noType);
     }
 
+    /** shared tree for stuck expressions */
+    final JCTree stuckTree;
+
     /**
      * This type represents a deferred type. A deferred type starts off with
      * no information on the underlying expression type. Such info needs to be
@@ -356,12 +363,11 @@
                 //scan a defensive copy of the node list - this is because a deferred
                 //attribution round can add new nodes to the list
                 for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) {
-                    if (!deferredAttrNode.isStuck()) {
-                        deferredAttrNode.process();
+                    if (!deferredAttrNode.process()) {
+                        stuckVars.addAll(deferredAttrNode.stuckVars);
+                    } else {
                         deferredAttrNodes.remove(deferredAttrNode);
                         progress = true;
-                    } else {
-                        stuckVars.addAll(deferredAttrNode.stuckVars);
                     }
                 }
                 if (!progress) {
@@ -404,21 +410,88 @@
             }
 
             /**
-             * is this node stuck?
+             * Process a deferred attribution node.
+             * Invariant: a stuck node cannot be processed.
              */
-            boolean isStuck() {
-                return stuckVars.nonEmpty();
+            @SuppressWarnings("fallthrough")
+            boolean process() {
+                switch (mode) {
+                    case SPECULATIVE:
+                        dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
+                        return true;
+                    case CHECK:
+                        if (stuckVars.nonEmpty()) {
+                            return false;
+                        } else {
+                            dt.check(resultInfo, stuckVars, basicCompleter);
+                            return true;
+                        }
+                    default:
+                        throw new AssertionError("Bad mode");
+                }
             }
 
             /**
-             * Process a deferred attribution node.
-             * Invariant: a stuck node cannot be processed.
+             * Structural checker for stuck expressions
              */
-            void process() {
-                if (isStuck()) {
-                    throw new IllegalStateException("Cannot process a stuck deferred node");
+            class StructuralStuckChecker extends TreeScanner implements DeferredTypeCompleter {
+
+                ResultInfo resultInfo;
+
+                public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
+                    this.resultInfo = resultInfo;
+                    dt.tree.accept(this);
+                    dt.speculativeCache.put(msym, stuckTree, phase);
+                    return Type.noType;
                 }
-                dt.check(resultInfo);
+
+                @Override
+                public void visitLambda(JCLambda tree) {
+                    Check.CheckContext checkContext = resultInfo.checkContext;
+                    Type pt = resultInfo.pt;
+                    if (inferenceContext.inferencevars.contains(pt)) {
+                        //ok
+                        return;
+                    } else {
+                        //must be a functional descriptor
+                        try {
+                            Type desc = types.findDescriptorType(pt);
+                            if (desc.getParameterTypes().length() != tree.params.length()) {
+                                checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
+                            }
+                        } catch (Types.FunctionDescriptorLookupError ex) {
+                            checkContext.report(null, ex.getDiagnostic());
+                        }
+                    }
+                }
+
+                @Override
+                public void visitNewClass(JCNewClass tree) {
+                    //do nothing
+                }
+
+                @Override
+                public void visitApply(JCMethodInvocation tree) {
+                    //do nothing
+                }
+
+                @Override
+                public void visitReference(JCMemberReference tree) {
+                    Check.CheckContext checkContext = resultInfo.checkContext;
+                    Type pt = resultInfo.pt;
+                    if (inferenceContext.inferencevars.contains(pt)) {
+                        //ok
+                        return;
+                    } else {
+                        try {
+                            //TODO: we should speculative determine if there's a match
+                            //based on arity - if yes, method is applicable.
+                            types.findDescriptorType(pt);
+                        } catch (Types.FunctionDescriptorLookupError ex) {
+                            checkContext.report(null, ex.getDiagnostic());
+                        }
+                    }
+                }
             }
         }
     }
@@ -624,12 +697,12 @@
             if (inferenceContext.inferenceVars().contains(pt)) {
                 stuckVars.add(pt);
             }
-            if (!types.isFunctionalInterface(pt.tsym)) {
+            if (!types.isFunctionalInterface(pt)) {
                 return;
             }
             Type descType = types.findDescriptorType(pt);
             List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
-            if (!TreeInfo.isExplicitLambda(tree) &&
+            if (tree.paramKind == JCLambda.ParameterKind.IMPLICIT &&
                     freeArgVars.nonEmpty()) {
                 stuckVars.addAll(freeArgVars);
             }
@@ -643,7 +716,7 @@
                 stuckVars.add(pt);
                 return;
             }
-            if (!types.isFunctionalInterface(pt.tsym)) {
+            if (!types.isFunctionalInterface(pt)) {
                 return;
             }
 
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Jan 21 20:13:56 2013 +0000
@@ -66,6 +66,9 @@
     Log log;
     JCDiagnostic.Factory diags;
 
+    /** Should we inject return-type constraints earlier? */
+    boolean allowEarlyReturnConstraints;
+
     public static Infer instance(Context context) {
         Infer instance = context.get(inferKey);
         if (instance == null)
@@ -83,6 +86,7 @@
         chk = Check.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         inferenceException = new InferenceException(diags);
+        allowEarlyReturnConstraints = Source.instance(context).allowEarlyReturnConstraints();
     }
 
    /**
@@ -188,19 +192,6 @@
             MethodType mtype,
             Attr.ResultInfo resultInfo,
             Warner warn) throws InferenceException {
-        Type to = resultInfo.pt;
-        if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
-            to = mtype.getReturnType().isPrimitiveOrVoid() ?
-                    mtype.getReturnType() : syms.objectType;
-        }
-        Type qtype1 = inferenceContext.asFree(mtype.getReturnType(), types);
-        if (!types.isSubtype(qtype1,
-                qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to)) {
-            throw inferenceException
-                    .setMessage("infer.no.conforming.instance.exists",
-                    inferenceContext.restvars(), mtype.getReturnType(), to);
-        }
-
         while (true) {
             boolean stuck = true;
             for (Type t : inferenceContext.undetvars) {
@@ -283,6 +274,11 @@
         try {
             methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn);
 
+            if (resultInfo != null && allowEarlyReturnConstraints &&
+                    !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
+                generateReturnConstraints(mt, inferenceContext, resultInfo);
+            }
+
             deferredAttrContext.complete();
 
             // minimize as yet undetermined type variables
@@ -298,6 +294,9 @@
 
             if (!restvars.isEmpty()) {
                 if (resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
+                    if (!allowEarlyReturnConstraints) {
+                        generateReturnConstraints(mt, inferenceContext, resultInfo);
+                    }
                     instantiateUninferred(env.tree.pos(), inferenceContext, mt, resultInfo, warn);
                     checkWithinBounds(inferenceContext, warn);
                     mt = (MethodType)inferenceContext.asInstType(mt, types);
@@ -313,6 +312,23 @@
             inferenceContext.notifyChange(types);
         }
     }
+    //where
+        void generateReturnConstraints(Type mt, InferenceContext inferenceContext, Attr.ResultInfo resultInfo) {
+            if (resultInfo != null) {
+                Type to = resultInfo.pt;
+                if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
+                    to = mt.getReturnType().isPrimitiveOrVoid() ?
+                            mt.getReturnType() : syms.objectType;
+                }
+                Type qtype1 = inferenceContext.asFree(mt.getReturnType(), types);
+                if (!types.isSubtype(qtype1,
+                        qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to)) {
+                    throw inferenceException
+                            .setMessage("infer.no.conforming.instance.exists",
+                            inferenceContext.restvars(), mt.getReturnType(), to);
+                }
+            }
+        }
 
     /** check that type parameters are within their bounds.
      */
@@ -461,52 +477,40 @@
             Type formalInterface = funcInterface.tsym.type;
             InferenceContext funcInterfaceContext =
                     new InferenceContext(funcInterface.tsym.type.getTypeArguments(), this, false);
-            if (paramTypes != null) {
-                //get constraints from explicit params (this is done by
-                //checking that explicit param types are equal to the ones
-                //in the functional interface descriptors)
-                List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes();
-                if (descParameterTypes.size() != paramTypes.size()) {
-                    checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda"));
+            Assert.check(paramTypes != null);
+            //get constraints from explicit params (this is done by
+            //checking that explicit param types are equal to the ones
+            //in the functional interface descriptors)
+            List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes();
+            if (descParameterTypes.size() != paramTypes.size()) {
+                checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda"));
+                return types.createErrorType(funcInterface);
+            }
+            for (Type p : descParameterTypes) {
+                if (!types.isSameType(funcInterfaceContext.asFree(p, types), paramTypes.head)) {
+                    checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
                     return types.createErrorType(funcInterface);
                 }
-                for (Type p : descParameterTypes) {
-                    if (!types.isSameType(funcInterfaceContext.asFree(p, types), paramTypes.head)) {
-                        checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
-                        return types.createErrorType(funcInterface);
-                    }
-                    paramTypes = paramTypes.tail;
+                paramTypes = paramTypes.tail;
+            }
+            List<Type> actualTypeargs = funcInterface.getTypeArguments();
+            for (Type t : funcInterfaceContext.undetvars) {
+                UndetVar uv = (UndetVar)t;
+                minimizeInst(uv, types.noWarnings);
+                if (uv.inst == null &&
+                        Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) {
+                    maximizeInst(uv, types.noWarnings);
                 }
-                for (Type t : funcInterfaceContext.undetvars) {
-                    UndetVar uv = (UndetVar)t;
-                    minimizeInst(uv, types.noWarnings);
-                    if (uv.inst == null &&
-                            Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) {
-                        maximizeInst(uv, types.noWarnings);
-                    }
-                }
-
-                formalInterface = funcInterfaceContext.asInstType(formalInterface, types);
-            }
-            ListBuffer<Type> typeargs = ListBuffer.lb();
-            List<Type> actualTypeargs = funcInterface.getTypeArguments();
-            //for remaining uninferred type-vars in the functional interface type,
-            //simply replace the wildcards with its bound
-            for (Type t : formalInterface.getTypeArguments()) {
-                if (actualTypeargs.head.hasTag(WILDCARD)) {
-                    WildcardType wt = (WildcardType)actualTypeargs.head;
-                    typeargs.append(wt.type);
-                } else {
-                    typeargs.append(actualTypeargs.head);
+                if (uv.inst == null) {
+                    uv.inst = actualTypeargs.head;
                 }
                 actualTypeargs = actualTypeargs.tail;
             }
-            Type owntype = types.subst(formalInterface, funcInterfaceContext.inferenceVars(), typeargs.toList());
+            Type owntype = funcInterfaceContext.asInstType(formalInterface, types);
             if (!chk.checkValidGenericType(owntype)) {
                 //if the inferred functional interface type is not well-formed,
                 //or if it's not a subtype of the original target, issue an error
                 checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
-                return types.createErrorType(funcInterface);
             }
             return owntype;
         }
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Jan 21 20:13:56 2013 +0000
@@ -253,7 +253,7 @@
         int refKind = referenceKind(sym);
 
         //convert to an invokedynamic call
-        result = makeMetaFactoryIndyCall(tree, tree.targetType, refKind, sym, indy_args);
+        result = makeMetaFactoryIndyCall(tree, refKind, sym, indy_args);
     }
 
     private JCIdent makeThis(Type type, Symbol owner) {
@@ -314,7 +314,7 @@
 
 
         //build a sam instance using an indy call to the meta-factory
-        result = makeMetaFactoryIndyCall(tree, tree.targetType, localContext.referenceKind(), refSym, indy_args);
+        result = makeMetaFactoryIndyCall(tree, localContext.referenceKind(), refSym, indy_args);
     }
 
     /**
@@ -503,19 +503,6 @@
 
     // </editor-fold>
 
-    private MethodSymbol makeSamDescriptor(Type targetType) {
-        return (MethodSymbol)types.findDescriptorSymbol(targetType.tsym);
-    }
-
-    private Type makeFunctionalDescriptorType(Type targetType, MethodSymbol samDescriptor, boolean erased) {
-        Type descType = types.memberType(targetType, samDescriptor);
-        return erased ? types.erasure(descType) : descType;
-    }
-
-    private Type makeFunctionalDescriptorType(Type targetType, boolean erased) {
-        return makeFunctionalDescriptorType(targetType, makeSamDescriptor(targetType), erased);
-    }
-
     /**
      * Generate an adapter method "bridge" for a method reference which cannot
      * be used directly.
@@ -698,12 +685,12 @@
     /**
      * Generate an indy method call to the meta factory
      */
-    private JCExpression makeMetaFactoryIndyCall(JCExpression tree, Type targetType, int refKind, Symbol refSym, List<JCExpression> indy_args) {
+    private JCExpression makeMetaFactoryIndyCall(JCFunctionalExpression tree, int refKind, Symbol refSym, List<JCExpression> indy_args) {
         //determine the static bsm args
-        Type mtype = makeFunctionalDescriptorType(targetType, true);
+        Type mtype = types.erasure(tree.descriptorType);
+        MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
         List<Object> staticArgs = List.<Object>of(
-                new Pool.MethodHandle(ClassFile.REF_invokeInterface,
-                    types.findDescriptorSymbol(targetType.tsym), types),
+                new Pool.MethodHandle(ClassFile.REF_invokeInterface, types.findDescriptorSymbol(tree.type.tsym), types),
                 new Pool.MethodHandle(refKind, refSym, types),
                 new MethodType(mtype.getParameterTypes(),
                         mtype.getReturnType(),
@@ -1165,7 +1152,7 @@
          * This class is used to store important information regarding translation of
          * lambda expression/method references (see subclasses).
          */
-        private abstract class TranslationContext<T extends JCTree> {
+        private abstract class TranslationContext<T extends JCFunctionalExpression> {
 
             /** the underlying (untranslated) tree */
             T tree;
@@ -1329,7 +1316,7 @@
             }
 
             Type generatedLambdaSig() {
-                return types.erasure(types.findDescriptorType(tree.targetType));
+                return types.erasure(tree.descriptorType);
             }
         }
 
@@ -1385,7 +1372,7 @@
             }
 
             Type bridgedRefSig() {
-                return types.erasure(types.findDescriptorSymbol(tree.targetType.tsym).type);
+                return types.erasure(types.findDescriptorSymbol(tree.targets.head).type);
             }
         }
     }
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Jan 21 20:13:56 2013 +0000
@@ -41,6 +41,7 @@
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -92,6 +93,7 @@
     public final boolean varargsEnabled; // = source.allowVarargs();
     public final boolean allowMethodHandles;
     public final boolean allowDefaultMethods;
+    public final boolean allowStructuralMostSpecific;
     private final boolean debugResolve;
     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
 
@@ -127,6 +129,7 @@
         Target target = Target.instance(context);
         allowMethodHandles = target.hasMethodHandles();
         allowDefaultMethods = source.allowDefaultMethods();
+        allowStructuralMostSpecific = source.allowStructuralMostSpecific();
         polymorphicSignatureScope = new Scope(syms.noSymbol);
 
         inapplicableMethodException = new InapplicableMethodException(diags);
@@ -835,6 +838,213 @@
         }
     }
 
+    /**
+     * Most specific method applicability routine. Given a list of actual types A,
+     * a list of formal types F1, and a list of formal types F2, the routine determines
+     * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
+     * argument types A.
+     */
+    class MostSpecificCheck implements MethodCheck {
+
+        boolean strict;
+        List<Type> actuals;
+
+        MostSpecificCheck(boolean strict, List<Type> actuals) {
+            this.strict = strict;
+            this.actuals = actuals;
+        }
+
+        @Override
+        public void argumentsAcceptable(final Env<AttrContext> env,
+                                    DeferredAttrContext deferredAttrContext,
+                                    List<Type> formals1,
+                                    List<Type> formals2,
+                                    Warner warn) {
+            formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
+            while (formals2.nonEmpty()) {
+                ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
+                mresult.check(null, formals1.head);
+                formals1 = formals1.tail;
+                formals2 = formals2.tail;
+                actuals = actuals.isEmpty() ? actuals : actuals.tail;
+            }
+        }
+
+       /**
+        * Create a method check context to be used during the most specific applicability check
+        */
+        ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
+               Warner rsWarner, Type actual) {
+           return attr.new ResultInfo(Kinds.VAL, to,
+                   new MostSpecificCheckContext(strict, deferredAttrContext, rsWarner, actual));
+        }
+
+        /**
+         * Subclass of method check context class that implements most specific
+         * method conversion. If the actual type under analysis is a deferred type
+         * a full blown structural analysis is carried out.
+         */
+        class MostSpecificCheckContext extends MethodCheckContext {
+
+            Type actual;
+
+            public MostSpecificCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
+                super(strict, deferredAttrContext, rsWarner);
+                this.actual = actual;
+            }
+
+            public boolean compatible(Type found, Type req, Warner warn) {
+                if (!allowStructuralMostSpecific || actual == null) {
+                    return super.compatible(found, req, warn);
+                } else {
+                    switch (actual.getTag()) {
+                        case DEFERRED:
+                            DeferredType dt = (DeferredType) actual;
+                            DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
+                            return (e == null || e.speculativeTree == deferredAttr.stuckTree)
+                                    ? false : mostSpecific(found, req, e.speculativeTree, warn);
+                        default:
+                            return standaloneMostSpecific(found, req, actual, warn);
+                    }
+                }
+            }
+
+            private boolean mostSpecific(Type t, Type s, JCTree tree, Warner warn) {
+                MostSpecificChecker msc = new MostSpecificChecker(t, s, warn);
+                msc.scan(tree);
+                return msc.result;
+            }
+
+            boolean polyMostSpecific(Type t1, Type t2, Warner warn) {
+                return (!t1.isPrimitive() && t2.isPrimitive())
+                        ? true : super.compatible(t1, t2, warn);
+            }
+
+            boolean standaloneMostSpecific(Type t1, Type t2, Type exprType, Warner warn) {
+                return (exprType.isPrimitive() == t1.isPrimitive()
+                        && exprType.isPrimitive() != t2.isPrimitive())
+                        ? true : super.compatible(t1, t2, warn);
+            }
+
+            /**
+             * Structural checker for most specific.
+             */
+            class MostSpecificChecker extends DeferredAttr.PolyScanner {
+
+                final Type t;
+                final Type s;
+                final Warner warn;
+                boolean result;
+
+                MostSpecificChecker(Type t, Type s, Warner warn) {
+                    this.t = t;
+                    this.s = s;
+                    this.warn = warn;
+                    result = true;
+                }
+
+                @Override
+                void skip(JCTree tree) {
+                    result &= standaloneMostSpecific(t, s, tree.type, warn);
+                }
+
+                @Override
+                public void visitConditional(JCConditional tree) {
+                    if (tree.polyKind == PolyKind.STANDALONE) {
+                        result &= standaloneMostSpecific(t, s, tree.type, warn);
+                    } else {
+                        super.visitConditional(tree);
+                    }
+                }
+
+                @Override
+                public void visitApply(JCMethodInvocation tree) {
+                    result &= (tree.polyKind == PolyKind.STANDALONE)
+                            ? standaloneMostSpecific(t, s, tree.type, warn)
+                            : polyMostSpecific(t, s, warn);
+                }
+
+                @Override
+                public void visitNewClass(JCNewClass tree) {
+                    result &= (tree.polyKind == PolyKind.STANDALONE)
+                            ? standaloneMostSpecific(t, s, tree.type, warn)
+                            : polyMostSpecific(t, s, warn);
+                }
+
+                @Override
+                public void visitReference(JCMemberReference tree) {
+                    if (types.isFunctionalInterface(t.tsym) &&
+                            types.isFunctionalInterface(s.tsym) &&
+                            types.asSuper(t, s.tsym) == null &&
+                            types.asSuper(s, t.tsym) == null) {
+                        Type desc_t = types.findDescriptorType(t);
+                        Type desc_s = types.findDescriptorType(s);
+                        if (types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
+                            if (!desc_s.getReturnType().hasTag(VOID)) {
+                                //perform structural comparison
+                                Type ret_t = desc_t.getReturnType();
+                                Type ret_s = desc_s.getReturnType();
+                                result &= ((tree.refPolyKind == PolyKind.STANDALONE)
+                                        ? standaloneMostSpecific(ret_t, ret_s, tree.type, warn)
+                                        : polyMostSpecific(ret_t, ret_s, warn));
+                            } else {
+                                return;
+                            }
+                        } else {
+                            result &= false;
+                        }
+                    } else {
+                        result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+                    }
+                }
+
+                @Override
+                public void visitLambda(JCLambda tree) {
+                    if (types.isFunctionalInterface(t.tsym) &&
+                            types.isFunctionalInterface(s.tsym) &&
+                            types.asSuper(t, s.tsym) == null &&
+                            types.asSuper(s, t.tsym) == null) {
+                        Type desc_t = types.findDescriptorType(t);
+                        Type desc_s = types.findDescriptorType(s);
+                        if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT
+                                || types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
+                            if (!desc_s.getReturnType().hasTag(VOID)) {
+                                //perform structural comparison
+                                Type ret_t = desc_t.getReturnType();
+                                Type ret_s = desc_s.getReturnType();
+                                scanLambdaBody(tree, ret_t, ret_s);
+                            } else {
+                                return;
+                            }
+                        } else {
+                            result &= false;
+                        }
+                    } else {
+                        result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+                    }
+                }
+                //where
+
+                void scanLambdaBody(JCLambda lambda, final Type t, final Type s) {
+                    if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
+                        result &= MostSpecificCheckContext.this.mostSpecific(t, s, lambda.body, warn);
+                    } else {
+                        DeferredAttr.LambdaReturnScanner lambdaScanner =
+                                new DeferredAttr.LambdaReturnScanner() {
+                                    @Override
+                                    public void visitReturn(JCReturn tree) {
+                                        if (tree.expr != null) {
+                                            result &= MostSpecificCheckContext.this.mostSpecific(t, s, tree.expr, warn);
+                                        }
+                                    }
+                                };
+                        lambdaScanner.scan(lambda.body);
+                    }
+                }
+            }
+        }
+    }
+
     public static class InapplicableMethodException extends RuntimeException {
         private static final long serialVersionUID = 0;
 
@@ -1142,151 +1352,30 @@
     }
     //where
     private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
-        Symbol m12 = adjustVarargs(m1, m2, useVarargs);
-        Symbol m22 = adjustVarargs(m2, m1, useVarargs);
-        Type mtype1 = types.memberType(site, m12);
-        Type mtype2 = types.memberType(site, m22);
-
-        //check if invocation is more specific
-        if (invocationMoreSpecific(env, site, m22, mtype1.getParameterTypes(), allowBoxing, useVarargs)) {
-            return true;
+        noteWarner.clear();
+        int maxLength = Math.max(
+                            Math.max(m1.type.getParameterTypes().length(), actuals.length()),
+                            m2.type.getParameterTypes().length());
+        Type mst = instantiate(env, site, m2, null,
+                adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
+                allowBoxing, useVarargs, new MostSpecificCheck(!allowBoxing, actuals), noteWarner);
+        return mst != null &&
+                !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
+    }
+    private List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
+        if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
+            Type varargsElem = types.elemtype(args.last());
+            if (varargsElem == null) {
+                Assert.error("Bad varargs = " + args.last() + " " + msym);
+            }
+            List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
+            while (newArgs.length() < length) {
+                newArgs = newArgs.append(newArgs.last());
+            }
+            return newArgs;
+        } else {
+            return args;
         }
-
-        //perform structural check
-
-        List<Type> formals1 = mtype1.getParameterTypes();
-        Type lastFormal1 = formals1.last();
-        List<Type> formals2 = mtype2.getParameterTypes();
-        Type lastFormal2 = formals2.last();
-        ListBuffer<Type> newFormals = ListBuffer.lb();
-
-        boolean hasStructuralPoly = false;
-        for (Type actual : actuals) {
-            //perform formal argument adaptation in case actuals > formals (varargs)
-            Type f1 = formals1.isEmpty() ?
-                    lastFormal1 : formals1.head;
-            Type f2 = formals2.isEmpty() ?
-                    lastFormal2 : formals2.head;
-
-            //is this a structural actual argument?
-            boolean isStructuralPoly = actual.hasTag(DEFERRED) &&
-                    (((DeferredType)actual).tree.hasTag(LAMBDA) ||
-                    ((DeferredType)actual).tree.hasTag(REFERENCE));
-
-            Type newFormal = f1;
-
-            if (isStructuralPoly) {
-                //for structural arguments only - check that corresponding formals
-                //are related - if so replace formal with <null>
-                hasStructuralPoly = true;
-                DeferredType dt = (DeferredType)actual;
-                Type t1 = deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, m1, currentResolutionContext.step).apply(dt);
-                Type t2 = deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, m2, currentResolutionContext.step).apply(dt);
-                if (t1.isErroneous() || t2.isErroneous() || !isStructuralSubtype(t1, t2)) {
-                    //not structural subtypes - simply fail
-                    return false;
-                } else {
-                    newFormal = syms.botType;
-                }
-            }
-
-            newFormals.append(newFormal);
-            if (newFormals.length() > mtype2.getParameterTypes().length()) {
-                //expand m2's type so as to fit the new formal arity (varargs)
-                m22.type = types.createMethodTypeWithParameters(m22.type, m22.type.getParameterTypes().append(f2));
-            }
-
-            formals1 = formals1.isEmpty() ? formals1 : formals1.tail;
-            formals2 = formals2.isEmpty() ? formals2 : formals2.tail;
-        }
-
-        if (!hasStructuralPoly) {
-            //if no structural actual was found, we're done
-            return false;
-        }
-        //perform additional adaptation if actuals < formals (varargs)
-        for (Type t : formals1) {
-            newFormals.append(t);
-        }
-        //check if invocation (with tweaked args) is more specific
-        return invocationMoreSpecific(env, site, m22, newFormals.toList(), allowBoxing, useVarargs);
-    }
-    //where
-    private boolean invocationMoreSpecific(Env<AttrContext> env, Type site, Symbol m2, List<Type> argtypes1, boolean allowBoxing, boolean useVarargs) {
-        MethodResolutionContext prevContext = currentResolutionContext;
-        try {
-            currentResolutionContext = new MethodResolutionContext();
-            currentResolutionContext.step = allowBoxing ? BOX : BASIC;
-            noteWarner.clear();
-            Type mst = instantiate(env, site, m2, null,
-                    types.lowerBounds(argtypes1), null,
-                    allowBoxing, false, resolveMethodCheck, noteWarner);
-            return mst != null &&
-                    !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
-        } finally {
-            currentResolutionContext = prevContext;
-        }
-    }
-    //where
-    private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
-        List<Type> fromArgs = from.type.getParameterTypes();
-        List<Type> toArgs = to.type.getParameterTypes();
-        if (useVarargs &&
-                (from.flags() & VARARGS) != 0 &&
-                (to.flags() & VARARGS) != 0) {
-            Type varargsTypeFrom = fromArgs.last();
-            Type varargsTypeTo = toArgs.last();
-            ListBuffer<Type> args = ListBuffer.lb();
-            if (toArgs.length() < fromArgs.length()) {
-                //if we are checking a varargs method 'from' against another varargs
-                //method 'to' (where arity of 'to' < arity of 'from') then expand signature
-                //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to'
-                //until 'to' signature has the same arity as 'from')
-                while (fromArgs.head != varargsTypeFrom) {
-                    args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head);
-                    fromArgs = fromArgs.tail;
-                    toArgs = toArgs.head == varargsTypeTo ?
-                        toArgs :
-                        toArgs.tail;
-                }
-            } else {
-                //formal argument list is same as original list where last
-                //argument (array type) is removed
-                args.appendList(toArgs.reverse().tail.reverse());
-            }
-            //append varargs element type as last synthetic formal
-            args.append(types.elemtype(varargsTypeTo));
-            Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
-            return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner);
-        } else {
-            return to;
-        }
-    }
-    //where
-    boolean isStructuralSubtype(Type s, Type t) {
-
-        Type ret_s = types.findDescriptorType(s).getReturnType();
-        Type ret_t = types.findDescriptorType(t).getReturnType();
-
-        //covariant most specific check for function descriptor return type
-        if (!types.isSubtype(ret_s, ret_t)) {
-            return false;
-        }
-
-        List<Type> args_s = types.findDescriptorType(s).getParameterTypes();
-        List<Type> args_t = types.findDescriptorType(t).getParameterTypes();
-
-        //arity must be identical
-        if (args_s.length() != args_t.length()) {
-            return false;
-        }
-
-        //invariant most specific check for function descriptor parameter types
-        if (!types.isSameTypes(args_t, args_s)) {
-            return false;
-        }
-
-        return true;
     }
     //where
     Type mostSpecificReturnType(Type mt1, Type mt2) {
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Jan 21 20:13:56 2013 +0000
@@ -549,9 +549,6 @@
             currentMethod = null;
             tree.params = translate(tree.params);
             tree.body = translate(tree.body, null);
-            //save non-erased target
-            tree.targetType = tree.type;
-            Assert.check(!tree.targetType.isCompound(), "Intersection-type targets not supported yet!");
             tree.type = erasure(tree.type);
             result = tree;
         }
@@ -785,9 +782,6 @@
 
     public void visitReference(JCMemberReference tree) {
         tree.expr = translate(tree.expr, null);
-        //save non-erased target
-        tree.targetType = tree.type;
-        Assert.check(!tree.targetType.isCompound(), "Intersection-type targets not supported yet!");
         tree.type = erasure(tree.type);
         result = tree;
     }
--- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Jan 21 20:13:56 2013 +0000
@@ -607,6 +607,42 @@
     }
 
     /**
+     * Common supertype for all poly expression trees (lambda, method references,
+     * conditionals, method and constructor calls)
+     */
+    public static abstract class JCPolyExpression extends JCExpression {
+
+        /**
+         * A poly expression can only be truly 'poly' in certain contexts
+         */
+        public enum PolyKind {
+            /** poly expression to be treated as a standalone expression */
+            STANDALONE,
+            /** true poly expression */
+            POLY;
+        }
+
+        /** is this poly expression a 'true' poly expression? */
+        public PolyKind polyKind;
+    }
+
+    /**
+     * Common supertype for all functional expression trees (lambda and method references)
+     */
+    public static abstract class JCFunctionalExpression extends JCPolyExpression {
+
+        public JCFunctionalExpression() {
+            //a functional expression is always a 'true' poly
+            polyKind = PolyKind.POLY;
+        }
+
+        /** target descriptor inferred for this functional expression. */
+        public Type descriptorType;
+        /** list of target types inferred for this functional expression. */
+        public List<TypeSymbol> targets;
+    }
+
+    /**
      * A class definition.
      */
     public static class JCClassDecl extends JCStatement implements ClassTree {
@@ -1147,7 +1183,7 @@
     /**
      * A ( ) ? ( ) : ( ) conditional expression
      */
-    public static class JCConditional extends JCExpression implements ConditionalExpressionTree {
+    public static class JCConditional extends JCPolyExpression implements ConditionalExpressionTree {
         public JCExpression cond;
         public JCExpression truepart;
         public JCExpression falsepart;
@@ -1373,7 +1409,7 @@
     /**
      * A method invocation
      */
-    public static class JCMethodInvocation extends JCExpression implements MethodInvocationTree {
+    public static class JCMethodInvocation extends JCPolyExpression implements MethodInvocationTree {
         public List<JCExpression> typeargs;
         public JCExpression meth;
         public List<JCExpression> args;
@@ -1416,7 +1452,7 @@
     /**
      * A new(...) operation.
      */
-    public static class JCNewClass extends JCExpression implements NewClassTree {
+    public static class JCNewClass extends JCPolyExpression implements NewClassTree {
         public JCExpression encl;
         public List<JCExpression> typeargs;
         public JCExpression clazz;
@@ -1502,18 +1538,29 @@
     /**
      * A lambda expression.
      */
-    public static class JCLambda extends JCExpression implements LambdaExpressionTree {
+    public static class JCLambda extends JCFunctionalExpression implements LambdaExpressionTree {
+
+        public enum ParameterKind {
+            IMPLICIT,
+            EXPLICIT;
+        }
 
         public List<JCVariableDecl> params;
         public JCTree body;
-        public Type targetType;
         public boolean canCompleteNormally = true;
         public List<Type> inferredThrownTypes;
+        public ParameterKind paramKind;
 
         public JCLambda(List<JCVariableDecl> params,
                         JCTree body) {
             this.params = params;
             this.body = body;
+            if (params.isEmpty() ||
+                params.head.vartype != null) {
+                paramKind = ParameterKind.EXPLICIT;
+            } else {
+                paramKind = ParameterKind.IMPLICIT;
+            }
         }
         @Override
         public Tag getTag() {
@@ -1812,15 +1859,15 @@
     /**
      * Selects a member expression.
      */
-    public static class JCMemberReference extends JCExpression implements MemberReferenceTree {
+    public static class JCMemberReference extends JCFunctionalExpression implements MemberReferenceTree {
         public ReferenceMode mode;
         public ReferenceKind kind;
         public Name name;
         public JCExpression expr;
         public List<JCExpression> typeargs;
-        public Type targetType;
         public Symbol sym;
         public Type varargsElement;
+        public PolyKind refPolyKind;
 
         /**
          * Javac-dependent classification for member references, based
--- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Mon Jan 21 20:13:56 2013 +0000
@@ -946,7 +946,7 @@
     public void visitLambda(JCLambda tree) {
         try {
             print("(");
-            if (TreeInfo.isExplicitLambda(tree)) {
+            if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT) {
                 printExprs(tree.params);
             } else {
                 String sep = "";
--- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Mon Jan 21 20:13:56 2013 +0000
@@ -32,6 +32,7 @@
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.Env;
 import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import static com.sun.tools.javac.code.Flags.*;
@@ -264,9 +265,38 @@
         }
     }
 
-    public static boolean isExplicitLambda(JCLambda lambda) {
-        return lambda.params.isEmpty() ||
-                lambda.params.head.vartype != null;
+    /** set 'polyKind' on given tree */
+    public static void setPolyKind(JCTree tree, PolyKind pkind) {
+        switch (tree.getTag()) {
+            case APPLY:
+                ((JCMethodInvocation)tree).polyKind = pkind;
+                break;
+            case NEWCLASS:
+                ((JCNewClass)tree).polyKind = pkind;
+                break;
+            case REFERENCE:
+                ((JCMemberReference)tree).refPolyKind = pkind;
+                break;
+            default:
+                throw new AssertionError("Unexpected tree: " + tree);
+        }
+    }
+
+    /** set 'varargsElement' on given tree */
+    public static void setVarargsElement(JCTree tree, Type varargsElement) {
+        switch (tree.getTag()) {
+            case APPLY:
+                ((JCMethodInvocation)tree).varargsElement = varargsElement;
+                break;
+            case NEWCLASS:
+                ((JCNewClass)tree).varargsElement = varargsElement;
+                break;
+            case REFERENCE:
+                ((JCMemberReference)tree).varargsElement = varargsElement;
+                break;
+            default:
+                throw new AssertionError("Unexpected tree: " + tree);
+        }
     }
 
     /** Return true if the tree corresponds to an expression statement */
--- a/test/tools/javac/Diagnostics/6722234/T6722234d_1.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/Diagnostics/6722234/T6722234d_1.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,3 +1,3 @@
-T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.intersection.type: 1, T6722234d.A)
+T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.intersection.type: 1, T6722234d.A,java.lang.Object)
 - compiler.misc.where.description.intersection: compiler.misc.intersection.type: 1,{(compiler.misc.where.intersection: compiler.misc.intersection.type: 1, java.lang.Object,T6722234d.I1,T6722234d.I2)}
 1 error
--- a/test/tools/javac/Diagnostics/6722234/T6722234d_2.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/Diagnostics/6722234/T6722234d_2.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,3 +1,3 @@
-T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.intersection.type: 1, T6722234d.A)
+T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.intersection.type: 1, T6722234d.A,Object)
 - compiler.misc.where.description.intersection: compiler.misc.intersection.type: 1,{(compiler.misc.where.intersection: compiler.misc.intersection.type: 1, Object,I1,I2)}
 1 error
--- a/test/tools/javac/diags/examples.not-yet.txt	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/diags/examples.not-yet.txt	Mon Jan 21 20:13:56 2013 +0000
@@ -59,6 +59,7 @@
 compiler.misc.fatal.err.cant.close	                # JavaCompiler
 compiler.misc.file.does.not.contain.package
 compiler.misc.illegal.start.of.class.file
+compiler.misc.inferred.do.not.conform.to.lower.bounds   # cannot happen?
 compiler.misc.kindname.annotation
 compiler.misc.kindname.enum
 compiler.misc.kindname.package
@@ -68,6 +69,7 @@
 compiler.misc.kindname.value
 compiler.misc.incompatible.eq.lower.bounds              # cannot happen?
 compiler.misc.no.unique.minimal.instance.exists
+compiler.misc.no.unique.maximal.instance.exists         # cannot happen?
 compiler.misc.resume.abort                              # prompt for a response
 compiler.misc.source.unavailable                        # DiagnosticSource
 compiler.misc.token.bad-symbol
--- a/test/tools/javac/diags/examples/CyclicInference.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/diags/examples/CyclicInference.java	Mon Jan 21 20:13:56 2013 +0000
@@ -21,7 +21,7 @@
  * questions.
  */
 
-// key: compiler.err.cant.apply.symbol
+// key: compiler.err.prob.found.req
 // key: compiler.misc.cyclic.inference
 
 class CyclicInference {
--- a/test/tools/javac/diags/examples/InferredDoNotConformToLower.java	Mon Jan 21 11:16:28 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-// key: compiler.err.prob.found.req
-// key: compiler.misc.inferred.do.not.conform.to.lower.bounds
-
-import java.util.*;
-
-class InferredDoNotConformToLower {
-    <X extends Number> List<X> m() { return null; }
-    { List<? super String> lss = this.m(); }
-}
--- a/test/tools/javac/diags/examples/NoUniqueMaximalInstance.java	Mon Jan 21 11:16:28 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-// key: compiler.err.prob.found.req
-// key: compiler.misc.no.unique.maximal.instance.exists
-
-class NoUniqueMaximalInstance {
-    <Z extends Integer> Z m() { return null; }
-
-    { String s = m(); }
-}
--- a/test/tools/javac/diags/examples/WhereIntersection.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/diags/examples/WhereIntersection.java	Mon Jan 21 20:13:56 2013 +0000
@@ -25,7 +25,7 @@
 // key: compiler.misc.where.description.intersection
 // key: compiler.misc.intersection.type
 // key: compiler.err.prob.found.req
-// key: compiler.misc.inconvertible.types
+// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
 // options: -XDdiags=where
 // run: simple
 
--- a/test/tools/javac/generics/diamond/T6939780.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/generics/diamond/T6939780.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,3 +1,4 @@
+T6939780.java:18:33: compiler.warn.diamond.redundant.args: Foo<java.lang.Number>, Foo<java.lang.Number>
 T6939780.java:19:28: compiler.warn.diamond.redundant.args: Foo<java.lang.Number>, Foo<java.lang.Number>
 T6939780.java:20:28: compiler.warn.diamond.redundant.args.1: Foo<java.lang.Integer>, Foo<java.lang.Number>
-2 warnings
+3 warnings
--- a/test/tools/javac/generics/diamond/neg/Neg05.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/generics/diamond/neg/Neg05.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,25 +1,25 @@
 Neg05.java:19:48: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:19:35: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<java.lang.String>)
 Neg05.java:20:58: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:20:45: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? extends java.lang.String>)
 Neg05.java:21:43: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:21:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<?>)
 Neg05.java:22:56: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:22:43: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? super java.lang.String>)
 Neg05.java:24:48: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:24:35: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<java.lang.String>)
 Neg05.java:25:58: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:25:45: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? extends java.lang.String>)
 Neg05.java:26:43: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:26:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<?>)
 Neg05.java:27:56: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:27:43: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? super java.lang.String>)
 Neg05.java:31:37: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:31:44: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V, Neg05.Foo<V>, Neg05<?>.Foo<java.lang.String>))
 Neg05.java:32:47: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:32:54: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V, Neg05.Foo<V>, Neg05<?>.Foo<? extends java.lang.String>))
 Neg05.java:33:32: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:33:39: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V, Neg05.Foo<V>, Neg05<?>.Foo<?>))
 Neg05.java:34:45: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:34:52: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V, Neg05.Foo<V>, Neg05<?>.Foo<? super java.lang.String>))
 Neg05.java:36:37: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:36:44: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<java.lang.String>))
 Neg05.java:37:47: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:37:54: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<? extends java.lang.String>))
 Neg05.java:38:32: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:38:39: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<?>))
 Neg05.java:39:45: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:39:52: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<? super java.lang.String>))
 24 errors
--- a/test/tools/javac/generics/diamond/neg/Neg10.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/generics/diamond/neg/Neg10.java	Mon Jan 21 20:13:56 2013 +0000
@@ -4,7 +4,8 @@
  *
  * @summary  Check that 'complex' diamond can infer type that is too specific
  * @author mcimadamore
- * @compile/fail/ref=Neg10.out Neg10.java -XDrawDiagnostics
+ * @compile/fail/ref=Neg10.out -source 7 -Xlint:-options Neg10.java -XDrawDiagnostics
+ * @compile Neg10.java -XDrawDiagnostics
  *
  */
 
--- a/test/tools/javac/generics/diamond/neg/Neg10.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/generics/diamond/neg/Neg10.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,2 +1,2 @@
-Neg10.java:16:22: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg10.Foo<java.lang.Integer>, Neg10.Foo<java.lang.Number>)
+Neg10.java:17:22: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg10.Foo<java.lang.Integer>, Neg10.Foo<java.lang.Number>)
 1 error
--- a/test/tools/javac/generics/inference/6315770/T6315770.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/generics/inference/6315770/T6315770.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,3 +1,3 @@
-T6315770.java:16:42: compiler.err.prob.found.req: (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
-T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer&java.lang.Runnable, java.lang.String)
+T6315770.java:16:42: compiler.err.prob.found.req: (compiler.misc.incompatible.upper.bounds: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
+T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Integer,java.lang.Runnable)
 2 errors
--- a/test/tools/javac/generics/inference/6638712/T6638712b.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/generics/inference/6638712/T6638712b.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,2 +1,2 @@
-T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String,java.lang.Object)
+T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: T, java.lang.Integer, java.lang.String,java.lang.Object)
 1 error
--- a/test/tools/javac/generics/inference/6650759/T6650759m.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/generics/inference/6650759/T6650759m.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,2 +1,2 @@
-T6650759m.java:43:36: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer, java.lang.String)
+T6650759m.java:43:36: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Integer,java.lang.Object)
 1 error
--- a/test/tools/javac/lambda/MethodReference25.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/MethodReference25.java	Mon Jan 21 20:13:56 2013 +0000
@@ -25,21 +25,13 @@
  * @test
  * @bug 8003280
  * @summary Add lambda tests
- *  check that non-boxing method references conversion has the precedence
- * @run main MethodReference25
+ *  check that non-boxing method references is not preferred over boxing one
+ * @compile/fail/ref=MethodReference25.out -XDrawDiagnostics MethodReference25.java
  */
 
-public class MethodReference25 {
+class MethodReference25 {
 
-    static void assertTrue(boolean cond) {
-        assertionCount++;
-        if (!cond)
-            throw new AssertionError();
-    }
-
-    static int assertionCount = 0;
-
-    static void m(Integer i) { assertTrue(true); }
+    static void m(Integer i) { }
 
     interface SAM1 {
         void m(int x);
@@ -49,11 +41,10 @@
         void m(Integer x);
     }
 
-    static void call(int i, SAM1 s) { s.m(i); assertTrue(false); }
+    static void call(int i, SAM1 s) { s.m(i);  }
     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);
+        call(1, MethodReference25::m); //ambiguous
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference25.out	Mon Jan 21 20:13:56 2013 +0000
@@ -0,0 +1,2 @@
+MethodReference25.java:48:9: compiler.err.ref.ambiguous: call, kindname.method, call(int,MethodReference25.SAM1), MethodReference25, kindname.method, call(int,MethodReference25.SAM2), MethodReference25
+1 error
--- a/test/tools/javac/lambda/MethodReference26.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/MethodReference26.java	Mon Jan 21 20:13:56 2013 +0000
@@ -1,9 +1,30 @@
 /*
- * @test /nodynamiccopyright/
- * @bug 8003280
- * @summary Add lambda tests
- *  check strict method conversion does not allow loose method reference conversion
- * @compile/fail/ref=MethodReference26.out -XDrawDiagnostics MethodReference26.java
+ * 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 allows loose method reference conversion
+ * @compile MethodReference26.java
  */
 
 class MethodReference26 {
@@ -18,6 +39,6 @@
     static void call(Integer i, SAM s) {   }
 
     static void test() {
-        call(1, MethodReference26::m); //ambiguous
+        call(1, MethodReference26::m); //ok
     }
 }
--- a/test/tools/javac/lambda/MethodReference26.out	Mon Jan 21 11:16:28 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-MethodReference26.java:21:9: compiler.err.ref.ambiguous: call, kindname.method, call(int,MethodReference26.SAM), MethodReference26, kindname.method, call(java.lang.Integer,MethodReference26.SAM), MethodReference26
-1 error
--- a/test/tools/javac/lambda/MethodReference43.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/MethodReference43.java	Mon Jan 21 20:13:56 2013 +0000
@@ -60,9 +60,9 @@
 
 
     static void m(SAM1 s) { assertTrue(false); }
-    static void m(SAM2 s) { assertTrue(true); }
+    static void m(SAM2 s) { assertTrue(false); }
     static void m(SAM3 s) { assertTrue(false); }
-    static void m(SAM4 s) { assertTrue(false); }
+    static void m(SAM4 s) { assertTrue(true); }
 
     public static void main(String[] args) {
         m(Foo::new);
--- a/test/tools/javac/lambda/TargetType01.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType01.java	Mon Jan 21 20:13:56 2013 +0000
@@ -27,7 +27,7 @@
  * @summary Add lambda tests
  *  check nested case of overload resolution and lambda parameter inference
  * @author  Maurizio Cimadamore
- * @compile TargetType01.java
+ * @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java
  */
 
 class TargetType01 {
@@ -43,7 +43,6 @@
     static String M(F_S_S f){ return null; }
 
     static {
-        //ambiguity here - the compiler does not try all the combinations!
-        M(x1 -> { return M( x2 -> { return x1 + x2; });});
+        M(x1 -> { return M( x2 -> { return x1 + x2; });}); //ambiguous
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType01.out	Mon Jan 21 20:13:56 2013 +0000
@@ -0,0 +1,3 @@
+TargetType01.java:46:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
+TargetType01.java:46:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
+2 errors
--- a/test/tools/javac/lambda/TargetType06.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType06.java	Mon Jan 21 20:13:56 2013 +0000
@@ -4,7 +4,7 @@
  * @summary Add lambda tests
  *  check complex case of target typing
  * @author  Maurizio Cimadamore
- * @compile/fail/ref=TargetType06.out -XDrawDiagnostics TargetType06.java
+ * @compile TargetType06.java
  */
 
 import java.util.List;
--- a/test/tools/javac/lambda/TargetType06.out	Mon Jan 21 11:16:28 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-TargetType06.java:25:23: compiler.err.cant.apply.symbol: kindname.method, map, TargetType06.Function<B,B>, @510, kindname.class, TargetType06, (compiler.misc.cyclic.inference: B)
-1 error
--- a/test/tools/javac/lambda/TargetType10.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType10.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,2 +1,2 @@
-TargetType10.java:17:11: compiler.err.cant.apply.symbol: kindname.method, compose, TargetType10.Function<B,C>,TargetType10.Function<A,? extends B>, @500,@515, kindname.class, TargetType10.Test, (compiler.misc.cyclic.inference: B,A)
+TargetType10.java:17:18: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: B,A)
 1 error
--- a/test/tools/javac/lambda/TargetType11.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType11.java	Mon Jan 21 20:13:56 2013 +0000
@@ -4,7 +4,7 @@
  * @summary Add lambda tests
  *  check that wildcards in the target method of a lambda conversion is handled correctly
  * @author  Maurizio Cimadamore
- * @compile/fail/ref=TargetType11.out -Xlint:unchecked -XDrawDiagnostics TargetType11.java
+ * @compile TargetType11.java
  */
 
 class TargetType11 {
--- a/test/tools/javac/lambda/TargetType11.out	Mon Jan 21 11:16:28 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-TargetType11.java:16:61: compiler.warn.unchecked.varargs.non.reifiable.type: TargetType11.Predicate<? super T>
-TargetType11.java:20:32: compiler.err.cant.apply.symbol: kindname.method, and, TargetType11.Predicate<? super T>[], @706,@718, kindname.class, TargetType11.Test, (compiler.misc.cyclic.inference: T)
-1 error
-1 warning
--- a/test/tools/javac/lambda/TargetType14.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType14.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,2 +1,2 @@
-TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TargetType14.SAM<java.lang.String>, TargetType14.SAM<java.lang.Integer>)
+TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer, java.lang.String)
 1 error
--- a/test/tools/javac/lambda/TargetType21.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType21.java	Mon Jan 21 20:13:56 2013 +0000
@@ -26,8 +26,8 @@
 
     void test() {
         call(x -> { throw new Exception(); }); //ambiguous
-        call(x -> { System.out.println(""); }); //ok - resolves to call(SAM2)
-        call(x -> { return (Object) null; }); //error - call(SAM3) is not applicable because of cyclic inference
-        call(x -> { return null; }); ////ok - resolves to call(SAM1)
+        call(x -> { System.out.println(""); }); //ambiguous
+        call(x -> { return (Object) null; }); //cyclic inference
+        call(x -> { return null; }); //ambiguous
     }
 }
--- a/test/tools/javac/lambda/TargetType21.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType21.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,3 +1,6 @@
-TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, call(TargetType21.SAM2), TargetType21
-TargetType21.java:30:9: compiler.err.cant.apply.symbols: kindname.method, call, @737,{(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, <R,A>call(TargetType21.SAM3<R,A>), (compiler.misc.cyclic.inference: A))}
-2 errors
+TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:28:14: compiler.err.incompatible.thrown.types.in.lambda: java.lang.Exception
+TargetType21.java:29:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:30:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: A)
+TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+5 errors
--- a/test/tools/javac/lambda/TargetType26.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType26.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,2 +1,2 @@
-TargetType26.java:16:7: compiler.err.cant.apply.symbol: kindname.method, call, Z, @340, kindname.class, TargetType26, (compiler.misc.cyclic.inference: Z)
+TargetType26.java:16:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
 1 error
--- a/test/tools/javac/lambda/TargetType27.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType27.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,2 +1,2 @@
-TargetType27.java:18:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType27.F<A,R>, @490, kindname.class, TargetType27, (compiler.misc.cyclic.inference: R)
+TargetType27.java:18:10: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: R)
 1 error
--- a/test/tools/javac/lambda/TargetType28.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType28.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,3 +1,3 @@
-TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TargetType28.SuperFoo<java.lang.Number>, TargetType28.SuperFoo<java.lang.String>)
-TargetType28.java:21:33: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TargetType28.SuperFoo<java.lang.Number>, TargetType28.SuperFoo<java.lang.Integer>)
+TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.String)
+TargetType28.java:21:33: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.Integer)
 2 errors
--- a/test/tools/javac/lambda/TargetType39.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType39.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,3 +1,3 @@
-TargetType39.java:19:9: compiler.err.cant.apply.symbol: kindname.method, call, TargetType39.SAM<U,V>, @442, kindname.class, TargetType39, (compiler.misc.cyclic.inference: U)
-TargetType39.java:20:9: compiler.err.cant.apply.symbol: kindname.method, call, TargetType39.SAM<U,V>, @479, kindname.class, TargetType39, (compiler.misc.cyclic.inference: V)
+TargetType39.java:19:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: U)
+TargetType39.java:20:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: V)
 2 errors
--- a/test/tools/javac/lambda/TargetType45.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType45.java	Mon Jan 21 20:13:56 2013 +0000
@@ -3,7 +3,7 @@
  * @bug 8003280
  * @summary Add lambda tests
  *  compiler crashes during flow analysis as it fails to report diagnostics during attribution
- * @compile/fail/ref=TargetType45.out -XDrawDiagnostics TargetType45.java
+ * @compile TargetType45.java
  */
 class TargetType45 {
 
--- a/test/tools/javac/lambda/TargetType45.out	Mon Jan 21 11:16:28 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-TargetType45.java:27:28: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U,V, (compiler.misc.inconvertible.types: TargetType45.Mapper<java.lang.String,java.lang.Integer>, TargetType45.Mapper<? super java.lang.Object,? extends java.lang.Integer>))
-1 error
--- a/test/tools/javac/lambda/TargetType50.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/TargetType50.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,3 +1,3 @@
-TargetType50.java:25:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object)
-TargetType50.java:26:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object)
+TargetType50.java:25:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>)
+TargetType50.java:26:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>)
 2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType51.java	Mon Jan 21 20:13:56 2013 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, 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 smoke test for combinator-like stuck analysis
+ * @author  Maurizio Cimadamore
+ * @compile TargetType51.java
+ */
+
+import java.util.Comparator;
+
+class TargetType51 {
+
+    interface SimpleMapper<T, U> {
+       T map(U t);
+    }
+
+    interface SimpleList<X> {
+        SimpleList<X> sort(Comparator<? super X> c);
+    }
+
+    static class Person {
+        String getName() { return ""; }
+    }
+
+    <T, U extends Comparable<? super U>> Comparator<T> comparing(SimpleMapper<U, T> mapper) {  return null; }
+
+    static class F<U extends Comparable<? super U>, T> {
+        F(SimpleMapper<U, T> f) { }
+    }
+
+    void testAssignmentContext(SimpleList<Person> list, boolean cond) {
+        SimpleList<Person> p1 = list.sort(comparing(Person::getName));
+        SimpleList<Person> p2 = list.sort(comparing(x->x.getName()));
+        SimpleList<Person> p3 = list.sort(cond ? comparing(Person::getName) : comparing(x->x.getName()));
+        SimpleList<Person> p4 = list.sort((cond ? comparing(Person::getName) : comparing(x->x.getName())));
+    }
+
+    void testMethodContext(SimpleList<Person> list, boolean cond) {
+        testMethodContext(list.sort(comparing(Person::getName)), true);
+        testMethodContext(list.sort(comparing(x->x.getName())), true);
+        testMethodContext(list.sort(cond ? comparing(Person::getName) : comparing(x->x.getName())), true);
+        testMethodContext(list.sort((cond ? comparing(Person::getName) : comparing(x->x.getName()))), true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType52.java	Mon Jan 21 20:13:56 2013 +0000
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary uncatched sam conversion failure exception lead to javac crash
+ * @compile/fail/ref=TargetType52.out -XDrawDiagnostics TargetType52.java
+ */
+class TargetType52 {
+
+    interface FI<T extends CharSequence, V extends java.util.AbstractList<T>> {
+        T m(V p);
+    }
+
+    void m(FI<? extends CharSequence, ? extends java.util.ArrayList<? extends CharSequence>> fip) { }
+
+    void test() {
+        m(p -> p.get(0));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType52.out	Mon Jan 21 20:13:56 2013 +0000
@@ -0,0 +1,2 @@
+TargetType52.java:15:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType52.FI<? extends java.lang.CharSequence,? extends java.util.ArrayList<? extends java.lang.CharSequence>>, @449, kindname.class, TargetType52, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: TargetType52.FI<java.lang.CharSequence,java.util.ArrayList<? extends java.lang.CharSequence>>))
+1 error
--- a/test/tools/javac/lambda/VoidCompatibility.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/VoidCompatibility.java	Mon Jan 21 20:13:56 2013 +0000
@@ -3,7 +3,7 @@
  * @bug 8003280
  * @summary Add lambda tests
  *  check that that void compatibility affects overloading as expected
- * @compile/fail/ref=VoidCompatibility.out -XDrawDiagnostics VoidCompatibility.java
+ * @compile VoidCompatibility.java
  */
 class VoidCompatibility {
 
@@ -14,13 +14,13 @@
     void schedule(Thunk<?> t) { }
 
     void test() {
-        schedule(() -> System.setProperty("done", "true")); //2
+        schedule(() -> System.setProperty("done", "true")); //non-void most specific
         schedule(() -> { System.setProperty("done", "true"); }); //1
         schedule(() -> { return System.setProperty("done", "true"); }); //2
         schedule(() -> System.out.println("done")); //1
         schedule(() -> { System.out.println("done"); }); //1
         schedule(Thread::yield); //1
-        schedule(Thread::getAllStackTraces); //ambiguous
+        schedule(Thread::getAllStackTraces); //non-void most specific
         schedule(Thread::interrupted); //1 (most specific)
     }
 }
--- a/test/tools/javac/lambda/VoidCompatibility.out	Mon Jan 21 11:16:28 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-VoidCompatibility.java:17:9: compiler.err.ref.ambiguous: schedule, kindname.method, schedule(VoidCompatibility.Runnable), VoidCompatibility, kindname.method, schedule(VoidCompatibility.Thunk<?>), VoidCompatibility
-VoidCompatibility.java:23:9: compiler.err.ref.ambiguous: schedule, kindname.method, schedule(VoidCompatibility.Runnable), VoidCompatibility, kindname.method, schedule(VoidCompatibility.Thunk<?>), VoidCompatibility
-2 errors
--- a/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java	Mon Jan 21 20:13:56 2013 +0000
@@ -149,8 +149,7 @@
                 return false; //ambiguous target type
             }
             else if(lambdaBody == LambdaBody.IMPLICIT) {
-                if(returnValue != ReturnValue.INTEGER) //ambiguous target type
-                    return false;
+                return false;
             }
             else { //explicit parameter type
                 if(fInterface.getParameterType().equals("Integer")) //ambiguous target type
--- a/test/tools/javac/lambda/methodReference/SamConversion.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/methodReference/SamConversion.java	Mon Jan 21 20:13:56 2013 +0000
@@ -149,14 +149,6 @@
         test2(A::method3, 4);
         test2(new A()::method4, 5);
         test2(new A()::method5, 6);
-        A a = new A(A::method1); //A(Foo f) called
-        assertTrue(a.method2(1) == 11);
-        assertTrue(a.method4(1) == 11);
-        assertTrue(a.method5(1) == 11);
-        A a2 = new A(new A()::method2); //A(Bar b) called
-        assertTrue(a2.method2(1) == 12);
-        assertTrue(a2.method4(1) == 12);
-        assertTrue(a2.method5(1) == 12);
     }
 
     /**
@@ -279,7 +271,7 @@
         testConditionalExpression(false);
         testLambdaExpressionBody();
 
-        assertTrue(assertionCount == 38);
+        assertTrue(assertionCount == 32);
     }
 
     static class MyException extends Exception {}
--- a/test/tools/javac/lambda/methodReference/SamConversionComboTest.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/methodReference/SamConversionComboTest.java	Mon Jan 21 20:13:56 2013 +0000
@@ -186,10 +186,7 @@
         if(context != Context.CONSTRUCTOR && fInterface != FInterface.C && methodDef == MethodDef.METHOD6)
         //method that throws exceptions not thrown by the interface method is a mismatch
             return false;
-        if(context == Context.CONSTRUCTOR &&
-           methodReference != MethodReference.METHOD1 &&
-           methodReference != MethodReference.METHOD2 &&
-           methodReference != MethodReference.METHOD3)//ambiguous reference
+        if(context == Context.CONSTRUCTOR)
                return false;
         return true;
     }
--- a/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out	Mon Jan 21 20:13:56 2013 +0000
@@ -1,2 +1,2 @@
-InferenceTest_neg5.java:14:13: compiler.err.cant.apply.symbol: kindname.method, method1, InferenceTest_neg5.SAM1<X>, @419, kindname.class, InferenceTest_neg5, (compiler.misc.cyclic.inference: X)
+InferenceTest_neg5.java:14:21: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: X)
 1 error
--- a/test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java	Mon Jan 21 11:16:28 2013 -0800
+++ b/test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java	Mon Jan 21 20:13:56 2013 +0000
@@ -23,44 +23,44 @@
 
 @TraceResolve(keys={"compiler.err.ref.ambiguous"})
 class PrimitiveOverReferenceVarargsAmbiguous {
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
     static void m_byte(byte... b) {}
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS)
     static void m_byte(Byte... b) {}
 
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
     static void m_short(short... s) {}
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS)
     static void m_short(Short... s) {}
 
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
     static void m_int(int... i) {}
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS)
     static void m_int(Integer... i) {}
 
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
     static void m_long(long... l) {}
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS)
     static void m_long(Long... l) {}
 
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
     static void m_float(float... f) {}
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS)
     static void m_float(Float... f) {}
 
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
     static void m_double(double... d) {}
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS)
     static void m_double(Double... d) {}
 
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
     static void m_char(char... c) {}
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS)
     static void m_char(Character... c) {}
 
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
     static void m_bool(boolean... z) {}
-    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    @Candidate(applicable=Phase.VARARGS)
     static void m_bool(Boolean... z) {}
 
     {