changeset 590:352641ddfafa

Next round of implementation reflecting the latest 'State of the Lambda' draft; implemented features are: *) Lambda expressions New syntax. The non-terminal symbol '#' is still used to introduce both lambda expressions and function types, but a bunch of improvements have been made. Now, the lambda body is always denoted by braces '{' '}', as in #(int x) {}. Moreover, if the argument list is empty, it can be omitted, as in #{...}. *) SAM conversion & Target typing Updated to latest specification. Lambda expression are now only allowed where a target type is expected (return/assignment/method call - and, for compatibility with old prototype). The target type can be either a function type or a SAM type. The target type is used for inferring partially specified lambda types, as in #(x) { ... }. TODO: *) break/continue/return *) implementation of effectively final analysis *) method references
author mcimadamore
date Fri, 23 Jul 2010 09:52:55 +0100
parents e8877bcc2fab
children 639980747ee9
files src/share/classes/com/sun/runtime/ProxyHelper.java src/share/classes/com/sun/source/tree/LambdaExpressionTree.java src/share/classes/com/sun/tools/javac/code/Flags.java src/share/classes/com/sun/tools/javac/code/Type.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/AttrContext.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/comp/Enter.java src/share/classes/com/sun/tools/javac/comp/Flow.java src/share/classes/com/sun/tools/javac/comp/Infer.java src/share/classes/com/sun/tools/javac/comp/Lower.java src/share/classes/com/sun/tools/javac/comp/Resolve.java src/share/classes/com/sun/tools/javac/comp/Unlambda.java src/share/classes/com/sun/tools/javac/main/JavaCompiler.java src/share/classes/com/sun/tools/javac/model/JavacTypes.java src/share/classes/com/sun/tools/javac/parser/JavacParser.java src/share/classes/com/sun/tools/javac/parser/Lexer.java src/share/classes/com/sun/tools/javac/parser/Scanner.java src/share/classes/com/sun/tools/javac/resources/compiler.properties src/share/classes/com/sun/tools/javac/tree/JCTree.java src/share/classes/com/sun/tools/javac/tree/TreeCopier.java src/share/classes/com/sun/tools/javac/tree/TreeInfo.java src/share/classes/com/sun/tools/javac/tree/TreeMaker.java src/share/classes/com/sun/tools/javac/tree/TreeScanner.java src/share/classes/com/sun/tools/javac/util/Log.java src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java src/share/classes/javax/lang/model/util/Types.java test/tools/javac/defender/Pos01.java test/tools/javac/lambda/BadAccess.java test/tools/javac/lambda/BadAccess.out test/tools/javac/lambda/BadConv01.java test/tools/javac/lambda/BadConv02.java test/tools/javac/lambda/BadLambdaCall.java test/tools/javac/lambda/BadLambdaCall.out test/tools/javac/lambda/BadLambdaPos.java test/tools/javac/lambda/BadLambdaPos.out test/tools/javac/lambda/BadReturn.java test/tools/javac/lambda/BadReturn.out test/tools/javac/lambda/BadTargetType.java test/tools/javac/lambda/BadTargetType.out test/tools/javac/lambda/FuncType01.java test/tools/javac/lambda/LambdaCapture01.java test/tools/javac/lambda/LambdaCapture02.java test/tools/javac/lambda/LambdaCapture03.java test/tools/javac/lambda/LambdaCapture04.java test/tools/javac/lambda/LambdaCapture05.java test/tools/javac/lambda/LambdaConv01.java test/tools/javac/lambda/LambdaConv02.java test/tools/javac/lambda/LambdaConv02.out test/tools/javac/lambda/LambdaConv03.java test/tools/javac/lambda/LambdaConv04.java test/tools/javac/lambda/LambdaConv07.java test/tools/javac/lambda/LambdaExpr01.java test/tools/javac/lambda/LambdaExpr02.java test/tools/javac/lambda/LambdaExpr03.java test/tools/javac/lambda/LambdaExpr04.java test/tools/javac/lambda/LambdaScope01.java test/tools/javac/lambda/LambdaScope02.java test/tools/javac/lambda/NakedThis.java test/tools/javac/lambda/NakedThis.out test/tools/javac/lambda/TargetType01.java test/tools/javac/lambda/TargetType01.out test/tools/javac/lambda/TargetType02.java test/tools/javac/lambda/TargetType03.java test/tools/javac/lambda/TargetType04.java test/tools/javac/lambda/TargetType04.out test/tools/javac/lambda/TargetType05.java test/tools/javac/lambda/TargetType06.java test/tools/javac/transparency/Neg09.java test/tools/javac/transparency/Neg09.out
diffstat 71 files changed, 1843 insertions(+), 499 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/runtime/ProxyHelper.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/runtime/ProxyHelper.java	Fri Jul 23 09:52:55 2010 +0100
@@ -40,7 +40,15 @@
         return (T)Proxy.newProxyInstance(sam.getClassLoader(), new Class<?>[]{sam}, new InvocationHandler() {
             @Override
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                return mh.invokeVarargs(args);
+                //prepend proxy to list arg list
+                int len = args != null ?
+                    args.length :
+                    0;
+                Object[] args1 = new Object[len + 1];
+                if (len != 0)
+                    System.arraycopy(args, 0, args1, 1, len);
+                args1[0] = proxy;                
+                return mh.invokeVarargs(args1);
             }
         });
     }
--- a/src/share/classes/com/sun/source/tree/LambdaExpressionTree.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/source/tree/LambdaExpressionTree.java	Fri Jul 23 09:52:55 2010 +0100
@@ -35,4 +35,5 @@
 public interface LambdaExpressionTree extends ExpressionTree {
     List<? extends VariableTree> getParameters();
     Tree getBody();
+    ExpressionTree getIdentifier();
 }
--- a/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Flags.java	Fri Jul 23 09:52:55 2010 +0100
@@ -258,6 +258,16 @@
      */
     public static final long POLYMORPHIC_SIGNATURE = 1L<<43;
 
+    /**
+     * Flag that marks a lambda that needs a synthetic return statement
+     */
+    public static final long NEEDS_RETURN = 1L<<44;
+
+    /**
+     * Flag that marks a partially attributed type
+     */
+    public static final long PARTIAL = 1L<<45;
+
     /** Modifier masks.
      */
     public static final int
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Fri Jul 23 09:52:55 2010 +0100
@@ -1213,7 +1213,7 @@
          * @return qtype where all occurrences of tvars are replaced
          * by types in actuals
          */
-        public Type inst(List<Type> actuals, Types types) {
+        public Type inst(List<Type> actuals, Type to, Types types) {
             return types.subst(qtype, tvars, actuals);
         }
 
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Jul 23 09:52:55 2010 +0100
@@ -34,6 +34,7 @@
 import com.sun.tools.javac.jvm.ClassReader;
 import com.sun.tools.javac.comp.Check;
 import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.comp.Resolve;
 import com.sun.tools.javac.comp.AttrContext;
 
 import static com.sun.tools.javac.code.Type.*;
@@ -273,7 +274,7 @@
     }
 
     public boolean isConvertible(Env<AttrContext> env, Type t, Type s, Warner warn) {
-        return isConvertible(t, s, warn).check(env.enclClass.type);
+        return isConvertible(t, s, warn).check(env);
     }
 
     private boolean isConvertibleNoCheck(Type t, Type s, Warner warn) {
@@ -283,8 +284,6 @@
     private ConversionResult isConvertible(Type t, final Type s, Warner warn) {
         if (isFunctionType(t) &&
                 (isFunctionType(s) || s.tsym.kind == Kinds.TYP)) {
-            if (s == syms.objectType)
-                return ConversionResult.SUCCESS;
             final SAMResult samRes = findSAM(s);
             if (!isFunctionType(s) && samRes.isErroneous()) {
                 return new ConversionResult(samRes.errKey,
@@ -297,18 +296,18 @@
                 samRes.getTargetType();
             //the order is inmportant here because of type-inference
             //(reference types first)
-            final boolean isReturnOk = t.getReturnType() == syms.voidType ?
+            final boolean isReturnOk = t.getReturnType().tag == NONE || (t.getReturnType() == syms.voidType ?
                 (isSameType(mtype.getReturnType(), boxedClass(syms.voidType).type) ||
                     isSameType(mtype.getReturnType(), syms.voidType)) :
-                isConvertibleNoCheck(t.getReturnType(), mtype.getReturnType(), warn);
+                isConvertibleNoCheck(t.getReturnType(), mtype.getReturnType(), warn));
             
             boolean argsOk = t.getParameterTypes().size() == mtype.getParameterTypes().size() &&
                 containsType(mtype.getParameterTypes(), t.getParameterTypes());
-                    
+
             boolean thrownOk = chk.unhandled(t.getThrownTypes(), mtype.getThrownTypes()).isEmpty();
             return new ConversionResult(isReturnOk && argsOk && thrownOk) {
                 @Override
-                public boolean check(Type site) {
+                public boolean check(Env<AttrContext> env) {
                     if (!isSuccess()) {
                         //target method is not compatible
                         setDiagnostic("incompatible.target.in.lambda.conv");
@@ -321,6 +320,7 @@
                         //SAM type is an abstract class - check that both
                         //the target method and the SAM constructor are accessible
                         //in the given context
+                        Type site = env.enclClass.type;
                         Symbol noArgConstr = findNoArgConstructor((ClassSymbol)s.tsym);
                         ListBuffer<Symbol> buf = lb();
                         findSAM(s, buf);
@@ -335,6 +335,13 @@
                             setDiagnostic("target.for.lambda.conv.must.have.default.constr");
                             return false;
                         }
+                        if (s.getEnclosingType() != Type.noType &&
+                                (Resolve.isStatic(env) ||
+                                !isSubtypeUnchecked(site, s.getEnclosingType()))) {
+                            setDiagnostic("encl.instance.for.lambda.conv.target.must.be.in.scope",
+                                    s.getEnclosingType());
+                            return false;
+                        }
                         if (!isTargetAccessible) {
                             setDiagnostic("target.not.accessible");
                             return false;
@@ -342,8 +349,16 @@
                         return true;
                     }
                 }
-                private void setDiagnostic(String key) {
-                    setKey(key).setArgs(samRes.getTargetName(), Kinds.kindName(s.tsym), s.tsym);
+                private void setDiagnostic(String key, Object... args) {
+                    Object[] args2 = new Object[args.length + 3];
+                    args2[0] = samRes.getTargetName();
+                    args2[1] = Kinds.kindName(s.tsym);
+                    args2[2] = s.tsym;
+                    int pos = 3;
+                    for (Object o : args) {
+                        args2[pos] = o;
+                    }
+                    setKey(key).setArgs(args2);
                 }
                 private boolean isAccessible(Symbol sym, Type site) {
                     return (sym.flags() & (PUBLIC | PROTECTED)) != 0 ||
@@ -397,7 +412,7 @@
         public static final ConversionResult SUCCESS = new ConversionResult(true);
         public static final ConversionResult FAILURE = new ConversionResult(false);
 
-        public boolean check(Type site) { return success; }
+        public boolean check(Env<AttrContext> env) { return success; }
 
         public JCDiagnostic getDiagnostic(JCDiagnostic.Factory diags) {
             return detailsKey != null ?
@@ -509,12 +524,12 @@
         List<Symbol> methodSyms;
         String errKey;
 
-        SAMResult(String errKey) {
+        public SAMResult(String errKey) {
            this(null, List.<Symbol>nil(), errKey);
            targetType = syms.errType;
         }
 
-        SAMResult(Type samType, List<Symbol> methodSyms) {
+        public SAMResult(Type samType, List<Symbol> methodSyms) {
             this(samType, methodSyms, null);
             targetType = getTargetType();
         }
@@ -549,7 +564,7 @@
         public long getTargetFlags() {
             long flags = 0;
             for (Symbol s : methodSyms) {
-                flags |= s.flags();
+                flags |= s.flags() & ~ABSTRACT;
             }
             if ((flags & PUBLIC) != 0) {
                 flags = flags & (~PROTECTED | ~PRIVATE);
@@ -621,6 +636,66 @@
     }
     // </editor-fold>
 
+    // <editor-fold defaultstate="collapsed" desc="normalize">
+
+    /**
+     * Removes toplevel wildcard from a generic classtype. E.g. if T is a
+     * classtype of the kind C< ... , ? super/extends A, ... > this method
+     * finds a type S of the kind C<..., A, ...>. Then, the new type S
+     * is returned (assuming S <: T) otherwise an error type is returned.
+     *
+     * @param t the type to be normalized
+     * @return a type where toplevel wildcards have been removed
+     */
+    public Type normalize(Type t) {
+
+        class Normalizer extends UnaryVisitor<Type> {
+
+            boolean seenTopLevel = false;
+
+            @Override
+            public Type visitClassType(ClassType ct, Void s) {
+                if (!seenTopLevel) {
+                    seenTopLevel = true;
+                    boolean changed = false;
+                    ListBuffer<Type> buf = lb();
+                    for (Type t : ct.getTypeArguments()) {
+                        Type t2 = visit(t);
+                        if (t != t2) changed = true;
+                        buf.append(t2);
+                    }
+                    if (changed)
+                        return new ClassType(ct.getEnclosingType(),
+                                buf.toList(), ct.tsym);
+                }
+                return ct;
+            }
+
+            @Override
+            public Type visitWildcardType(WildcardType t, Void s) {
+                return visit(t.type);
+            }
+
+            @Override
+            public Type visitForAll(ForAll t, Void s) {
+                Type qtype2 = visit(t.qtype);
+                if (qtype2 != t.qtype) {
+                    return new ForAll(t.tvars, qtype2);
+                }
+                return t;
+            }
+
+            public Type visitType(Type t, Void s) {
+                return t;
+            }
+
+        }
+        Type t2 = new Normalizer().visit(t);
+        return isSubtypeUnchecked(t2, t) ?
+            t2 : createErrorType(t);
+    }
+    // </editor-fold>
+
     // <editor-fold defaultstate="collapsed" desc="isSubtype">
     /**
      * Is t an unchecked subtype of s?
@@ -774,10 +849,7 @@
 
             @Override
             public Boolean visitFunctionType(FunctionType t, Type s) {
-                if (isSameType(s, syms.objectType)) {
-                    return true;
-                }
-                else if (isFunctionType(s)) {
+                if (isFunctionType(s)) {
                     FunctionType that = (FunctionType)s;
                     boolean isReturnOk =                            
                         isSubtype(t.getReturnType(), that.getReturnType());
@@ -1717,8 +1789,11 @@
     }
 
     public boolean isFunctionType(Type t) {
-        return (t.tag == CLASS) &&
-                ((ClassType)t).isFunctionType();
+        switch (t.tag) {
+            case CLASS: return ((ClassType)t).isFunctionType();
+            case FORALL: return isFunctionType(((ForAll)t).qtype);
+            default: return false;
+        }
     }
 
     /**
@@ -1943,7 +2018,7 @@
     }
 
     public boolean isAssignable(Env<AttrContext> env, Type t, Type s, Warner warn) {        
-        return isAssignable(t, s, warn).check(env.enclClass.type);
+        return isAssignable(t, s, warn).check(env);
     }
 
     //the following methods should be private, but they need to be accessed from
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Jul 23 09:52:55 2010 +0100
@@ -38,6 +38,7 @@
 import com.sun.tools.javac.util.List;
 
 import com.sun.tools.javac.jvm.Target;
+import com.sun.tools.javac.code.Attribute.Compound;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.code.Type.*;
@@ -121,11 +122,14 @@
         allowCovariantReturns = source.allowCovariantReturns();
         allowAnonOuterThis = source.allowAnonOuterThis();
         allowStringsInSwitch = source.allowStringsInSwitch();
+        allowLambda = source.allowLambda();
         sourceName = source.name;
         relax = (options.get("-retrofit") != null ||
                  options.get("-relax") != null);
         useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null;
         enableSunApiLintControl = options.get("enableSunApiLintControl") != null;
+        identifyLambdaCandidate = options.get("identifyLambdaCandidate") != null &&
+                options.get("identifyLambdaCandidate").equals("true") ; //default disabled
     }
 
     /** Switch: relax some constraints for retrofit mode.
@@ -152,6 +156,10 @@
      */
     boolean allowCovariantReturns;
 
+    /** Switch: support lambda expressions ?
+     */
+    boolean allowLambda;
+
     /** Switch: allow references to surrounding object from anonymous
      * objects during constructor call?
      */
@@ -170,6 +178,12 @@
     boolean enableSunApiLintControl;
 
     /**
+     * Switch: generate warnings whenever an anonymous inner class that is convertible
+     * to a lambda expression is found
+     */
+    boolean identifyLambdaCandidate;
+
+    /**
      * Switch: allow strings in switch?
      */
     boolean allowStringsInSwitch;
@@ -380,6 +394,10 @@
      */
     Env<AttrContext> env;
 
+    /** Visitor argument: enclosing tree kind
+     */
+    int enclKind = -1;
+
     /** Visitor argument: the currently expected proto-kind.
      */
     int pkind;
@@ -400,13 +418,15 @@
      *  @param pkind   The protokind visitor argument.
      *  @param pt      The prototype visitor argument.
      */
-    Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt) {
+    Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, int enclKind, Type pt) {
         Env<AttrContext> prevEnv = this.env;
         int prevPkind = this.pkind;
+        int prevEnclKind = this.enclKind;
         Type prevPt = this.pt;
         try {
             this.env = env;
             this.pkind = pkind;
+            this.enclKind = enclKind;
             this.pt = pt;
             tree.accept(this);
             if (tree == breakTree)
@@ -418,12 +438,17 @@
         } finally {
             this.env = prevEnv;
             this.pkind = prevPkind;
+            this.enclKind = prevEnclKind;
             this.pt = prevPt;
         }
     }
 
     /** Derived visitor method: attribute an expression tree.
      */
+    Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt) {
+        return attribTree(tree, env, pkind, -1, pt);
+    }
+
     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
         return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType);
     }
@@ -477,7 +502,7 @@
         ListBuffer<Type> argtypes = new ListBuffer<Type>();
         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
             argtypes.append(chk.checkNonVoid(
-                l.head.pos(), types.upperBound(attribTree(l.head, env, VAL, Infer.anyPoly))));
+                l.head.pos(), types.upperBound(attribTree(l.head, env, VAL, JCTree.APPLY, Infer.anyPoly))));
         return argtypes.toList();
     }
 
@@ -1649,6 +1674,15 @@
                 //       }
                 //       ...
                 //     }
+
+                if (allowLambda &&
+                        identifyLambdaCandidate &&
+                        clazztype.tag == CLASS &&
+                        (enclKind == JCTree.APPLY || pt.tag == CLASS) &&
+                        !types.findSAM(clazztype).isErroneous()) {
+                    log.note(tree.def, "potential.lambda.found");
+                }
+
                 if (Resolve.isStatic(env)) cdef.mods.flags |= STATIC;
 
                 if (clazztype.tsym.isInterface()) {
@@ -1886,35 +1920,34 @@
      * also be generated as they are required during lowering (in order to find
      * free-variables used within a lambda expression).
      */
-    Env<AttrContext> lambdaEnvironment(JCLambda tree) {        
-        long flags = lambdaFlags(env);
+    Env<AttrContext> lambdaEnvironment(JCLambda tree, final Type targetType, boolean needsInference) {
+
         //create synthetic outer class symbol hoisting the lambda
-        ClassSymbol lambdaClassSym = 
-                new ClassSymbol(flags, names.empty, null, env.info.scope.owner);
-        lambdaClassSym.type = new ClassType(env.enclClass.type,
-                List.<Type>nil(),
-                lambdaClassSym);
-        Env<AttrContext> outerEnv =
-                env.dup(tree, env.info.dup(new Scope(lambdaClassSym)));
-        outerEnv.outer = env;
-        ((ClassType)lambdaClassSym.type).supertype_field = syms.methodHandleType;
-        outerEnv.enclClass = make.ClassDef(make.Modifiers(flags),
+        ClassSymbol lambdaClassSym = makeLambdaClass(targetType, env.info.scope.owner,
+                LAMBDA | SYNTHETIC | (needsInference ? PARTIAL : 0));
+
+        JCClassDecl classdef = make.ClassDef(make.Modifiers(lambdaClassSym.flags()),
                 names.empty,
                 List.<JCTypeParameter>nil(),
                 null, null, null);
-        outerEnv.enclClass.sym = lambdaClassSym;
-        outerEnv.enclClass.type = lambdaClassSym.type;
-        lambdaClassSym.members_field = outerEnv.info.scope;
+
+        classdef.sym = lambdaClassSym;
+        classdef.type = lambdaClassSym.type;
+
+        Env<AttrContext> outerEnv = enter.classEnv(classdef, env);
+        outerEnv.info.lint = env.info.lint.augment(List.<Compound>nil());
+
         lambdaEnvs.put(tree, outerEnv);
+        enter.typeEnvs.put(lambdaClassSym, outerEnv);
 
         //create synthetic lambda symbol
-        MethodSymbol lambdaSym =
-                new MethodSymbol(flags, names.lambda, null, outerEnv.info.scope.owner);
-        lambdaSym.type = new MethodType(null, Type.noType, null, syms.methodClass);
+        MethodSymbol lambdaSym = makeLambdaSymbol(targetType, lambdaClassSym);
+        lambdaClassSym.members_field.enter(lambdaSym);
+
         JCBlock body = tree.getBodyKind() == JCLambda.BodyKind.EXPRESSION ?
             make.Block(0, List.<JCStatement>of(make.Return((JCExpression)tree.body))) :
             (JCBlock)tree.body;
-        JCMethodDecl lambda = make.MethodDef(make.Modifiers(flags),
+        JCMethodDecl lambda = make.MethodDef(make.Modifiers(lambdaSym.flags()),
                 lambdaSym.name,
                 null, // missing restype
                 List.<JCTypeParameter>nil(),
@@ -1922,65 +1955,305 @@
                 List.<JCExpression>nil(),
                 body,
                 null); // missing defaultValue
-        tree.sym = lambdaSym;
+
+        lambda.type = lambdaSym.type;
+        lambda.sym = lambdaSym;
+        outerEnv.enclClass.defs = List.<JCTree>of(lambda);
         Env<AttrContext> newEnv = memberEnter.methodEnv(lambda, outerEnv);
-        newEnv.info.scope.owner = lambda.sym = lambdaSym;
-        newEnv.enclClass.defs = List.<JCTree>of(newEnv.enclMethod);
+        newEnv.info.scope.owner = lambda.sym;
+        
         //add 'this'
         VarSymbol thisSym = new VarSymbol(FINAL | HASINIT,
                 names._this,
                 lambdaClassSym.type,
                 lambdaClassSym);
         newEnv.info.scope.enter(thisSym);
+        
         return newEnv;
     }
     //where
-    private long lambdaFlags(Env<AttrContext> env) {
-        Symbol owner = env.info.scope.owner;
-        //a lambda definied in a static conext is static
-        boolean needsOuterAccess = (owner.flags() & LAMBDA) != 0 ?
-            (owner.flags() & OUTER_ACCESS) != 0 :
-            !Resolve.isStatic(env);
-        return LAMBDA | SYNTHETIC |
-                (needsOuterAccess ? OUTER_ACCESS : 0);
+    private ClassSymbol makeLambdaClass(Type targetType, Symbol owner, long flags) {
+
+        ClassSymbol lambdaClassSym =
+                    new ClassSymbol(flags, names.empty, null, owner);
+
+        lambdaClassSym.type = new ClassType(Type.noType,
+                List.<Type>nil(),
+                lambdaClassSym);
+
+        enter.setEnclosingType(lambdaClassSym, lambdaClassSym.owner);
+        lambdaClassSym.members_field = new Scope(lambdaClassSym);
+
+        Type superType = types.isFunctionType(targetType) ?
+            syms.methodHandleType :
+            targetType;
+
+        if (superType.isInterface()) {
+            ((ClassType)lambdaClassSym.type).supertype_field = syms.objectType;
+            ((ClassType)lambdaClassSym.type).interfaces_field = List.of(superType);
+        }
+        else {
+            ((ClassType)lambdaClassSym.type).supertype_field = superType;
+        }
+
+        return lambdaClassSym;
     }
-
+    //where
+    private MethodSymbol makeLambdaSymbol(Type targetType, Symbol owner) {
+        Name lambdaName = names.lambda;
+        long lambdaFlags = SYNTHETIC | LAMBDA;
+        Type lambdaType = null;
+
+        if (!types.isFunctionType(targetType)) {
+            Types.SAMResult samMethod = types.findSAM(targetType);
+            lambdaName = samMethod.getTargetName();
+            lambdaFlags = samMethod.getTargetFlags();
+            lambdaType = samMethod.getTargetType();
+        } else {
+            lambdaType = targetType.asMethodType(types);
+        }
+
+        return new MethodSymbol(
+                lambdaFlags,
+                lambdaName,
+                lambdaType,
+                owner);
+    }
+
+    /*
+     * Some lambda expressions are attributed using a two-phase process. First,
+     * thrown types/return type of a lambda expression is inferred from the lambda
+     * body (if possible, note that this might require exact knowledge of the
+     * target type of a lambda expression, which might/might not be available).
+     * During a second sweep, all type information associated with a lambda expression
+     * is given (e.g. expected return type/thrown types/parameer types) so that
+     * attribution of the lambda expression can proceed normally.
+     */
     @Override
     public void visitLambda(JCLambda that) {
-        Env<AttrContext> localEnv = lambdaEnvironment(that);
+        if (enclKind != JCTree.APPLY && pt.tag != CLASS) {
+            //lambda only allowed in assignment or method invocation context
+            log.error(that.pos(), "unexpected.lambda");
+        }
+        
+        Type targetType = that.clazz != null ?
+            attribType(that.clazz, env) :
+            Type.noType;
+
+        final Type typeToCheck = targetType != Type.noType ?
+            targetType :
+            pt;
+
+        //if the lambda expression needs parameter inference and/or the target
+        //type is unknown (e.g. the lambda position is in argument position)
+        //apply an inference step where lambda return type/thrown types are
+        //inferred from the body of the lambda; otherwise, just attribute the
+        //lambda expression against a given target type.
+        Type owntype = (typeToCheck.tag == NONE ||
+                that.needsParameterInference()) ?
+            inferLambda(that) :
+            attribLambda(that, typeToCheck);
+
+        //if the target type is known (e.g. lambda expression is in assignment,
+        //return statement, etc.) then we need to check the lambda expression type
+        //against the target type --- this will cause inference of uninferred
+        //lambda parameter types (if any).
+        result = (typeToCheck.tag != NONE) ?
+                check(that, owntype, VAL, pkind, typeToCheck) :
+                owntype;
+    }
+
+    /*
+     * Prepare for lambda inference. Replicate the AST and perform a first round
+     * of lambda attribution (see below) in which lambda return/thrown types
+     * are inferred from the lambda body.
+     */
+    Type inferLambda(final JCLambda that) {
+        ListBuffer<Type> argTypes = ListBuffer.lb();
+        ListBuffer<Type> tvars = ListBuffer.lb();
+        JCLambda tempLambda = new TreeCopier<Object>(make).copy(that);
+
+        //for each empty variable type, create a 'partial' type-variable
+        //this type-variable will be eventually inferred from the target-type
+        for (JCVariableDecl param : tempLambda.params) {
+            if (param.vartype == null) {
+                TypeSymbol tvSym = new TypeSymbol(PARTIAL,
+                        names.fromString("A_"+param.name),
+                        null,
+                        env.info.scope.owner);
+                TypeVar tv = new TypeVar(tvSym, syms.objectType, null);
+                param.vartype = make.Type(tv);
+                tvSym.type = tv;
+                tvars.append(tv);
+                argTypes.append(tv);
+            }
+            else {
+                argTypes.append(attribType(param.vartype, env));
+            }
+        }
+        Type ft = null;
+        boolean prevLogEnabled = log.isEnabled();
+        try {
+            //disable the log -- we need to do this in order to avoid
+            //spurious error messages from this partial attribution sweep
+            log.setEnabled(false);
+            ft = attribLambda(tempLambda);
+        }
+        finally {
+            log.setEnabled(prevLogEnabled);
+        }
+        return that.type = new ForAll(tvars.toList(), ft) {
+            @Override
+            public Type inst(List<Type> actuals, Type to, Types types) {
+                //now that we have a target type 'to' and a set of instantiated types
+                //for each of the unknown lambda parameter types, we can proceed
+                //with the second phase of lambda attribution (see below).
+                for (JCVariableDecl param : that.params) {
+                    if (param.vartype == null) {
+                        param.vartype = make.Type(actuals.head);
+                        actuals = actuals.tail;
+                    }
+                }
+                return that.type = attribLambda(that, to);
+            }
+        };
+    }
+
+    /*
+     * phase 1:
+     * Attribute a lambda expression where the target type is unknown;
+     * return type/thrown types of the lambda expression are inferred from the
+     * lambda body (if possible).
+     */
+    Type attribLambda(JCLambda that) {
+
+        //create an environment for attribution of the lambda expression
+        final Env<AttrContext> localEnv = lambdaEnvironment(that,
+                new FunctionType(List.<Type>nil(), Type.noType, List.<Type>nil(), syms.methodHandleType.tsym),
+                true);
+        localEnv.info.partialTypes = ListBuffer.<Type>lb();
+
+        //attribute lambda parameters
         attribStats(that.params, localEnv);
         ListBuffer<Type> argtypes = ListBuffer.lb();
         for (JCTree arg : that.params) {
             argtypes.append(arg.type);
         }
-        ((MethodType)localEnv.info.scope.owner.type).argtypes = argtypes.toList();
+
         Type resType = null;
+
         if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
+            //the return type is the type of the expression
             resType = attribExpr(that.getBody(), localEnv);
         }
         else {
+            //the return type is the union of all types
+            //returned by the lambda
+            JCBlock body = (JCBlock)that.body;
+            attribStats(body.stats, localEnv);
+            resType = localEnv.info.scope.owner.type.getReturnType();
+            if (resType == null || resType == Type.noType) {
+                //this happens if the body contains an expression statement
+                resType = syms.voidType;
+            }
+        }
+
+        //there are two causes that disable inference of lambda return type:
+        //(i) either the inferred return type is erroneous (meaning that the
+        // body of the lambda contained errors) or (ii) the inferred return type
+        //depends on the type of 'this' (which is unkown at this stage).
+        if (resType.isErroneous() ||
+                resType.contains(localEnv.enclClass.type)) {
+            //give up
+            resType = Type.noType;
+        }
+        else {
+            //infer return type from lambda body
+            resType = resType == syms.botType ?
+                    syms.objectType :
+                    resType;
+        }
+        
+        List<Type> thrownTypes = null;
+
+        //if one or more 'partial' types were accessed during this first attribution
+        //pass, then thrown types are left uninferred (as e.g. calling an unknown
+        //method on an unknown type might raise unknown exception types).
+        if (localEnv.info.partialTypes.nonEmpty()) {
+            thrownTypes = List.<Type>nil();
+        }
+
+        that.type = new FunctionType(argtypes.toList(),
+                resType,
+                thrownTypes,
+                syms.methodHandleType.tsym);
+
+        if (thrownTypes == null) {
+            //infer thrown types from lambda body
+            flow.analyzeLambda(that, make);
+        }
+        return that.type;
+    }
+
+    /**
+     * phase 2:
+     * Attribute a lambda expression with expected SAM type; return type/thrown
+     * types of the lambda expression are inferred from the target method of the
+     * lambda conversion.
+     */
+    Type attribLambda(JCLambda that, Type samOrFunctionType) {
+
+        //'normalize' the target type (i.e. strip toplevel wildcards, where possible)
+        Type superType = types.normalize(samOrFunctionType);
+
+        if (superType.isErroneous() ||
+                superType == Type.noType ||
+                (!types.isFunctionType(samOrFunctionType) &&
+                types.findSAM(superType).isErroneous())) {
+            //if the target type is neither a SAM type nor a function type, reports an error
+            log.error(that.pos(), "invalid.target.type.for.lambda.conv", samOrFunctionType);
+            return that.type = syms.errType;
+        }
+
+        //create an environment for attribution of the lambda expression
+        final Env<AttrContext> localEnv = lambdaEnvironment(that,
+                    superType,
+                    false);
+
+        //attribute lambda parameters
+        attribStats(that.params, localEnv);
+        ListBuffer<Type> argtypes = ListBuffer.lb();
+        for (JCTree arg : that.params) {
+            argtypes.append(arg.type);
+        }
+
+        Type targetType = localEnv.enclMethod.type;
+
+        //attribute the lambda body
+        if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
+            Type exprType = attribExpr(that.getBody(), localEnv);
+            Type reqType = targetType.getReturnType();
+            if (!types.isSameType(reqType, types.boxedClass(syms.voidType).type) &&
+                    exprType.tag == VOID) {
+                //check the expression type against the (possibly inferred) lambda return type
+                chk.checkType(that.getBody(), localEnv, exprType, reqType);
+            }
+        }
+        else {
             JCBlock body = (JCBlock)that.body;
             attribStats(body.stats, localEnv);
-            resType = localEnv.info.scope.owner.type.getReturnType();
-            if (resType == null || resType == Type.noType) { //if EXEC
-                resType = syms.voidType;
-            }
         }
-        if (resType == that.sym.owner.type) {
-            log.error(that.pos(), "cannot.infer.lambda.return.type");
-            resType = types.createErrorType(resType);
-        }
+        
         that.type = new FunctionType(argtypes.toList(),
-                resType == syms.botType ?
-                    syms.objectType :
-                    resType,
-                null,
+                targetType.getReturnType(),
+                targetType.getThrownTypes(),
                 syms.methodHandleType.tsym);
-        flow.analyzeLambda(that, make);
-        that.sym.type = that.type.asMethodType(types);
-        result = that.type = check(that, that.type, VAL, pkind, pt);
+
+        that.targetType = samOrFunctionType;
+        that.sym = localEnv.enclMethod.sym;
+        return that.type;
     }
-
+    
     public void visitParens(JCParens tree) {
         Type owntype = attribTree(tree.expr, env, pkind, pt);
         result = check(tree, owntype, pkind, pkind, pt);
@@ -2217,6 +2490,13 @@
             (sym.flags() & STATIC) == 0) {
             chk.earlyRefError(tree.pos(), sym.kind == VAR ? sym : thisSym(tree.pos(), env));
         }
+
+        if (sym.type.isErroneous() &&
+                (symEnv.enclClass.sym.flags() & PARTIAL) != 0 &&
+                env.info.partialTypes != null) {
+            env.info.partialTypes.append(symEnv.enclClass.type);
+        }
+
         Env<AttrContext> env1 = env;
         if (sym.kind != ERR && sym.kind != TYP && sym.owner != null && sym.owner != env1.enclClass.sym) {
             // If the found symbol is inaccessible, then it is
@@ -2279,6 +2559,13 @@
         // Determine the symbol represented by the selection.
         env.info.varArgs = false;
         Symbol sym = selectSym(tree, site, env, pt, pkind);
+
+        if (sym.type.isErroneous() &&
+                (site.tsym.flags() & PARTIAL) != 0 &&
+                env.info.partialTypes != null) {
+            env.info.partialTypes.append(site);
+        }
+
         if (sym.exists() && !isType(sym) && (pkind & (PCK | TYP)) != 0) {
             site = capture(site);
             sym = selectSym(tree, site, env, pt, pkind);
--- a/src/share/classes/com/sun/tools/javac/comp/AttrContext.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/AttrContext.java	Fri Jul 23 09:52:55 2010 +0100
@@ -75,6 +75,10 @@
      */
     boolean allowsDisjointTypes = false;
 
+    /** partial types encountered during attributin of lambda expressions
+     */
+    ListBuffer<Type> partialTypes = null;
+
     /** Duplicate this context, replacing scope field and copying all others.
      */
     AttrContext dup(Scope scope) {
@@ -88,6 +92,7 @@
         info.lint = lint;
         info.enclVar = enclVar;
         info.allowsDisjointTypes = allowsDisjointTypes;
+        info.partialTypes = partialTypes;
         return info;
     }
 
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Jul 23 09:52:55 2010 +0100
@@ -380,7 +380,7 @@
         if (req.tag == NONE)
             return found;
         Types.ConversionResult res = types.isAssignable(found, req, convertWarner(pos, found, req));
-        if (res.check(env.enclClass.type))
+        if (res.check(env))
             return found;
         if (found.tag <= DOUBLE && req.tag <= DOUBLE)
             return typeError(pos, diags.fragment("possible.loss.of.precision"), found, req);
@@ -428,7 +428,7 @@
                 }
             } catch (Infer.InvalidInstanceException ex) {
                 JCDiagnostic d = ex.getDiagnostic();
-                log.error(pos, "invalid.inferred.types", t.tvars, d);
+                log.error(pos, "invalid.inferred.types", ex.tvars, d);
                 return types.createErrorType(pt);
             }
         }
--- a/src/share/classes/com/sun/tools/javac/comp/Enter.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java	Fri Jul 23 09:52:55 2010 +0100
@@ -390,24 +390,10 @@
         c.sourcefile = env.toplevel.sourcefile;
         c.members_field = new Scope(c);
 
-        ClassType ct = (ClassType)c.type;
-        if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
-            // We are seeing a local or inner class.
-            // Set outer_field of this class to closest enclosing class
-            // which contains this class in a non-static context
-            // (its "enclosing instance class"), provided such a class exists.
-            Symbol owner1 = owner;
-            while (((owner1.kind & (VAR | MTH)) != 0 &&
-                   (owner1.flags_field & STATIC) == 0) ||
-                   (owner1.flags_field & LAMBDA) != 0) {
-                owner1 = owner1.owner;
-            }
-            if (owner1.kind == TYP) {
-                ct.setEnclosingType(owner1.type);
-            }
-        }
+        setEnclosingType(c, owner);
 
         // Enter type parameters.
+        ClassType ct = (ClassType)c.type;
         ct.typarams_field = classEnter(tree.typarams, localEnv);
 
         // Add non-local class to uncompleted, to make sure it will be
@@ -421,6 +407,25 @@
         result = c.type;
     }
     //where
+    void setEnclosingType(ClassSymbol c, Symbol owner) {
+        ClassType ct = (ClassType)c.type;
+        if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
+            // We are seeing a local or inner class.
+            // Set outer_field of this class to closest enclosing class
+            // which contains this class in a non-static context
+            // (its "enclosing instance class"), provided such a class exists.
+            Symbol owner1 = owner;
+            while ((owner1.kind & (VAR | MTH)) != 0 &&
+                   (owner1.flags_field & STATIC) == 0) {
+                owner1 = owner1.owner;
+            }
+            if (owner1.kind == TYP) {
+                ct.setEnclosingType(owner1.type);
+            }
+        }
+    }
+
+    //where
         /** Does class have the same name as the file it appears in?
          */
         private static boolean classNameMatchesFileName(ClassSymbol c,
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Fri Jul 23 09:52:55 2010 +0100
@@ -1256,8 +1256,17 @@
             }
             alive = true;
             scanStat(tree.body);
+            
+            if (alive && types.isSameType(tree.type.getReturnType(), types.boxedClass(syms.voidType).type)) {
+                //there's no return statement and the lambda (possibly inferred)
+                //return type is java.lang.Void; sets the NEEDS_RETURN flag in
+                //order to tell code generation to emit a synthetic return statement
+                tree.sym.flags_field |= NEEDS_RETURN;
+                alive = false;
+            }
+
             if (tree.getBodyKind() == JCLambda.BodyKind.STATEMENT &&
-                alive && tree.type.getReturnType().tag != VOID) {
+                    alive && tree.type.getReturnType().tag != VOID) {
                 log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt");
             }
             if (tree.type.getThrownTypes() == null) {
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri Jul 23 09:52:55 2010 +0100
@@ -31,6 +31,8 @@
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.code.Type.ForAll.ConstraintKind;
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
 import com.sun.tools.javac.util.JCDiagnostic;
 
 import static com.sun.tools.javac.code.TypeTags.*;
@@ -83,14 +85,16 @@
 
         JCDiagnostic diagnostic;
         JCDiagnostic.Factory diags;
+        List<Type> tvars;
 
         InferenceException(JCDiagnostic.Factory diags) {
             this.diagnostic = null;
             this.diags = diags;
         }
 
-        InferenceException setMessage(String key, Object... args) {
+        InferenceException setMessage(List<Type> tvars, String key, Object... args) {
             this.diagnostic = diags.fragment(key, args);
+            this.tvars = tvars;
             return this;
         }
 
@@ -144,12 +148,12 @@
                 switch (t.tag) {
                 case UNKNOWN:
                     throw ambiguousNoInstanceException
-                        .setMessage("undetermined.type");
+                        .setMessage(List.<Type>nil(), "undetermined.type");
                 case UNDETVAR:
                     UndetVar that = (UndetVar) t;
                     if (that.inst == null)
                         throw ambiguousNoInstanceException
-                            .setMessage("type.variable.has.undetermined.type",
+                            .setMessage(List.<Type>of(that.qtype), "type.variable.has.undetermined.type",
                                         that.qtype);
                     return apply(that.inst);
                 default:
@@ -177,7 +181,7 @@
         if (that.inst == null ||
             that.inst.isErroneous())
             throw ambiguousNoInstanceException
-                .setMessage("no.unique.maximal.instance.exists",
+                .setMessage(List.<Type>of(that.qtype), "no.unique.maximal.instance.exists",
                             that.qtype, that.hibounds);
     }
     //where
@@ -218,7 +222,7 @@
             }
             if (that.inst == null || that.inst.tag == ERROR)
                     throw ambiguousNoInstanceException
-                        .setMessage("no.unique.minimal.instance.exists",
+                        .setMessage(List.<Type>of(that.qtype), "no.unique.minimal.instance.exists",
                                     that.qtype, that.lobounds);
             // VGJ: sort of inlined maximizeInst() below.  Adding
             // bounds can cause lobounds that are above hibounds.
@@ -265,15 +269,27 @@
             }
             List<Type> inst = that.getConstraints(tv, ConstraintKind.EQUAL);
             if (inst.nonEmpty() && inst.head.tag != BOT) {
-                uv.inst = inst.head;
+                uv.inst = types.subst(inst.head, that.tvars, undetvars);
             }
             uv.hibounds = hibounds.toList();
         }
+        Type to2 = to.isPrimitive() && !that.qtype.isPrimitive() ?
+            types.boxedClass(to).type :
+            to; //this is a hack
         Type qtype1 = types.subst(that.qtype, that.tvars, undetvars);
-        if (!types.isSubtype(qtype1, to)) {
+        boolean ok = true;
+        if (types.isFunctionType(qtype1)) {
+            if (types.isFunctionType(to2) ||
+                    !types.findSAM(to2).isErroneous()) {
+                ok = types.isConvertible(env, qtype1, to2);
+            }
+        } else {
+            ok = types.isSubtype(qtype1, to2);
+        }
+        if (!ok) {
             throw unambiguousNoInstanceException
-                .setMessage("no.conforming.instance.exists",
-                            that.tvars, that.qtype, to);
+                .setMessage(that.tvars, "no.conforming.instance.exists",
+                            that.tvars, that.qtype, to2);
         }
         for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail)
             maximizeInst((UndetVar) l.head, warn);
@@ -283,7 +299,7 @@
         List<Type> targs = Type.map(undetvars, getInstFun);
         targs = types.subst(targs, that.tvars, targs);
         checkWithinBounds(that.tvars, targs, warn);
-        return chk.checkType(warn.pos(), env, that.inst(targs, types), to);
+        return chk.checkType(warn.pos(), env, that.inst(targs, to, types), to);
     }
 
     /** Instantiate method type `mt' by finding instantiations of
@@ -297,6 +313,7 @@
                                   final boolean useVarargs,
                                   final Warner warn) throws InferenceException {
         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
+        boolean inferArguments = false;
         List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
         List<Type> formals = mt.argtypes;
         //need to capture exactly once - otherwise subsequent
@@ -311,15 +328,24 @@
             Type formal = formals.head;
             Type actual = actuals.head.baseType();
             Type actualNoCapture = actualsNoCapture.head.baseType();
-            if (actual.tag == FORALL)
-                actual = instantiateArg(env, (ForAll)actual, formal, tvars, warn);
             Type undetFormal = types.subst(formal, tvars, undetvars);
+            if (actual.tag == FORALL) {
+                //improvement - go ahead with method conversion check but create
+                //a 'fake' actual arg, where tvars are replaced with undet var
+                ForAll fa = (ForAll)actual;
+                final List<Type> arg_fvs = Type.map(fa.tvars, fromTypeVarFun);
+                actual = types.subst(fa.qtype, fa.tvars, arg_fvs);
+                undetvars = undetvars.prependList(arg_fvs);
+                tvars = tvars.prependList(fa.tvars);
+                inferArguments = true;
+            }
+            
             boolean works = allowBoxing
                 ? types.isConvertible(env, actual, undetFormal, warn)
                 : types.isSubtypeUnchecked(actual, undetFormal, warn);
             if (!works) {
                 throw unambiguousNoInstanceException
-                    .setMessage("no.conforming.assignment.exists",
+                    .setMessage(tvars, "no.conforming.assignment.exists",
                                 tvars, actualNoCapture, formal);
             }
             formals = formals.tail;
@@ -330,7 +356,7 @@
             !useVarargs && actuals.nonEmpty()) { // too many args
             // argument lists differ in length
             throw unambiguousNoInstanceException
-                .setMessage("arg.length.mismatch");
+                .setMessage(tvars, "arg.length.mismatch");
         }
 
         // for varargs arguments as well
@@ -340,12 +366,20 @@
             while (actuals.nonEmpty()) {
                 Type actual = actuals.head.baseType();
                 Type actualNoCapture = actualsNoCapture.head.baseType();
-                if (actual.tag == FORALL)
-                    actual = instantiateArg(env, (ForAll)actual, elemType, tvars, warn);
+                if (actual.tag == FORALL) {                    
+                    //improvement - go ahead with method conversion check but create
+                    //a 'fake' actual arg, where tvars are replaced with undet var
+                    ForAll fa = (ForAll)actual;
+                    final List<Type> arg_fvs = Type.map(fa.tvars, fromTypeVarFun);
+                    actual = types.subst(fa.qtype, fa.tvars, arg_fvs);
+                    undetvars = undetvars.prependList(arg_fvs);
+                    tvars = tvars.prependList(fa.tvars);
+                    inferArguments = true;
+                }                
                 boolean works = types.isConvertible(env, actual, elemUndet, warn);
                 if (!works) {
                     throw unambiguousNoInstanceException
-                        .setMessage("no.conforming.assignment.exists",
+                        .setMessage(tvars, "no.conforming.assignment.exists",
                                     tvars, actualNoCapture, elemType);
                 }
                 actuals = actuals.tail;
@@ -371,12 +405,19 @@
 
         for (Type t : undetvars) {
             UndetVar uv = (UndetVar)t;
-            if (uv.inst.tag == BOT) {
+            while (uv.inst != null && uv.inst.tag == UNDETVAR) {
+                uv = (UndetVar)uv.inst;
+            }
+            if (uv.inst == null) {
+                uv = (UndetVar)t;
+            }
+            if (uv.inst.tag == UNDETVAR || uv.inst.tag == BOT) {
                 restvars.append(uv.qtype);
                 restundet.append(uv);
                 insttypes.append(uv.qtype);
                 undettypes.append(uv);
-                uv.inst = null;
+                if (uv.inst.tag == BOT)
+                    uv.inst = null;
             } else {
                 insttypes.append(uv.inst);
                 undettypes.append(uv.inst);
@@ -386,7 +427,7 @@
 
         mt = (MethodType)types.subst(mt, tvars, insttypes.toList());
 
-        if (!restvars.isEmpty()) {
+        if (!restvars.isEmpty() || inferArguments) {
             // if there are uninstantiated variables,
             // quantify result type with them
             final List<Type> inferredTypes = insttypes.toList();
@@ -401,7 +442,14 @@
                             switch (ck) {
                                 case EXTENDS: return uv.hibounds;
                                 case SUPER: return uv.lobounds;
-                                case EQUAL: return uv.inst != null ? List.of(uv.inst) : List.<Type>nil();
+                                case EQUAL: {
+                                    if (uv.inst != null && uv.inst.tag == UNDETVAR) {
+                                        return List.<Type>of(((UndetVar)uv.inst).qtype);
+                                    }
+                                    else {
+                                        return uv.inst != null ? List.of(uv.inst) : List.<Type>nil();
+                                    }
+                                }
                             }
                         }
                     }
@@ -409,52 +457,52 @@
                 }
 
                 @Override
-                public Type inst(List<Type> inferred, Types types) throws NoInstanceException {
+                public Type inst(List<Type> inferred, Type to, Types types) throws NoInstanceException {                   
                     List<Type> formals = types.subst(mt2.argtypes, tvars, inferred);
                     if (!rs.argumentsAcceptable(env, capturedArgs, formals,
                            allowBoxing, useVarargs, warn)) {
                       // inferred method is not applicable
-                      throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", formals, argtypes);
+                      throw invalidInstanceException.setMessage(tvars, "inferred.do.not.conform.to.params", formals, argtypes);
                     }
                     // check that inferred bounds conform to their bounds
                     checkWithinBounds(all_tvars,
                            types.subst(inferredTypes, tvars, inferred), warn);
                     if (useVarargs) {
                         chk.checkVararg(env.tree.pos(), formals);
+                    }                   
+                    if (env.tree.getTag() == JCTree.APPLY) {
+                        ((JCMethodInvocation)env.tree).meth.type = types.subst(mt2, tvars, inferred);
                     }
-                    return super.inst(inferred, types);
+                    return super.inst(inferred, to, types);
             }};
             return mt2;
         }
         else if (!rs.argumentsAcceptable(env, capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn)) {
             // inferred method is not applicable
-            throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", mt.getParameterTypes(), argtypes);
+            throw invalidInstanceException.setMessage(tvars, "inferred.do.not.conform.to.params", mt.getParameterTypes(), argtypes);
         }
         else {
             // return instantiated version of method type
             return mt;
         }
     }
-    //where
-
+    
         /** Try to instantiate argument type `that' to given type `to'.
          *  If this fails, try to insantiate `that' to `to' where
          *  every occurrence of a type variable in `tvars' is replaced
          *  by an unknown type.
          */
-        private Type instantiateArg(Env<AttrContext> env, ForAll that,
+        public Type instantiateArg(Env<AttrContext> env, ForAll that,
                                     Type to,
-                                    List<Type> tvars,
                                     Warner warn) throws InferenceException {
-            List<Type> targs;
+            Type inferredArg = null;
             try {
-                return instantiateExpr(env, that, to, warn);
-            } catch (NoInstanceException ex) {
-                Type to1 = to;
-                for (List<Type> l = tvars; l.nonEmpty(); l = l.tail)
-                    to1 = types.subst(to1, List.of(l.head), List.of(syms.unknownType));
-                return instantiateExpr(env, that, to1, warn);
+                inferredArg = instantiateExpr(env, that, to, warn);
             }
+            catch (Infer.InferenceException e) {
+                inferredArg = syms.errType;
+            }
+            return inferredArg;
         }
 
     /** check that type parameters are within their bounds.
@@ -470,7 +518,7 @@
             List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
             if (!types.isSubtypeUnchecked(args.head, bounds, warn))
                 throw invalidInstanceException
-                    .setMessage("inferred.do.not.conform.to.bounds",
+                    .setMessage(List.of(tvs.head), "inferred.do.not.conform.to.bounds",
                                 args.head, bounds);
         }
     }
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Fri Jul 23 09:52:55 2010 +0100
@@ -3741,17 +3741,26 @@
     }
 
     JCBlock makeLambdaBody(JCLambda tree) {
+        JCReturn defaultRet = null;
+        if ((tree.sym.flags() & Flags.NEEDS_RETURN) != 0) {
+            defaultRet = make.Return(make.Literal(TypeTags.BOT, null).setType(syms.botType));
+        }
+        JCBlock body = null;
         if (tree.getBodyKind() == JCLambda.BodyKind.EXPRESSION &&
                 tree.body.type != syms.voidType) {
-            return make.Block(0, List.<JCStatement>of(make.Return((JCExpression)tree.body)));
+            body = make.Block(0, List.<JCStatement>of(make.Return((JCExpression)tree.body)));
         } else {
             switch (tree.body.getTag()) {
-                case JCTree.BLOCK: return (JCBlock)tree.body;
+                case JCTree.BLOCK: body = (JCBlock)tree.body; break;
                 default:
                     JCStatement stat = make.Exec((JCExpression)tree.body);
-                    return make.Block(0, List.<JCStatement>of(stat));
+                    body = make.Block(0, List.<JCStatement>of(stat));
             }
         }
+        if (defaultRet != null) {
+            body.stats = body.stats.append(defaultRet);
+        }
+        return body;
     }
 
     /*
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Jul 23 09:52:55 2010 +0100
@@ -123,7 +123,7 @@
     /** An environment is "static" if its static level is greater than
      *  the one of its outer environment
      */
-    static boolean isStatic(Env<AttrContext> env) {
+    public static boolean isStatic(Env<AttrContext> env) {
         return env.info.staticLevel > env.outer.info.staticLevel;
     }
 
@@ -387,9 +387,12 @@
                                 Warner warn) {
         Type varargsFormal = useVarargs ? formals.last() : null;
         while (argtypes.nonEmpty() && formals.head != varargsFormal) {
+            Type actual = argtypes.head.tag == FORALL ?
+                infer.instantiateArg(env, (ForAll)argtypes.head, formals.head, warn) :
+                argtypes.head;
             boolean works = allowBoxing
-                ? types.isConvertible(env, argtypes.head, formals.head, warn)
-                : types.isSubtypeUnchecked(argtypes.head, formals.head, warn);
+                ? types.isConvertible(env, actual, formals.head, warn)
+                : types.isSubtypeUnchecked(actual, formals.head, warn);
             if (!works) return false;
             argtypes = argtypes.tail;
             formals = formals.tail;
@@ -399,7 +402,10 @@
             return argtypes.isEmpty();
         Type elt = types.elemtype(varargsFormal);
         while (argtypes.nonEmpty()) {
-            if (!types.isConvertible(env, argtypes.head, elt, warn))
+            Type actual = argtypes.head.tag == FORALL ?
+                infer.instantiateArg(env, (ForAll)argtypes.head, formals.head, warn) :
+                argtypes.head;
+            if (!types.isConvertible(env, actual, elt, warn))
                 return false;
             argtypes = argtypes.tail;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Unlambda.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1999, 2009, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.tools.javac.comp;
+
+import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.tree.*;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.List;
+
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.code.Type.*;
+
+
+/** This pass translates away lambda expressions
+ *
+ *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
+ *  you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class Unlambda extends TreeTranslator {
+    protected static final Context.Key<Unlambda> unlambdaKey =
+        new Context.Key<Unlambda>();
+
+    public static Unlambda instance(Context context) {
+        Unlambda instance = context.get(unlambdaKey);
+        if (instance == null)
+            instance = new Unlambda(context);
+        return instance;
+    }
+
+    private Names names;
+    private Symtab syms;
+    private Check chk;
+    private Enter enter;
+    private MemberEnter memberEnter;
+    private TreeMaker make;
+    private Types types;
+    private JCClassDecl currentClass;
+
+    protected Unlambda(Context context) {
+        names = Names.instance(context);
+        syms = Symtab.instance(context);
+        chk = Check.instance(context);
+        enter = Enter.instance(context);
+        memberEnter = MemberEnter.instance(context);
+        make = TreeMaker.instance(context);
+        types = Types.instance(context);
+    }
+
+    public JCTree translateTopLevelClass(JCTree cdef, TreeMaker make) {
+        // note that this method does NOT support recursion.
+        this.make = make;
+        return translate(cdef);
+    }
+
+    @Override
+    public void visitClassDef(JCClassDecl tree) {
+        JCClassDecl prevClass = currentClass;
+        try {
+            currentClass = tree;
+            super.visitClassDef(tree);
+        }
+        finally {
+            currentClass = prevClass;
+        }
+    }
+
+
+
+    public void visitLambda(JCLambda tree) {
+        if (types.isFunctionType(tree.targetType)) {
+            //lambda expression whose target is a function type are still
+            //translated in Lower
+            result = tree;
+            return;
+        }
+
+        Type type = tree.targetType;
+
+        //create new anon class definition implementing SAM method
+        //   class <anon> extends SAMClass { ... }
+
+        ClassSymbol samClassSym = (ClassSymbol)tree.sym.owner;
+        samClassSym.flatname = chk.localClassName(samClassSym);
+        chk.compiled.put(samClassSym.flatname, samClassSym);
+
+        JCClassDecl samClassDecl = make.ClassDef(
+                make.Modifiers(samClassSym.flags_field),
+                names.empty,
+                List.<JCTypeParameter>nil(),
+                type.isInterface() ? make.QualIdent(syms.objectType.tsym).setType(syms.objectType) : make.QualIdent(type.tsym).setType(type),
+                type.isInterface() ? List.of(make.QualIdent(type.tsym).setType(type)) : List.<JCExpression>nil(),
+                null);
+
+        samClassDecl.sym = samClassSym;
+        samClassDecl.type = samClassSym.type;
+
+        JCMethodDecl samConstrDecl = makeDefaultConstructor(tree.pos(), samClassSym);
+
+        //create SAM method
+        //   R m(A1, A2 ... An) throws T1, T2 ... Tn {
+        //      [return] $mh.invoke(a1, a2, ... an);
+        //   }
+
+        MethodSymbol samMethSym = (MethodSymbol)tree.sym;
+
+
+        JCMethodDecl samMethodDecl = make.MethodDef(samMethSym, null);
+        samMethodDecl.params = tree.params;
+
+        samMethodDecl.body = makeLambdaBody(tree);
+        samClassDecl.defs = List.<JCTree>of(samConstrDecl, samMethodDecl);
+        samClassSym.members().enter(samConstrDecl.sym);
+
+        JCNewClass newClass = make.NewClass(null,
+                List.<JCExpression>nil(),
+                make.QualIdent(type.tsym),
+                List.<JCExpression>nil(),
+                samClassDecl);
+        newClass.constructor = samConstrDecl.sym;
+        newClass.setType(samClassSym.type);
+        enter.typeEnvs.get(samClassSym).tree = samClassDecl;
+        result = translate(newClass);
+    }
+
+    private JCMethodDecl makeDefaultConstructor(final DiagnosticPosition pos, final ClassSymbol owner) {
+
+        final MethodSymbol defaultConstrSym = new MethodSymbol(0, names.init, null, owner);
+        defaultConstrSym.type = new MethodType(List.<Type>nil(), syms.voidType, List.<Type>nil(), syms.methodClass);
+
+        JCMethodDecl defaultConstr = (JCMethodDecl)memberEnter.DefaultConstructor(
+                make,
+                owner,
+                List.<Type>nil(),
+                List.<Type>nil(),
+                List.<Type>nil(),
+                defaultConstrSym.flags(),
+                false);
+        defaultConstr.sym = defaultConstrSym;
+        defaultConstr.type = defaultConstrSym.type;
+
+        class DefaultConstructorPatcher extends TreeScanner {
+            @Override
+            public void visitApply(JCMethodInvocation tree) {
+                super.visitApply(tree);
+                tree.type = syms.voidType; //super constructor call has void type
+            }
+            @Override
+            public void visitIdent(JCIdent tree) {
+                if (tree.name == names._super) {
+                    //set super constructor symbol and type
+                    tree.sym = types.findNoArgConstructor((ClassSymbol)types.supertype(owner.type).tsym);
+                    tree.type = tree.sym.type;
+                }
+            }
+        }
+
+        new DefaultConstructorPatcher().scan(defaultConstr);
+        return defaultConstr;
+    }
+
+    JCBlock makeLambdaBody(JCLambda tree) {
+        JCReturn defaultRet = null;
+        if ((tree.sym.flags() & Flags.NEEDS_RETURN) != 0) {
+            defaultRet = make.Return(make.Literal(TypeTags.BOT, null).setType(syms.botType));
+        }
+        JCBlock body = null;
+        if (tree.getBodyKind() == JCLambda.BodyKind.EXPRESSION &&
+                tree.body.type != syms.voidType) {
+            body = make.Block(0, List.<JCStatement>of(make.Return((JCExpression)tree.body)));
+        } else {
+            switch (tree.body.getTag()) {
+                case JCTree.BLOCK: body = (JCBlock)tree.body; break;
+                default:
+                    JCStatement stat = make.Exec((JCExpression)tree.body);
+                    body = make.Block(0, List.<JCStatement>of(stat));
+            }
+        }
+        if (defaultRet != null) {
+            body.stats = body.stats.append(defaultRet);
+        }
+        return body;
+    }
+}
--- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Jul 23 09:52:55 2010 +0100
@@ -266,6 +266,10 @@
      */
     protected TransTypes transTypes;
 
+    /** The lambda translator.
+     */
+    protected Unlambda unlambda;
+
     /** The syntactic sugar desweetener.
      */
     protected Lower lower;
@@ -349,6 +353,7 @@
         gen = Gen.instance(context);
         flow = Flow.instance(context);
         transTypes = TransTypes.instance(context);
+        unlambda = Unlambda.instance(context);
         lower = Lower.instance(context);
         annotate = Annotate.instance(context);
         types = Types.instance(context);
@@ -482,10 +487,12 @@
         ENTER(2),
         PROCESS(3),
         ATTR(4),
-        FLOW(5),
-        TRANSTYPES(6),
-        LOWER(7),
-        GENERATE(8);
+        FLOW(5),        
+        UNLAMBDA(6),
+        TRANSTYPES(7),
+        LOWER(8),
+        GENERATE(9);
+        
         CompileState(int value) {
             this.value = value;
         }
@@ -1304,6 +1311,12 @@
                 return;
             }
 
+            if (shouldStop(CompileState.UNLAMBDA))
+                return;
+
+            env.tree = unlambda.translateTopLevelClass(env.tree, localMake);
+            compileStates.put(env, CompileState.UNLAMBDA);
+
             if (shouldStop(CompileState.TRANSTYPES))
                 return;
 
--- a/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Fri Jul 23 09:52:55 2010 +0100
@@ -99,14 +99,7 @@
         validateTypeNotIn(t2, EXEC_OR_PKG);
         return types.isAssignableNoCheck((Type) t1, (Type) t2);
     }
-
-    public boolean isAssignable(TypeMirror site, TypeMirror t1, TypeMirror t2) {
-        validateTypeNotIn(site, EXEC_OR_PKG);
-        validateTypeNotIn(t1, EXEC_OR_PKG);
-        validateTypeNotIn(t2, EXEC_OR_PKG);
-        return types.isAssignable((Type) t1, (Type) t2, Warner.noWarnings).check((Type)site);
-    }
-
+    
     public boolean contains(TypeMirror t1, TypeMirror t2) {
         validateTypeNotIn(t1, EXEC_OR_PKG);
         validateTypeNotIn(t2, EXEC_OR_PKG);
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Jul 23 09:52:55 2010 +0100
@@ -29,7 +29,6 @@
 
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.code.*;
-import com.sun.tools.javac.main.OptionName;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.List;
 import static com.sun.tools.javac.util.ListBuffer.lb;
@@ -228,6 +227,7 @@
     static final int TYPEARG = 0x8;
     static final int DIAMOND = 0x10;
     static final int DISJOINT = 0x20;
+    static final int NOLAMBDA = 0x40;
 
     /** The current mode.
      */
@@ -657,7 +657,7 @@
 
     public JCExpression parseType() {
         List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
-        return parseType(annotations, TYPE);
+        return parseType(annotations, TYPE | NOLAMBDA);
     }
 
     public JCExpression parseType(List<JCTypeAnnotation> annotations, int mode) {
@@ -939,7 +939,7 @@
      *                 | "[" Expression "]"
      *  TypeSelector   = "." Ident [TypeArguments]
      *  SuperSuffix    = Arguments | "." Ident [Arguments]
-     */
+     */    
     protected JCExpression term3() {
         int pos = S.pos();
         JCExpression t;
@@ -966,7 +966,7 @@
                     return F.at(pos).Unary(unoptag(token), t);
                 }
             } else return illegal();
-            break;
+            break;        
         case HASH:
             int prevPos = S.pos();
             S.nextToken();
@@ -976,7 +976,7 @@
             if (typeArgs == null && (mode & EXPR) != 0) {
                 S.pushState();
                 S.nextToken();
-                mode = EXPR | TYPE | NOPARAMS;
+                mode = EXPR | TYPE | NOPARAMS | NOLAMBDA;
                 t = term3();
                 if ((mode & TYPE) != 0 && S.token() == LT) {
                     // Could be a cast to a parameterized type
@@ -984,7 +984,7 @@
                     int pos1 = S.pos();
                     S.nextToken();
                     mode &= (EXPR | TYPE);
-                    mode |= TYPEARG | DISJOINT;
+                    mode |= TYPEARG | DISJOINT | NOLAMBDA;
                     JCExpression t1 = term3();
                     if ((mode & TYPE) != 0 &&
                         (S.token() == COMMA || S.token() == GT)) {
@@ -1025,6 +1025,7 @@
                     break;
                 }
                 accept(RPAREN);
+                S.mergeState();
                 lastmode = mode;
                 mode = EXPR;
                 if ((lastmode & EXPR) == 0) {
@@ -1167,7 +1168,7 @@
                             mode = EXPR;
                             t = to(F.at(pos).Select(t, names._class));
                             S.nextToken();
-                            break loop;
+                            break loop;                        
                         case THIS:
                             if (typeArgs != null) return illegal();
                             mode = EXPR;
@@ -1207,8 +1208,46 @@
                     break loop;
                 }
             }
-            if (typeArgs != null) illegal();
-            t = typeArgumentsOpt(t);
+            if (typeArgs != null) illegal();            
+            if ((mode & NOLAMBDA) != 0) {
+                t = typeArgumentsOpt(t);
+            }
+            else if (S.token() == LT) {                
+                S.pushState();
+                int oldPos = S.pos();
+                S.nextToken();
+                int prevMode = mode;                
+                mode |= EXPR | TYPE | TYPEARG| NOLAMBDA | DISJOINT;
+                JCExpression t1 = term3();                
+                if ((mode & TYPE) != 0 &&
+                    (S.token() == COMMA || S.token() == GT)) {
+                    checkGenerics(oldPos);
+                    mode = TYPE;
+                    ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
+                    args.append(t1);
+                    while (S.token() == COMMA) {
+                        S.nextToken();
+                        args.append(typeArgument());
+                    }
+                    if (S.token() == GT) {
+                        accept(GT);
+                        S.mergeState();
+                        t = toP(F.at(pos).TypeApply(t, args.toList()));
+                        if (S.token() == HASH) {
+                            accept(HASH);
+                            t = lambdaExpressionOrStatement(t, pos);
+                        }
+                    }
+                    else {
+                        mode = EXPR;
+                        S.popState();
+                    }
+                } else {
+                    mode = prevMode;
+                    S.popState();                    
+                    t = typeArgumentsOpt(t);
+                }
+             };
             break;
         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
         case DOUBLE: case BOOLEAN:
@@ -1334,32 +1373,55 @@
     }
 
     JCExpression lambdaOrFunctionType(int pos) {
-        return S.token() == LPAREN ?
-            lambdaExpressionOrStatement(pos) :
+        return S.token() == LPAREN ||
+                S.token() == LBRACE ?
+            lambdaExpressionOrStatement(null, pos) :
             functionType();
     }
 
-    JCExpression lambdaExpressionOrStatement(int pos) {
+    @SuppressWarnings("fallthrough")
+    JCExpression lambdaExpressionOrStatement(JCExpression clazz, int pos) {
         mode = EXPR;
         checkLambda();
-        List<JCVariableDecl> args = formalParameters();
-        return S.token() == LBRACE ?
-            lambdaExpression(args, pos) :
-            S.token() == LPAREN ?
-                lambdaStatement(args, pos) :
-                illegal();
+
+        List<JCVariableDecl> args = List.nil();
+        if (S.token() == LPAREN) {
+            args = formalParameters(true);
+        }
+
+        S.pushState();
+        boolean isBlock = false;
+        accept(LBRACE);
+        if (S.token() == RBRACE) {
+            //empty block
+            isBlock = true;
+        }
+        else {
+            StatementKind sk = statementKind();
+            switch (sk) {
+                case STATEMENT: isBlock = true; break;
+                case EXPRESSION_STATEMENT:
+                    parseExpression();
+                    isBlock = S.token() != RBRACE;
+            }
+        }
+        S.popState();
+
+        return isBlock ?
+            lambdaStatement(clazz, args, pos) :
+            lambdaExpression(clazz, args, pos);
     }
 
-    JCExpression lambdaExpression(List<JCVariableDecl> args, int pos) {
+    JCExpression lambdaStatement(JCExpression clazz, List<JCVariableDecl> args, int pos) {
         JCBlock block = block();
-        return toP(F.at(pos).Lambda(args, block));
+        return toP(F.at(pos).Lambda(clazz, args, block));
     }
 
-    JCExpression lambdaStatement(List<JCVariableDecl> args, int pos) {
-        accept(LPAREN);
+    JCExpression lambdaExpression(JCExpression clazz, List<JCVariableDecl> args, int pos) {
+        accept(LBRACE);
         JCTree expr = parseExpression();
-        accept(RPAREN);
-        return toP(F.at(pos).Lambda(args, expr));
+        accept(RBRACE);
+        return toP(F.at(pos).Lambda(clazz, args, expr));
     }
 
     JCExpression functionType() {
@@ -1449,7 +1511,7 @@
         if (S.token() == LT &&
             (mode & TYPE) != 0 &&
             (mode & NOPARAMS) == 0) {
-            mode = TYPE | DISJOINT;
+            mode = TYPE | NOLAMBDA | DISJOINT;
             checkGenerics();
             return typeArguments(t);
         } else {
@@ -1457,7 +1519,7 @@
         }
     }
     List<JCExpression> typeArgumentsOpt() {
-        return typeArgumentsOpt(TYPE | DISJOINT);
+        return typeArgumentsOpt(TYPE | NOLAMBDA | DISJOINT);
     }
 
     List<JCExpression> typeArgumentsOpt(int useMode) {
@@ -1484,10 +1546,10 @@
                 S.nextToken();
                 return List.nil();
             }
-            args.append(((mode & EXPR) == 0) ? typeArgument() : parseType(TYPE | DISJOINT));
+            args.append(((mode & EXPR) == 0) ? typeArgument() : parseType(TYPE | NOLAMBDA | DISJOINT));
             while (S.token() == COMMA) {
                 S.nextToken();
-                args.append(((mode & EXPR) == 0) ? typeArgument() : parseType(TYPE | DISJOINT));
+                args.append(((mode & EXPR) == 0) ? typeArgument() : parseType(TYPE | NOLAMBDA | DISJOINT));
             }
             switch (S.token()) {
             case GTGTGTEQ:
@@ -1522,19 +1584,19 @@
      */
     JCExpression typeArgument() {
         List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
-        if (S.token() != QUES) return parseType(annotations, TYPE | DISJOINT);
+        if (S.token() != QUES) return parseType(annotations, TYPE | NOLAMBDA | DISJOINT);
         int pos = S.pos();
             S.nextToken();
         JCExpression result;
         if (S.token() == EXTENDS) {
             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
             S.nextToken();
-            JCExpression bound = parseType(TYPE | DISJOINT);
+            JCExpression bound = parseType(TYPE | NOLAMBDA | DISJOINT);
             result = F.at(pos).Wildcard(t, bound);
         } else if (S.token() == SUPER) {
             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
             S.nextToken();
-            JCExpression bound = parseType(TYPE | DISJOINT);
+            JCExpression bound = parseType(TYPE | NOLAMBDA | DISJOINT);
             result = F.at(pos).Wildcard(t, bound);
         } else if (S.token() == IDENTIFIER) {
             //error recovery
@@ -1964,6 +2026,53 @@
         }
     }
 
+    enum StatementKind {
+        ERRONEOUS,
+        STATEMENT,
+        EXPRESSION,
+        EXPRESSION_STATEMENT;
+    }
+
+    @SuppressWarnings("fallthrough")
+    StatementKind statementKind() {
+        switch (S.token()) {
+            case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
+            case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
+            case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
+            case INTERFACE: case CLASS: case MONKEYS_AT: case FINAL:
+            case ABSTRACT: case STRICTFP:
+                return StatementKind.STATEMENT;
+            case ENUM:
+            case ASSERT:
+                if (allowEnums && S.token() == ENUM) {
+                    return StatementKind.ERRONEOUS;
+                } else if (allowAsserts && S.token() == ASSERT) {
+                    return StatementKind.STATEMENT;
+                }
+            /* fall through to default */
+            default:
+                try {
+                    S.pushState();
+                    JCExpression t = term(EXPR | TYPE);
+                    if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
+                        return StatementKind.STATEMENT;
+                    } else if ((lastmode & TYPE) != 0 &&
+                               (S.token() == IDENTIFIER ||
+                                S.token() == ASSERT ||
+                                S.token() == ENUM)) {
+                        return StatementKind.STATEMENT;
+                    } else {
+                        return isExpressionStatement(t) ?
+                            StatementKind.EXPRESSION_STATEMENT :
+                            StatementKind.ERRONEOUS;
+                    }
+                }
+                finally {
+                    S.popState();
+                }
+        }
+    }
+
     /** Statement =
      *       Block
      *     | IF ParExpression Statement [ELSE Statement]
@@ -3131,15 +3240,19 @@
      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
      */
-    List<JCVariableDecl> formalParameters() {
+    List<JCVariableDecl> formalParameters() {     
+        return formalParameters(false);
+    }
+
+    List<JCVariableDecl> formalParameters(boolean optionalTypes) {
         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
         JCVariableDecl lastParam = null;
         accept(LPAREN);
         if (S.token() != RPAREN) {
-            params.append(lastParam = formalParameter());
+            params.append(lastParam = formalParameter(optionalTypes));
             while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
                 S.nextToken();
-                params.append(lastParam = formalParameter());
+                params.append(lastParam = formalParameter(optionalTypes));
             }
         }
         accept(RPAREN);
@@ -3156,14 +3269,25 @@
     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
      */
-    JCVariableDecl formalParameter() {
+    JCVariableDecl formalParameter(boolean optionalTypes) {
         JCModifiers mods = optFinal(Flags.PARAMETER);
+        if (optionalTypes) {
+            S.pushState();
+        }
         // need to distinguish between vararg annos and array annos
         // look at typeAnnotaitonsPushedBack comment
         this.permitTypeAnnotationsPushBack = true;
         JCExpression type = parseType();
         this.permitTypeAnnotationsPushBack = false;
 
+        if (optionalTypes && (
+                S.token() == COMMA ||
+                S.token() == RPAREN)) {
+            S.popState();
+            return variableDeclaratorId(mods, null);
+        }
+        S.mergeState();
+
         if (S.token() == ELLIPSIS) {
             List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
             typeAnnotationsPushedBack = null;
@@ -3209,6 +3333,22 @@
         }
     }
 
+    protected boolean isExpressionStatement(JCExpression t) {
+        switch(t.getTag()) {
+            case JCTree.PREINC: case JCTree.PREDEC:
+            case JCTree.POSTINC: case JCTree.POSTDEC:
+            case JCTree.ASSIGN:
+            case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
+            case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
+            case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
+            case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
+            case JCTree.APPLY: case JCTree.NEWCLASS:
+            case JCTree.ERRONEOUS:
+                return true;
+            default: return false;
+        }
+    }
+
     /** Return precedence of operator represented by token,
      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
      */
@@ -3350,8 +3490,11 @@
     }
 
     void checkGenerics() {
+        checkGenerics(S.pos());
+    }
+    void checkGenerics(int pos) {
         if (!allowGenerics) {
-            log.error(S.pos(), "generics.not.supported.in.source", source.name);
+            log.error(pos, "generics.not.supported.in.source", source.name);
             allowGenerics = true;
         }
     }
--- a/src/share/classes/com/sun/tools/javac/parser/Lexer.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/Lexer.java	Fri Jul 23 09:52:55 2010 +0100
@@ -154,4 +154,9 @@
      * Restore the previously saved lexer state
      */
     void popState();
+
+    /**
+     * Restore the previously saved lexer state
+     */
+    void mergeState();
 }
--- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Fri Jul 23 09:52:55 2010 +0100
@@ -259,6 +259,12 @@
         stateStack = stateStack.tail;
     }
 
+    public void mergeState() {
+        stateStack = stateStack.nonEmpty() ?
+            stateStack.tail :
+            List.<ScannerState>nil();
+    }
+
     private static final boolean hexFloatsWork = hexFloatsWork();
     private static boolean hexFloatsWork() {
         try {
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Jul 23 09:52:55 2010 +0100
@@ -93,6 +93,8 @@
     lambda expression cannot be applied to given types\n\
     required: {0}\n\
     found: {1}
+compiler.err.invalid.target.type.for.lambda.conv=\
+    invalid target type {0} for lambda conversion
 compiler.misc.no.target.method.for.lambda.conv=\
     no target method for lambda conversion found in {1} {2}
 compiler.misc.incompatible.target.in.lambda.conv=\
@@ -105,6 +107,8 @@
     the target type of a lambda conversion must be an abstract class/interface
 compiler.misc.target.for.lambda.conv.must.have.default.constr=\
     the target type of a lambda conversion must define an accessible no-arg constructor
+compiler.misc.encl.instance.for.lambda.conv.target.must.be.in.scope=\
+    an enclosing instance that contains {3} is required
 compiler.misc.target.not.accessible=\
     target method of lambda conversion {0} in {1} {2} is not accessible
 compiler.misc.multiple.targets.for.lambda.conv=\
@@ -603,6 +607,9 @@
 
 ## The following string will appear before all messages keyed as:
 ## "compiler.note".
+
+compiler.note.potential.lambda.found=\
+    This anonymous inner class creation can be turned into a lambda expression.
 compiler.note.note=\
     Note:\u0020
 
@@ -1086,6 +1093,8 @@
     actual arguments do not conform to inferred formal arguments\n\
     required: {0}\n\
     found: {1}
+compiler.misc.inference.loop=\
+    type-inference loop detected
 compiler.misc.diamond=\
     {0}<>
 compiler.misc.diamond.invalid.arg=\
@@ -1109,6 +1118,9 @@
 required: {0}\n\
 found:    {1}
 
+compiler.err.unexpected.lambda=\
+   lambda expression not expected here
+
 ## The first argument {0} is a "kindname" (e.g. 'constructor', 'field', etc.)
 ## The second argument {1} is the non-resolved symbol
 ## The third argument {2} is a list of type parameters (non-empty if {1} is a method)
@@ -1146,9 +1158,6 @@
 compiler.err.lambda.call.non.func.type=\
     lambda invocation syntax cannot be used on non-lambda type {0}
 
-compiler.err.cannot.infer.lambda.return.type=\
-    return type of the lambda expression cannot be inferred because of a cyclic reference to ''this''
-
 ## The following are all possible string for "kindname".
 ## They should be called whatever the JLS calls them after it been translated
 ## to the appropriate language.
--- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Fri Jul 23 09:52:55 2010 +0100
@@ -1441,16 +1441,28 @@
         public List<JCVariableDecl> params;
         public JCTree body;
         public Symbol sym;
+        public Type targetType;
+        public JCExpression clazz;
+        private boolean needsParameterInference = false;
     
         public JCLambda(List<JCVariableDecl> params,
-                        JCTree body) {
+                        JCTree body,
+                        JCExpression clazz) {
             this.params = params;
             this.body = body;
+            this.clazz = clazz;
+            for (JCVariableDecl param : params) {
+                if (param.vartype == null) {
+                    needsParameterInference = true;
+                    break;
+                }
+            }
         }
         @Override
         public int getTag() {
             return LAMBDA;
         }
+        public JCExpression getIdentifier() { return clazz; }
         @Override
         public void accept(Visitor v) {
             v.visitLambda(this);
@@ -1481,6 +1493,9 @@
                 return BodyKind.EXPRESSION;
             }
         }
+        public boolean needsParameterInference() {
+            return needsParameterInference;
+        }
     }
 
     /**
--- a/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Fri Jul 23 09:52:55 2010 +0100
@@ -282,8 +282,9 @@
     public JCTree visitLambdaExpression(LambdaExpressionTree node, P p) {
         JCLambda t = (JCLambda) node;
         List<JCVariableDecl> params = copy(t.params, p);
+        JCExpression clazz = copy(t.clazz, p);
         JCTree body = copy(t.body, p);
-        return M.at(t.pos).Lambda(params, body);
+        return M.at(t.pos).Lambda(clazz, params, body);
     }
 
     public JCTree visitParenthesized(ParenthesizedTree node, P p) {
--- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Fri Jul 23 09:52:55 2010 +0100
@@ -327,6 +327,10 @@
             JCVariableDecl node = (JCVariableDecl)tree;
             if (node.mods.pos != Position.NOPOS) {
                 return node.mods.pos;
+            } else if (node.vartype == null) {
+                //if there's no type (partially typed lambda parameter)
+                //simply return node position
+                return node.pos;
             } else {
                 return getStartPos(node.vartype);
             }
--- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Fri Jul 23 09:52:55 2010 +0100
@@ -360,10 +360,11 @@
         return tree;
     }
 
-    public JCLambda Lambda(List<JCVariableDecl> params,
+    public JCLambda Lambda(JCExpression clazz,
+                           List<JCVariableDecl> params,
                            JCTree body)
     {
-        JCLambda tree = new JCLambda(params, body);
+        JCLambda tree = new JCLambda(params, body, clazz);
         tree.pos = pos;
         return tree;
     }
@@ -670,6 +671,15 @@
             tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
             break;
         }
+        case DISJOINT: {
+            DisjunctiveType dt = (DisjunctiveType)t;
+            ListBuffer<JCExpression> subTypes = ListBuffer.lb();
+            for (Type t2 : dt.types) {
+                subTypes.append(Type(t2));
+            }
+            tp = TypeDisjoint(subTypes.toList());
+            break;
+        }
         case CLASS:
             Type outer = t.getEnclosingType();
             JCExpression clazz = outer.tag == CLASS && t.tsym.owner.kind == TYP
--- a/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Fri Jul 23 09:52:55 2010 +0100
@@ -216,6 +216,7 @@
     }
 
     public void visitLambda(JCLambda tree) {
+        scan(tree.clazz);
         scan(tree.body);
         scan(tree.params);
     }
--- a/src/share/classes/com/sun/tools/javac/util/Log.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/util/Log.java	Fri Jul 23 09:52:55 2010 +0100
@@ -71,6 +71,10 @@
 
     /** Switch: prompt user on each error.
      */
+    public boolean enabled;
+
+    /** Switch: prompt user on each error.
+     */
     public boolean promptOnError;
 
     /** Switch: emit warning messages.
@@ -127,6 +131,7 @@
         this.suppressNotes = options.get("suppressNotes") != null;
         this.MaxErrors = getIntOption(options, "-Xmaxerrs", 100);
         this.MaxWarnings = getIntOption(options, "-Xmaxwarns", 100);
+        this.enabled = true;
 
         boolean rawDiagnostics = options.get("rawDiagnostics") != null;
         messages = JavacMessages.instance(context);
@@ -208,6 +213,14 @@
         return diagListener != null;
     }
 
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
     public void setEndPosTable(JavaFileObject name, Map<JCTree, Integer> table) {
         name.getClass(); // null check
         getSource(name).setEndPosTable(table);
@@ -326,6 +339,7 @@
      * reported so far, the diagnostic may be handed off to writeDiagnostic.
      */
     public void report(JCDiagnostic diagnostic) {
+        if (!enabled) return;
         if (expectDiagKeys != null)
             expectDiagKeys.remove(diagnostic.getCode());
 
--- a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Fri Jul 23 09:52:55 2010 +0100
@@ -348,6 +348,16 @@
         }
 
         @Override
+        public String visitForAll(ForAll t, Locale locale) {
+            if (types.isFunctionType(t)) {
+                return visit(t.qtype, locale);
+            }
+            else {
+                return super.visitForAll(t, locale);
+            }
+        }
+
+        @Override
         public String visitCapturedType(CapturedType t, Locale locale) {
             if (getConfiguration().isEnabled(RichFormatterFeature.WHERE_CLAUSES)) {
                 return localize(locale,
@@ -396,7 +406,10 @@
 
         @Override
         public String visitTypeVar(TypeVar t, Locale locale) {
-            if (unique(t) ||
+            if ((t.tsym.flags() & PARTIAL) != 0) {
+                return "?";
+            }
+            else if (unique(t) ||
                     !getConfiguration().isEnabled(RichFormatterFeature.UNIQUE_TYPEVAR_NAMES)) {
                 return t.toString();
             }
@@ -460,14 +473,14 @@
     protected Types.UnaryVisitor<Void> typePreprocessor =
             new Types.UnaryVisitor<Void>() {
 
-        public Void visit(List<Type> ts) {
+        public Void visit(List<Type> ts) {            
             for (Type t : ts)
                 visit(t);
             return null;
         }
 
         @Override
-        public Void visitForAll(ForAll t, Void ignored) {
+        public Void visitForAll(ForAll t, Void ignored) {            
             visit(t.tvars);
             visit(t.qtype);
             return null;
@@ -559,14 +572,16 @@
 
         @Override
         public Void visitTypeVar(TypeVar t, Void ignored) {
-            if (indexOf(t, WhereClauseKind.TYPEVAR) == -1) {
+            if ((t.tsym.flags() & PARTIAL) == 0 &&
+                    indexOf(t, WhereClauseKind.TYPEVAR) == -1) {
                 //access the bound type and skip error types
                 Type bound = t.bound;
                 while ((bound instanceof ErrorType))
                     bound = ((ErrorType)bound).getOriginalType();
                 //retrieve the bound list - if the type variable
                 //has not been attributed the bound is not set
-                List<Type> bounds = bound != null ?
+                List<Type> bounds = bound != null &&
+                        (bound.tag == CLASS || bound.tag == TYPEVAR) ?
                     types.getBounds(t) :
                     List.<Type>nil();
 
--- a/src/share/classes/javax/lang/model/util/Types.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/src/share/classes/javax/lang/model/util/Types.java	Fri Jul 23 09:52:55 2010 +0100
@@ -97,24 +97,9 @@
      * @throws IllegalArgumentException if given an executable or package type
      * @jls3 5.2 Assignment Conversion
      */
-    @Deprecated
     boolean isAssignable(TypeMirror t1, TypeMirror t2);
 
     /**
-     * Tests whether one type is assignable to another in the context of
-     * the type 'site'
-     *
-     * @param site the context used to perform accessibility check
-     * @param t1  the first type
-     * @param t2  the second type
-     * @return {@code true} if and only if the first type is assignable
-     *          to the second
-     * @throws IllegalArgumentException if given an executable or package type
-     * @jls3 5.2 Assignment Conversion
-     */
-    boolean isAssignable(TypeMirror site, TypeMirror t1, TypeMirror t2);
-
-    /**
      * Tests whether one type argument <i>contains</i> another.
      *
      * @param t1  the first type
--- a/test/tools/javac/defender/Pos01.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/defender/Pos01.java	Fri Jul 23 09:52:55 2010 +0100
@@ -46,7 +46,7 @@
     public static void main(String[] args) {
        MyList<Integer> l = new MyList<Integer>();
        l.add(1); l.add(2); l.add(3);
-       l.map(#(Integer x)(x * x));
+       l.map(#(Integer x){ x * x });
     }
 
     static <T> List<T> listMapper(List<T> l, Mapper<T> mapper) {
--- a/test/tools/javac/lambda/BadAccess.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/BadAccess.java	Fri Jul 23 09:52:55 2010 +0100
@@ -34,15 +34,19 @@
     int i;
     static int I;
 
+    interface SAM {
+        int m();
+    }
+
     static void test1() {
         int l = 0;
         final int L = 0;
-        Object o = #()(i + I + l + L);
+        SAM s = #{ i + I + l + L };
     }
 
     void test2() {
         int l = 0;
         final int L = 0;
-        Object o = #()(i + I + l + L);
+        SAM s = #{ i + I + l + L };
     }
 }
--- a/test/tools/javac/lambda/BadAccess.out	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/BadAccess.out	Fri Jul 23 09:52:55 2010 +0100
@@ -1,4 +1,4 @@
-BadAccess.java:40:24: compiler.err.non-static.cant.be.ref: kindname.variable, i
-BadAccess.java:40:32: compiler.err.local.var.accessed.from.inner.ctx.needs.final: l, (compiler.misc.lambda)
-BadAccess.java:46:32: compiler.err.local.var.accessed.from.inner.ctx.needs.final: l, (compiler.misc.lambda)
+BadAccess.java:44:20: compiler.err.non-static.cant.be.ref: kindname.variable, i
+BadAccess.java:44:28: compiler.err.local.var.accessed.from.inner.ctx.needs.final: l, (compiler.misc.icls)
+BadAccess.java:50:28: compiler.err.local.var.accessed.from.inner.ctx.needs.final: l, (compiler.misc.icls)
 3 errors
--- a/test/tools/javac/lambda/BadConv01.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/BadConv01.java	Fri Jul 23 09:52:55 2010 +0100
@@ -29,7 +29,7 @@
  */
 
 class BadConv01<T> {
-    #int(T) p = #(T x) ( 10 );
+    #int(T) p = #(T x) { 10 };
     interface Bar { <X> int m(X x); }
 
     Bar b = p; // Illegal. Bar has an infinite number of members called m.
--- a/test/tools/javac/lambda/BadConv02.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/BadConv02.java	Fri Jul 23 09:52:55 2010 +0100
@@ -40,7 +40,7 @@
         int m() { return 1; }
     }
 
-    #int() x = #()(42);
+    #int() x = #{ 42 };
     Foo f_1 = new FooImpl();  // Illegal, of course.
     Foo f_2 = x;  // x has no argument for Foo's constructor, so must be illegal like the FooImpl() line.
 }
--- a/test/tools/javac/lambda/BadLambdaCall.java	Mon Jun 28 13:12:44 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2010, 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 test for capture in nested lambda expressions
- * @author  Maurizio Cimadamore
- * @compile/fail/ref=BadLambdaCall.out -XDrawDiagnostics BadLambdaCall.java
- */
-
-class BadLambdaCall {
-    void test(final int a0) {
-        #(){ }.(1); //too many args
-        #(int x){ }.(); //not enough args
-        #(int x){ }.(1,2); //not enough args
-        #(int x){ }.(""); //type mismatch
-    }
-}
--- a/test/tools/javac/lambda/BadLambdaCall.out	Mon Jun 28 13:12:44 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-BadLambdaCall.java:33:16: compiler.err.cant.apply.lambda: compiler.misc.no.args, int
-BadLambdaCall.java:34:21: compiler.err.cant.apply.lambda: int, compiler.misc.no.args
-BadLambdaCall.java:35:21: compiler.err.cant.apply.lambda: int, int,int
-BadLambdaCall.java:36:21: compiler.err.cant.apply.lambda: int, java.lang.String
-4 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/BadLambdaPos.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that lambda is only allowed in plain argument position
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=BadLambdaPos.out -XDrawDiagnostics BadLambdaPos.java
+ */
+
+interface SAM {
+    void m(Integer x);
+}
+
+class Test {
+    void test(Object x) {}
+    SAM test2() { test((Object)#(x){} ); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/BadLambdaPos.out	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,2 @@
+BadLambdaPos.java:37:32: compiler.err.unexpected.lambda
+1 error
--- a/test/tools/javac/lambda/BadReturn.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/BadReturn.java	Fri Jul 23 09:52:55 2010 +0100
@@ -30,8 +30,12 @@
 
 class BadReturn {
 
+    interface SAM {
+        Comparable<?> m();
+    }
+
     static void testNeg1() {
-        Object o = #(){
+        SAM s = # {
             if (true) {
                 return "";
             } else {
@@ -40,16 +44,16 @@
     }
 
     static void testNeg2() {
-        Object o = #(){ return System.out.println(""); };
+        SAM s = # { return System.out.println(""); };
     }
 
     static void testPos() {
-        Comparable<?> o = #() {
+        SAM s = # {
             if (false) {
                 return 10;
             }
             else {
                 return true;
-            }}.();
+            }};
     }
 }
--- a/test/tools/javac/lambda/BadReturn.out	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/BadReturn.out	Fri Jul 23 09:52:55 2010 +0100
@@ -1,4 +1,3 @@
-BadReturn.java:38:42: compiler.err.cant.ret.void.expr
-BadReturn.java:38:17: compiler.err.incompatibles.ret.types.in.lambda: java.lang.String, void
-BadReturn.java:43:50: compiler.err.cant.ret.void.expr
-3 errors
+BadReturn.java:42:42: compiler.err.prob.found.req: (compiler.misc.incompatible.types), void, java.lang.Comparable<?>
+BadReturn.java:47:46: compiler.err.prob.found.req: (compiler.misc.incompatible.types), void, java.lang.Comparable<?>
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/BadTargetType.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that only SAM are allowed as target types for lambda expressions
+ * @author Jan Lahoda
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=BadTargetType.out -XDrawDiagnostics BadTargetType.java
+ */
+
+class BadTargetType {
+
+    static void m1(Object o) {}
+    void m2(Object o) {}
+
+    static Object l1 = #(int pos) {};
+    Object l2 = #(int pos) {};
+
+    {
+        m1(#(int pos) {});
+        m2(#(int pos) {});
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/BadTargetType.out	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,5 @@
+BadTargetType.java:37:24: compiler.err.invalid.target.type.for.lambda.conv: java.lang.Object
+BadTargetType.java:38:17: compiler.err.invalid.target.type.for.lambda.conv: java.lang.Object
+BadTargetType.java:41:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, #void(int), kindname.class, BadTargetType, null
+BadTargetType.java:42:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, #void(int), kindname.class, BadTargetType, null
+4 errors
--- a/test/tools/javac/lambda/FuncType01.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/FuncType01.java	Fri Jul 23 09:52:55 2010 +0100
@@ -37,7 +37,7 @@
     }
 
     public static void main(String[] args) {
-        #boolean() cond = #()( true );
+        #boolean() cond = #{ true };
         assertTrue(cond.());
     }
 }
--- a/test/tools/javac/lambda/LambdaCapture01.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaCapture01.java	Fri Jul 23 09:52:55 2010 +0100
@@ -56,7 +56,7 @@
     //Simple local capture
     void test1() {
         final int N = 1;
-        int x = LambdaCapture01.<Integer,Integer>exec(#(Integer x)(x + N), 3);
+        int x = LambdaCapture01.<Integer,Integer>exec(#(Integer x){x + N}, 3);
         assertTrue(4 == x);
     }
 
@@ -66,7 +66,7 @@
         new Tester() {
             public void test() {
                 final int M = 2;
-                int x = LambdaCapture01.<Integer,Integer>exec(#(Integer x)(x + N + M), 3);
+                int x = LambdaCapture01.<Integer,Integer>exec(#(Integer x){x + N + M}, 3);
                 assertTrue(6 == x);
             }
         }.test();
@@ -78,7 +78,7 @@
         class MyTester implements Tester {
             public void test() {
                 final int M = 2;
-                int x = LambdaCapture01.<Integer,Integer>exec(#(Integer x)(x + N + M), 3);
+                int x = LambdaCapture01.<Integer,Integer>exec(#(Integer x){x + N + M}, 3);
                 assertTrue(6 == x);
             }
         }
@@ -88,9 +88,9 @@
     //access to field from enclosing scope
     void test4() {
         final int N = 4;
-        int x1 = LambdaCapture01.<Integer,Integer>exec(#(Integer x)(x + n + N), 3);
+        int x1 = LambdaCapture01.<Integer,Integer>exec(#(Integer x){x + n + N}, 3);
         assertTrue(12 == x1);
-        int x2 = LambdaCapture01.<Integer,Integer>exec(#(Integer x)(x + LambdaCapture01.this.n + N), 3);
+        int x2 = LambdaCapture01.<Integer,Integer>exec(#(Integer x){x + LambdaCapture01.this.n + N}, 3);
         assertTrue(12 == x2);
     }
 
--- a/test/tools/javac/lambda/LambdaCapture02.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaCapture02.java	Fri Jul 23 09:52:55 2010 +0100
@@ -56,7 +56,7 @@
     //Simple local capture
     void test1() {
         final Integer N = 1;
-        int x = LambdaCapture02.<Integer,Integer>exec(#(Integer x)(x + N), 3);
+        int x = LambdaCapture02.<Integer,Integer>exec(#(Integer x){x + N}, 3);
         assertTrue(4 == x);
     }
 
@@ -66,7 +66,7 @@
         new Tester() {
             public void test() {
                 final Integer M = 2;
-                int x = LambdaCapture02.<Integer,Integer>exec(#(Integer x)(x + N + M), 3);
+                int x = LambdaCapture02.<Integer,Integer>exec(#(Integer x){x + N + M}, 3);
                 assertTrue(6 == x);
             }
         }.test();
@@ -78,7 +78,7 @@
         class MyTester implements Tester {
             public void test() {
                 final Integer M = 2;
-                int x = LambdaCapture02.<Integer,Integer>exec(#(Integer x)(x + N + M), 3);
+                int x = LambdaCapture02.<Integer,Integer>exec(#(Integer x){x + N + M}, 3);
                 assertTrue(6 == x);
             }
         }
@@ -88,9 +88,9 @@
     //access to field from enclosing scope
     void test4() {
         final Integer N = 4;
-        int x1 = LambdaCapture02.<Integer,Integer>exec(#(Integer x)(x + n + N), 3);
+        int x1 = LambdaCapture02.<Integer,Integer>exec(#(Integer x){x + n + N}, 3);
         assertTrue(12 == x1);
-        int x2 = LambdaCapture02.<Integer,Integer>exec(#(Integer x)(x + LambdaCapture02.this.n + N), 3);
+        int x2 = LambdaCapture02.<Integer,Integer>exec(#(Integer x){x + LambdaCapture02.this.n + N}, 3);
         assertTrue(12 == x2);
     }
 
--- a/test/tools/javac/lambda/LambdaCapture03.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaCapture03.java	Fri Jul 23 09:52:55 2010 +0100
@@ -61,7 +61,7 @@
                   class B {
                        void test() {
                            final Integer N3 = 3;
-                           int x = LambdaCapture03.exec(#(Integer x)(x + n1 + n2 + N1 + N2 + N3), 30);
+                           int x = LambdaCapture03.exec(#(Integer x){x + n1 + n2 + N1 + N2 + N3}, 30);
                            assertTrue(x == 66);
                        }
                   }
@@ -80,7 +80,7 @@
                 new Tester() {
                     public void test() {
                         final Integer N3 = 3;
-                        int x = LambdaCapture03.exec(#(Integer x)(x + n1 + n2 + N1 + N2 + N3), 30);
+                        int x = LambdaCapture03.exec(#(Integer x){x + n1 + n2 + N1 + N2 + N3}, 30);
                         assertTrue(x == 66);
                     }
                 }.test();
--- a/test/tools/javac/lambda/LambdaCapture04.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaCapture04.java	Fri Jul 23 09:52:55 2010 +0100
@@ -61,7 +61,7 @@
                   class B {
                        void test() {
                            final Integer N3 = 3;
-                           #(final Integer x)(new Tester() { public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); } }.test()).(30);
+                           exec(#(final Integer x){new Tester() { public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); } }.test()},30);
                        }
                   }
                   new B().test();
@@ -79,11 +79,11 @@
                   class B {
                        void test() {
                            final Integer N3 = 3;
-                           #(final Integer x){
+                           exec(#(final Integer x){
                                class LocTester implements Tester {
                                    public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); }
                                };
-                               new LocTester().test();}.(30);
+                               new LocTester().test();},30);
                        }
                   }
                   new B().test();
@@ -101,7 +101,7 @@
                 new Tester() {
                     public void test() {
                         final Integer N3 = 3;
-                        #(final Integer x)(new Tester() { public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); } }.test()).(30);
+                        exec(#(final Integer x){new Tester() { public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); } }.test()},30);
                     }
                 }.test();
             }
@@ -117,11 +117,11 @@
                 new Tester() {
                     public void test() {
                         final Integer N3 = 3;
-                        #(final Integer x){
+                        exec(#(final Integer x){
                             class LocTester implements Tester {
                                 public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); }
                             };
-                            new LocTester().test();}.(30);
+                            new LocTester().test();},30);
                     }
                 }.test();
             }
--- a/test/tools/javac/lambda/LambdaCapture05.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaCapture05.java	Fri Jul 23 09:52:55 2010 +0100
@@ -38,24 +38,32 @@
             throw new AssertionError();
     }
 
+    interface TU<T, U> {
+        public T foo(U u);
+    }
+
+    public static <T, U> T exec(TU<T, U> lambda, U x) {
+        return lambda.foo(x);
+    }
+
     int i = 40;
 
     void test1(final int a0) {
-        #(final int a1){
-            final Integer x2 = 10; #(final int a2) {
+        exec(#(final Integer a1){
+            final Integer x2 = 10; exec(#(final Integer a2) {
                 final Integer x3 = 20;
-                #(final int a3)(assertTrue(106 == (a0 + a1 + a2 + a3 + x2 + x3 + i))).(3);
-            }.(2);
-        }.(1);
+                exec(#(final Integer a3){assertTrue(106 == (a0 + a1 + a2 + a3 + x2 + x3 + i))},3);
+            },2);
+        },1);
     }
 
     static void test2(final int a0) {
-        #(final int a1){
-            final Integer x2 = 10; #(final int a2) {
+        exec(#(final Integer a1){
+            final Integer x2 = 10; exec(#(final Integer a2) {
                 final Integer x3 = 20;
-                #(final int a3)(assertTrue(66 == (a0 + a1 + a2 + a3 + x2 + x3))).(3);
-            }.(2);
-        }.(1);
+                exec(#(final Integer a3){assertTrue(66 == (a0 + a1 + a2 + a3 + x2 + x3))}, 3);
+            }, 2);
+        }, 1);
     }
 
     public static void main(String[] args) {
--- a/test/tools/javac/lambda/LambdaConv01.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaConv01.java	Fri Jul 23 09:52:55 2010 +0100
@@ -61,17 +61,17 @@
 
     static {
         //Assignment conversion:
-        VoidToInt f1 = #()(3);
+        VoidToInt f1 = #{3};
         assertTrue(3 == f1.foo());
         //Covariant returns:
-        TU<Number, Integer> f2 = #(Integer x)(x);
+        TU<Number, Integer> f2 = #(Integer x){x};
         assertTrue(3 == f2.foo(3));
         //Method resolution with boxing:
-        int x = LambdaConv01.<Integer,Integer>exec(#(Integer x)(x), 3);
+        int x = LambdaConv01.<Integer,Integer>exec(#(Integer x){x}, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            LambdaConv01.<Integer,Object>exec(#(Object x)(x.hashCode()), null);
+            LambdaConv01.<Integer,Object>exec(#(Object x){x.hashCode()}, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
@@ -80,17 +80,17 @@
 
     {
         //Assignment conversion:
-        VoidToInt f1 = #()(3);
+        VoidToInt f1 = #{3};
         assertTrue(3 == f1.foo());
         //Covariant returns:
-        TU<Number, Integer> f2 = #(Integer x)(x);
+        TU<Number, Integer> f2 = #(Integer x){x};
         assertTrue(3 == f2.foo(3));
         //Method resolution with boxing:
-        int x = LambdaConv01.<Integer,Integer>exec(#(Integer x)(x), 3);
+        int x = LambdaConv01.<Integer,Integer>exec(#(Integer x){x}, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            LambdaConv01.<Integer,Object>exec(#(Object x)(x.hashCode()), null);
+            LambdaConv01.<Integer,Object>exec(#(Object x){x.hashCode()}, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
@@ -99,17 +99,17 @@
 
     public static void test1() {
         //Assignment conversion:
-        VoidToInt f1 = #()(3);
+        VoidToInt f1 = #{3};
         assertTrue(3 == f1.foo());
         //Covariant returns:
-        TU<Number, Integer> f2 = #(Integer x)(x);
+        TU<Number, Integer> f2 = #(Integer x){x};
         assertTrue(3 == f2.foo(3));
         //Method resolution with boxing:
-        int x = LambdaConv01.<Integer,Integer>exec(#(Integer x)(x), 3);
+        int x = LambdaConv01.<Integer,Integer>exec(#(Integer x){x}, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            LambdaConv01.<Integer,Object>exec(#(Object x)(x.hashCode()), null);
+            LambdaConv01.<Integer,Object>exec(#(Object x){x.hashCode()}, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
@@ -118,17 +118,17 @@
 
     public void test2() {
         //Assignment conversion:
-        VoidToInt f1 = #()(3);
+        VoidToInt f1 = #{3};
         assertTrue(3 == f1.foo());
         //Covariant returns:
-        TU<Number, Integer> f2 = #(Integer x)(x);
+        TU<Number, Integer> f2 = #(Integer x){x};
         assertTrue(3 == f2.foo(3));
         //Method resolution with boxing:
-        int x = LambdaConv01.<Integer,Integer>exec(#(Integer x)(x), 3);
+        int x = LambdaConv01.<Integer,Integer>exec(#(Integer x){x}, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            LambdaConv01.<Integer,Object>exec(#(Object x)(x.hashCode()), null);
+            LambdaConv01.<Integer,Object>exec(#(Object x){x.hashCode()}, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
--- a/test/tools/javac/lambda/LambdaConv02.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaConv02.java	Fri Jul 23 09:52:55 2010 +0100
@@ -23,32 +23,28 @@
 
 /*
  * @test
- * @summary basic test for lambda conversion and function types
+ * @summary lambda conversion to abstract class should check that enclosing instance
+ *          of target type is in scope
  * @author  Maurizio Cimadamore
- * @compile -XDallowFunctionTypes LambdaConv02.java
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles LambdaConv02
+ * @compile/fail/ref=LambdaConv02.out -XDrawDiagnostics LambdaConv02.java
  */
 
 public class LambdaConv02 {
 
-    interface A { void f(int i1, int i2, int i3) throws Exception; }
-    interface B { void f(int i1, int i2, int i3); }
-    interface C extends A, B {}
+    abstract class SAM { //this needs an enclosing instances of type LambdaConv02
+        abstract void m();
+    }
 
-    static int assertionCount = 0;
+    static void test1(SAM s) {}
+    void test2(SAM s) {}
 
-    static void assertTrue(boolean cond) {
-        assertionCount++;
-        if (!cond)
-            throw new AssertionError();
+    static {
+        SAM s1 = #(){}; //error - no encl instance in scope
+        test1(#(){}); //error - no encl instance in scope
     }
-    public static void main(String[] args) throws Exception {
-        #void(int,int,int)(throws Exception) lambda = #(int i1, int i2, int i3) {
-            assertTrue(i1 + i2 == i3); };
-        lambda.(1,2,3);
-        C foo1 = lambda;
-        foo1.f(3,4,7);
 
-        assertTrue(assertionCount == 2);
+    {
+        SAM s2 = #(){}; //ok
+        test2(#(){}); //ok
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaConv02.out	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,3 @@
+LambdaConv02.java:42:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.encl.instance.for.lambda.conv.target.must.be.in.scope: m, kindname.class, LambdaConv02.SAM, LambdaConv02)), #void(), LambdaConv02.SAM
+LambdaConv02.java:43:9: compiler.err.cant.apply.symbol: kindname.method, test1, LambdaConv02.SAM, #void(), kindname.class, LambdaConv02, null
+2 errors
--- a/test/tools/javac/lambda/LambdaConv03.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaConv03.java	Fri Jul 23 09:52:55 2010 +0100
@@ -51,14 +51,14 @@
         //void
         exec(#(Integer x){ assertTrue(x == 3); }, 3);
         //Covariant returns:
-        int i = exec(#(Integer x)(x), 3);
+        int i = exec(#(Integer x){return x;}, 3);
         assertTrue(3 == i);
         //Method resolution with boxing:
-        int x = exec(#(Integer x)(x), 3);
+        int x = exec(#(Integer x){return x;}, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            exec(#(Object x)(x.hashCode()), null);
+            exec(#(Object x){return x.hashCode();}, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
@@ -69,14 +69,14 @@
         //void
         exec(#(Integer x){ assertTrue(x == 3); }, 3);
         //Covariant returns:
-        int i = exec(#(Integer x)(x), 3);
+        int i = exec(#(Integer x){return x;}, 3);
         assertTrue(3 == i);
         //Method resolution with boxing:
-        int x = exec(#(Integer x)(x), 3);
+        int x = exec(#(Integer x){return x;}, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            exec(#(Object x)(x.hashCode()), null);
+            exec(#(Object x){return x.hashCode();}, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
@@ -87,14 +87,14 @@
         //void
         exec(#(Integer x){ assertTrue(x == 3); }, 3);
         //Covariant returns:
-        int i = exec(#(Integer x)(x), 3);
+        int i = exec(#(Integer x){return x;}, 3);
         assertTrue(3 == i);
         //Method resolution with boxing:
-        int x = exec(#(Integer x)(x), 3);
+        int x = exec(#(Integer x){return x;}, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            exec(#(Object x)(x.hashCode()), null);
+            exec(#(Object x){return x.hashCode();}, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
@@ -105,14 +105,14 @@
         //void
         exec(#(Integer x){ assertTrue(x == 3); }, 3);
         //Covariant returns:
-        int i = exec(#(Integer x)(x), 3);
+        int i = exec(#(Integer x){return x;}, 3);
         assertTrue(3 == i);
         //Method resolution with boxing:
-        int x = exec(#(Integer x)(x), 3);
+        int x = exec(#(Integer x){return x;}, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            exec(#(Object x)(x.hashCode()), null);
+            exec(#(Object x){return x.hashCode();}, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
--- a/test/tools/javac/lambda/LambdaConv04.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaConv04.java	Fri Jul 23 09:52:55 2010 +0100
@@ -48,14 +48,14 @@
         //void
         exec(#(Integer x){ assertTrue(x == 3); }, 3);
         //Covariant returns:
-        int i = exec(#(Integer x)(x), 3);
+        int i = exec(#(Integer x){ x }, 3);
         assertTrue(3 == i);
         //Method resolution with boxing:
-        int x = exec(#(Integer x)(x), 3);
+        int x = exec(#(Integer x) { x }, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            exec(#(Object x)(x.hashCode()), null);
+            exec(#(Object x) { x.hashCode() }, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
@@ -66,14 +66,14 @@
         //void
         exec(#(Integer x){ assertTrue(x == 3); }, 3);
         //Covariant returns:
-        int i = exec(#(Integer x)(x), 3);
+        int i = exec(#(Integer x) { x }, 3);
         assertTrue(3 == i);
         //Method resolution with boxing:
-        int x = exec(#(Integer x)(x), 3);
+        int x = exec(#(Integer x) { x }, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            exec(#(Object x)(x.hashCode()), null);
+            exec(#(Object x) { x.hashCode() }, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
@@ -84,14 +84,14 @@
         //void
         exec(#(Integer x){ assertTrue(x == 3); }, 3);
         //Covariant returns:
-        int i = exec(#(Integer x)(x), 3);
+        int i = exec(#(Integer x) { x }, 3);
         assertTrue(3 == i);
         //Method resolution with boxing:
-        int x = exec(#(Integer x)(x), 3);
+        int x = exec(#(Integer x) { x }, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            exec(#(Object x)(x.hashCode()), null);
+            exec(#(Object x) { x.hashCode() }, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
@@ -102,14 +102,14 @@
         //void
         exec(#(Integer x){ assertTrue(x == 3); }, 3);
         //Covariant returns:
-        int i = exec(#(Integer x)(x), 3);
+        int i = exec(#(Integer x) { x }, 3);
         assertTrue(3 == i);
         //Method resolution with boxing:
-        int x = exec(#(Integer x)(x), 3);
+        int x = exec(#(Integer x) { x }, 3);
         assertTrue(3 == x);
         //Runtime exception transparency:
         try {
-            exec(#(Object x)(x.hashCode()), null);
+            exec(#(Object x) { x.hashCode() }, null);
         }
         catch (RuntimeException e) {
             assertTrue(true);
--- a/test/tools/javac/lambda/LambdaConv07.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaConv07.java	Fri Jul 23 09:52:55 2010 +0100
@@ -44,22 +44,22 @@
 
 
     static {
-        SAM s = #(int i)(assertTrue(i == 1));
+        SAM s = #(int i){assertTrue(i == 1)};
         s.foo(1);
     }
 
     {
-        SAM s = #(int i)(assertTrue(i == 2));
+        SAM s = #(int i){assertTrue(i == 2)};
         s.foo(2);
     }
 
     static void test1() {
-        SAM s = #(int i)(assertTrue(i == 3));
+        SAM s = #(int i){assertTrue(i == 3)};
         s.foo(3);
     }
 
     void test2() {
-        SAM s = #(int i)(assertTrue(i == 4));
+        SAM s = #(int i){assertTrue(i == 4)};
         s.foo(4);
     }
 
--- a/test/tools/javac/lambda/LambdaExpr01.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaExpr01.java	Fri Jul 23 09:52:55 2010 +0100
@@ -39,61 +39,93 @@
             throw new AssertionError();
     }
 
+    interface S_int {
+        int m();
+    }
+
+    interface S_Integer {
+        Integer m();
+    }
+
+    interface S_int_int {
+        int m(int i);
+    }
+
+    interface S_Integer_int {
+        int m(Integer i);
+    }
+
+    interface S_int_Integer {
+        Integer m(int i);
+    }
+
+    interface S_Integer_Integer {
+        Integer m(Integer i);
+    }
+
     static {
-        int i1 = #()(3).();
-        assertTrue(3 == i1);
-        Integer i2 = #()(3).();
-        assertTrue(3 == i2);
-        int i3 = #(int x)( x + 1 ).(3);
-        assertTrue(4 == i3);
-        int i4 = #(Number x)(x.intValue()).(new Float(3.0f));
-        assertTrue(3 == i4);
-        Object o = #()(3);
-        assertTrue(o != null);
+        S_int s_i = #{3};
+        assertTrue(3 == s_i.m());
+        S_Integer s_I = #{3};
+        assertTrue(3 == s_I.m());
+        S_int_int s_i_i = #(int x){ x + 1 };
+        assertTrue(4 == s_i_i.m(3));
+        S_int_Integer s_i_I = #(int x){ x + 1 };
+        assertTrue(4 == s_i_I.m(3));
+        S_Integer_int s_I_i = #(Integer x){ x.intValue() + 1 };
+        assertTrue(4 == s_I_i.m(3));
+        S_Integer_Integer s_I_I = #(Integer x){ x.intValue() + 1 };
+        assertTrue(4 == s_I_I.m(3));
     }
 
     {
-        int i1 = #()(3).();
-        assertTrue(3 == i1);
-        Integer i2 = #()(3).();
-        assertTrue(3 == i2);
-        int i3 = #(int x)( x + 1 ).(3);
-        assertTrue(4 == i3);
-        int i4 = #(Number x)(x.intValue()).(new Float(3.0f));
-        assertTrue(3 == i4);
-        Object o = #()(3);
-        assertTrue(o != null);
+        S_int s_i = #{3};
+        assertTrue(3 == s_i.m());
+        S_Integer s_I = #{3};
+        assertTrue(3 == s_I.m());
+        S_int_int s_i_i = #(int x){ x + 1 };
+        assertTrue(4 == s_i_i.m(3));
+        S_int_Integer s_i_I = #(int x){ x + 1 };
+        assertTrue(4 == s_i_I.m(3));
+        S_Integer_int s_I_i = #(Integer x){ x.intValue() + 1 };
+        assertTrue(4 == s_I_i.m(3));
+        S_Integer_Integer s_I_I = #(Integer x){ x.intValue() + 1 };
+        assertTrue(4 == s_I_I.m(3));
     }
 
     static void test1() {
-        int i1 = #()(3).();
-        assertTrue(3 == i1);
-        Integer i2 = #()(3).();
-        assertTrue(3 == i2);
-        int i3 = #(int x)( x + 1 ).(3);
-        assertTrue(4 == i3);
-        int i4 = #(Number x)(x.intValue()).(new Float(3.0f));
-        assertTrue(3 == i4);
-        Object o = #()(3);
-        assertTrue(o != null);
+        S_int s_i = #{3};
+        assertTrue(3 == s_i.m());
+        S_Integer s_I = #{3};
+        assertTrue(3 == s_I.m());
+        S_int_int s_i_i = #(int x){ x + 1 };
+        assertTrue(4 == s_i_i.m(3));
+        S_int_Integer s_i_I = #(int x){ x + 1 };
+        assertTrue(4 == s_i_I.m(3));
+        S_Integer_int s_I_i = #(Integer x){ x.intValue() + 1 };
+        assertTrue(4 == s_I_i.m(3));
+        S_Integer_Integer s_I_I = #(Integer x){ x.intValue() + 1 };
+        assertTrue(4 == s_I_I.m(3));
     }
 
     void test2() {
-        int i1 = #()(3).();
-        assertTrue(3 == i1);
-        Integer i2 = #()(3).();
-        assertTrue(3 == i2);
-        int i3 = #(int x)( x + 1 ).(3);
-        assertTrue(4 == i3);
-        int i4 = #(Number x)(x.intValue()).(new Float(3.0f));
-        assertTrue(3 == i4);
-        Object o = #()(3);
-        assertTrue(o != null);
+        S_int s_i = #{3};
+        assertTrue(3 == s_i.m());
+        S_Integer s_I = #{3};
+        assertTrue(3 == s_I.m());
+        S_int_int s_i_i = #(int x){ x + 1 };
+        assertTrue(4 == s_i_i.m(3));
+        S_int_Integer s_i_I = #(int x){ x + 1 };
+        assertTrue(4 == s_i_I.m(3));
+        S_Integer_int s_I_i = #(Integer x){ x.intValue() + 1 };
+        assertTrue(4 == s_I_i.m(3));
+        S_Integer_Integer s_I_I = #(Integer x){ x.intValue() + 1 };
+        assertTrue(4 == s_I_I.m(3));
     }
 
     public static void main(String[] args) {
         test1();
         new LambdaExpr01().test2();
-        assertTrue(assertionCount == 20);
+        assertTrue(assertionCount == 24);
     }
 }
--- a/test/tools/javac/lambda/LambdaExpr02.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaExpr02.java	Fri Jul 23 09:52:55 2010 +0100
@@ -26,7 +26,7 @@
  * @summary basic test for simple lambda expressions in multiple scopes
  * @author  Brian Goetz
  * @author  Maurizio Cimadamore
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles LambdaExpr02
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles LambdaExpr01
  */
 
 public class LambdaExpr02 {
@@ -39,61 +39,93 @@
             throw new AssertionError();
     }
 
+    interface S_int {
+        int m();
+    }
+
+    interface S_Integer {
+        Integer m();
+    }
+
+    interface S_int_int {
+        int m(int i);
+    }
+
+    interface S_Integer_int {
+        int m(Integer i);
+    }
+
+    interface S_int_Integer {
+        Integer m(int i);
+    }
+
+    interface S_Integer_Integer {
+        Integer m(Integer i);
+    }
+
     static {
-        int i1 = #(){ return 3; }.();
-        assertTrue(3 == i1);
-        Integer i2 = #(){ return 3; }.();
-        assertTrue(3 == i2);
-        int i3 = #(int x){ return x + 1; }.(3);
-        assertTrue(4 == i3);
-        int i4 = #(Number x){ return x.intValue(); }.(new Float(3.0f));
-        assertTrue(3 == i4);
-        Object o = #(){ return 3; };
-        assertTrue(o != null);
+        S_int s_i = #(){ return 3; };
+        assertTrue(3 == s_i.m());
+        S_Integer s_I = #(){ return 3; };
+        assertTrue(3 == s_I.m());
+        S_int_int s_i_i = #(int x){ return x + 1; };
+        assertTrue(4 == s_i_i.m(3));
+        S_int_Integer s_i_I = #(int x){ return x + 1; };
+        assertTrue(4 == s_i_I.m(3));
+        S_Integer_int s_I_i = #(Integer x){ return x.intValue() + 1; };
+        assertTrue(4 == s_I_i.m(3));
+        S_Integer_Integer s_I_I = #(Integer x) { return x.intValue() + 1; };
+        assertTrue(4 == s_I_I.m(3));
     }
 
     {
-        int i1 = #(){ return 3; }.();
-        assertTrue(3 == i1);
-        Integer i2 = #(){ return 3; }.();
-        assertTrue(3 == i2);
-        int i3 = #(int x){ return x + 1; }.(3);
-        assertTrue(4 == i3);
-        int i4 = #(Number x){ return x.intValue(); }.(new Float(3.0f));
-        assertTrue(3 == i4);
-        Object o = #(){ return 3; };
-        assertTrue(o != null);
+        S_int s_i = #(){ return 3; };
+        assertTrue(3 == s_i.m());
+        S_Integer s_I = #(){ return 3; };
+        assertTrue(3 == s_I.m());
+        S_int_int s_i_i = #(int x){ return x + 1; };
+        assertTrue(4 == s_i_i.m(3));
+        S_int_Integer s_i_I = #(int x){ return x + 1; };
+        assertTrue(4 == s_i_I.m(3));
+        S_Integer_int s_I_i = #(Integer x){ return x.intValue() + 1; };
+        assertTrue(4 == s_I_i.m(3));
+        S_Integer_Integer s_I_I = #(Integer x) { return x.intValue() + 1; };
+        assertTrue(4 == s_I_I.m(3));
     }
 
     static void test1() {
-        int i1 = #(){ return 3; }.();
-        assertTrue(3 == i1);
-        Integer i2 = #(){ return 3; }.();
-        assertTrue(3 == i2);
-        int i3 = #(int x){ return x + 1; }.(3);
-        assertTrue(4 == i3);
-        int i4 = #(Number x){ return x.intValue(); }.(new Float(3.0f));
-        assertTrue(3 == i4);
-        Object o = #(){ return 3; };
-        assertTrue(o != null);
+        S_int s_i = #(){ return 3; };
+        assertTrue(3 == s_i.m());
+        S_Integer s_I = #(){ return 3; };
+        assertTrue(3 == s_I.m());
+        S_int_int s_i_i = #(int x){ return x + 1; };
+        assertTrue(4 == s_i_i.m(3));
+        S_int_Integer s_i_I = #(int x){ return x + 1; };
+        assertTrue(4 == s_i_I.m(3));
+        S_Integer_int s_I_i = #(Integer x){ return x.intValue() + 1; };
+        assertTrue(4 == s_I_i.m(3));
+        S_Integer_Integer s_I_I = #(Integer x) { return x.intValue() + 1; };
+        assertTrue(4 == s_I_I.m(3));
     }
 
     void test2() {
-        int i1 = #(){ return 3; }.();
-        assertTrue(3 == i1);
-        Integer i2 = #(){ return 3; }.();
-        assertTrue(3 == i2);
-        int i3 = #(int x){ return x + 1; }.(3);
-        assertTrue(4 == i3);
-        int i4 = #(Number x){ return x.intValue(); }.(new Float(3.0f));
-        assertTrue(3 == i4);
-        Object o = #(){ return 3; };
-        assertTrue(o != null);
+        S_int s_i = #(){ return 3; };
+        assertTrue(3 == s_i.m());
+        S_Integer s_I = #(){ return 3; };
+        assertTrue(3 == s_I.m());
+        S_int_int s_i_i = #(int x){ return x + 1; };
+        assertTrue(4 == s_i_i.m(3));
+        S_int_Integer s_i_I = #(int x){ return x + 1; };
+        assertTrue(4 == s_i_I.m(3));
+        S_Integer_int s_I_i = #(Integer x){ return x.intValue() + 1; };
+        assertTrue(4 == s_I_i.m(3));
+        S_Integer_Integer s_I_I = #(Integer x) { return x.intValue() + 1; };
+        assertTrue(4 == s_I_I.m(3));
     }
 
     public static void main(String[] args) {
         test1();
         new LambdaExpr02().test2();
-        assertTrue(assertionCount == 20);
+        assertTrue(assertionCount == 24);
     }
 }
--- a/test/tools/javac/lambda/LambdaExpr03.java	Mon Jun 28 13:12:44 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2010, 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 parser should be able to disambiguate between function types and lambdas
- * @author  Maurizio Cimadamore
- * @compile -XDallowFunctionTypes LambdaExpr03.java
- */
-
-class LambdaExpr03 {
-    static {
-        #(int x){ }.(1); //lambda call
-        #(int x)(null).(2); //lambda call
-        #int() x; //var
-    }
-}
--- a/test/tools/javac/lambda/LambdaExpr04.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaExpr04.java	Fri Jul 23 09:52:55 2010 +0100
@@ -30,11 +30,15 @@
  */
 
 class LambdaExpr04 {
-    static Object lambda_01 = #(int pos) {};
 
-    static final Object lambda_02 = #(int pos) {};
+    interface SAM {
+        void m(int i);
+    }
+    static SAM lambda_01 = #(int pos) {};
 
-    Object lambda_03 = #(int pos) {};
+    static final SAM lambda_02 = #(int pos) {};
 
-    final Object lambda_04 = #(int pos) {};
+    SAM lambda_03 = #(int pos) {};
+
+    final SAM lambda_04 = #(int pos) {};
 }
--- a/test/tools/javac/lambda/LambdaScope01.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaScope01.java	Fri Jul 23 09:52:55 2010 +0100
@@ -54,13 +54,13 @@
     }
 
     public void test1() {
-        int x = LambdaScope01.<Integer,Integer>exec(#(Integer x)(x * hashCode()), 3);
+        int x = LambdaScope01.<Integer,Integer>exec(#(Integer x){ x * hashCode() }, 3);
         assertTrue(true); //should not throw
     }
 
     public void test2() {
         final int n = 10;
-        int x = LambdaScope01.<Integer,Integer>exec(#(Integer x)(x + n), 3);
+        int x = LambdaScope01.<Integer,Integer>exec(#(Integer x){ x + n }, 3);
         assertTrue(13 == x);
     }
 
--- a/test/tools/javac/lambda/LambdaScope02.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/LambdaScope02.java	Fri Jul 23 09:52:55 2010 +0100
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @summary check that MethodHandle members are accessible as expected
+ * @summary check that Object members are accessible as expected
  * @author  Maurizio Cimadamore
  * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles LambdaScope02
  */
@@ -38,16 +38,24 @@
             throw new AssertionError();
     }
 
+    static abstract class Callable {
+        abstract void call();
+        @Override
+        public String toString() {
+            return "Callable";
+        }
+    }
+
+    static void call(Callable c) { c.call(); }
+
     static void test1() {
-        final String sig = "(java.dyn.MethodHandle)void";
-        #() {assertTrue(this.type().toString().equals(sig));}.();
-        #() {assertTrue(type().toString().equals(sig));}.();
+        call(#() {assertTrue(this.toString().equals("Callable"));});
+        call(#() {assertTrue(toString().equals("Callable"));});
     }
 
     void test2() {
-        final String sig = "(java.dyn.MethodHandle,LambdaScope02)void";
-        #() {assertTrue(this.type().toString().equals(sig));}.();
-        #() {assertTrue(type().toString().equals(sig));}.();
+        call(#() {assertTrue(this.toString().equals("Callable"));});
+        call(#() {assertTrue(toString().equals("Callable"));});
     }
 
     public static void main(String[] args) {
--- a/test/tools/javac/lambda/NakedThis.java	Mon Jun 28 13:12:44 2010 +0100
+++ b/test/tools/javac/lambda/NakedThis.java	Fri Jul 23 09:52:55 2010 +0100
@@ -26,10 +26,19 @@
  * @summary basic test for capture of non-mutable locals
  * @author  Brian Goetz
  * @author  Maurizio Cimadamore
- * @compile/fail/ref=NakedThis.out -XDrawDiagnostics NakedThis.java
+ * @compile -XDrawDiagnostics NakedThis.java
  */
 
 class NakedThis {
-  Object x1 = #(int x)(this);
-  Object x2 = #(int x)(NakedThis.this);
+
+    interface SAM1 {
+        SAM1 m(int x);
+    }
+
+    interface SAM2 {
+        NakedThis m(int x);
+    }
+  
+    SAM1 s1 = #(int x){ this };
+    SAM2 s2 = #(int x){ NakedThis.this };
 }
--- a/test/tools/javac/lambda/NakedThis.out	Mon Jun 28 13:12:44 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-NakedThis.java:33:15: compiler.err.cannot.infer.lambda.return.type
-1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType01.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010, 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 show that method resolution is not NP hard
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java
+ */
+
+class TargetType01 {
+
+    interface Func<A,B> {
+        B call(A a);
+    }
+
+    interface F_I_I extends Func<Integer,Integer> {}
+    interface F_S_S extends Func<String,String> {}
+
+    static Integer M(F_I_I f){ return null; }
+    static String M(F_S_S f){ return null; }
+
+    static {
+        //ambiguity here - the compiler does not try all the combinations!
+        M(#(final x1){return M(#(x2) { return x1 + x2; });});
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType01.out	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,2 @@
+TargetType01.java:45:30: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType02.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2010, 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 overload resolution and target type inference w.r.t. generic methods
+ * @author  Maurizio Cimadamore
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles TargetType02
+ */
+
+public class TargetType02 {
+
+    static int assertionCount = 0;
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    static abstract class S1<X extends Number> {
+        abstract X m(Integer x);
+        public String toString() { assertTrue(true); return super.toString(); }
+    }
+
+    static abstract class S2<X extends String> {
+        abstract X m(Integer x);
+        public String toString() { assertTrue(false); return super.toString(); }
+    }
+
+    static <Z extends Number> void call(S1<Z> s) { s.m(1); }
+    static <Z extends String> void call(S2<Z> s) { s.m(2); }
+
+    public static void main(String[] args) {
+        call(#(i) { toString(); return i; });
+        assertTrue(assertionCount == 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType03.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, 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 overload resolution and target type inference w.r.t. generic methods
+ * @author  Maurizio Cimadamore
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles TargetType03
+ */
+import java.util.*;
+
+public class TargetType03 {
+
+    interface Mapper<X,Y> {
+        Y map(X a);
+    }
+
+    static class MapperList<A> extends ArrayList<A> {
+        public <B> List<B> map(Mapper<A, B> mapper) {
+            ArrayList<B> mappedList = new ArrayList<>();
+            for (A elem : this) {
+                mappedList.add(mapper.map(elem));
+            }
+            return mappedList;
+        };
+    }
+
+    public static void main(String[] args) {
+        MapperList<Integer> numbers = new MapperList<>();
+        numbers.add(1);
+        numbers.add(2);
+        numbers.add(3);
+        numbers.add(4);
+        numbers.add(5);
+        List<Integer> sqNumbers = numbers.map(#(a){ a * a });
+        //check invariants
+        if (numbers.size() != sqNumbers.size()) {
+            throw new AssertionError();
+        }
+        for (int i = 0; i < numbers.size() ; i ++) {
+            if (sqNumbers.get(i) != Math.pow(numbers.get(i), 2)) {
+                throw new AssertionError();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType04.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, 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 target typing in assignment context
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=TargetType04.out -XDrawDiagnostics TargetType04.java
+ */
+class TargetType04 {
+
+    interface S<X extends Number, Y extends Number> {
+       Y m(X x);
+    }
+
+    S<Integer, Integer> s1 = #(i) { return i; }; //ok
+    S<Double, Integer> s2 = #(i) { return i; }; //no
+    S<Integer, Double> s3 = #(i) { return i; }; //no
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType04.out	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,3 @@
+TargetType04.java:37:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: ?, #?(?), TargetType04.S<java.lang.Double,java.lang.Integer>)), #?(?), TargetType04.S<java.lang.Double,java.lang.Integer>
+TargetType04.java:38:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: ?, #?(?), TargetType04.S<java.lang.Integer,java.lang.Double>)), #?(?), TargetType04.S<java.lang.Integer,java.lang.Double>
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType05.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 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 test recursion through SAM type
+ * @author  Maurizio Cimadamore
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles TargetType05
+ */
+public class TargetType05 {
+
+    static int assertionCount = 0;
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    interface Func<A,R> {
+        R call(A a);
+    }
+
+    static int doFactorial(Func<Integer, Integer> fact, int i) {
+        return fact.call(i);
+    }
+
+    public static void main(String[] args) {
+        Func<Integer, Integer> f = #(i) { return i == 1 ? 1 : call(i-1) * i; };
+        assertTrue(f.call(5) == 120);
+        assertTrue(doFactorial(#(i) { return i == 1 ? 1 : call(i-1) * i; }, 5) == 120);
+        assertTrue(assertionCount == 2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType06.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, 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 complex case of target typing
+ * @author  Maurizio Cimadamore
+ * @compile TargetType06.java
+ */
+
+import java.util.List;
+
+class TargetType06 {
+
+    class Foo {
+        Foo getFoo() { return null; }
+    }
+
+    interface Function<A,R> {
+        R invoke(A a);
+    }
+
+    static <B> List<B> map(Function<B, B> function) { return null; }
+
+    void test() {
+        List<Foo> l = map(#(foo){ foo.getFoo() });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/transparency/Neg09.java	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, 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 erroneous recursive throw type-var definitions
+ * @author  Victor Rudometov
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=Neg09.out -XDrawDiagnostics Neg09.java
+ */
+
+class Neg09<throws E extends E> { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/transparency/Neg09.out	Fri Jul 23 09:52:55 2010 +0100
@@ -0,0 +1,2 @@
+Neg09.java:32:30: compiler.err.prob.found.req: (compiler.misc.incompatible.types), E, java.lang.Exception
+1 error