changeset 1139:b9e08af836ed

Updated functional interface test as per latest spec draft (v0.4) *) Removed Types.SAMResult *) Revised implementation for merging signatures of override-equivalent methods *) Added support for caching result of sam-ness test Updated code-generation support *) Added support for method type constants as static args in indy calls
author mcimadamore
date Wed, 10 Aug 2011 17:48:09 +0100
parents 95ae37c3d0cf
children 6a38e7ad078f
files src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/comp/Infer.java src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java src/share/classes/com/sun/tools/javac/comp/LambdaTranslator.java src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/share/classes/com/sun/tools/javac/resources/compiler.properties test/tools/javac/diags/examples.not-yet.txt test/tools/javac/lambda/BadConv03.out test/tools/javac/lambda/BadConv04.java test/tools/javac/lambda/BadConv04.out test/tools/javac/lambda/BadLambdaPos.out test/tools/javac/lambda/BadTargetType.out test/tools/javac/lambda/LambdaConv09.out test/tools/javac/lambda/LambdaExpr10.out test/tools/javac/lambda/MethodReference04.out test/tools/javac/lambda/TargetType17.out test/tools/javac/lambda/sqe/SAM_types/Helper.java test/tools/javac/lambda/sqe/SAM_types/LambdaTest2_SAM3.java test/tools/javac/lambda/sqe/SAM_types/LambdaTest2_neg1.java test/tools/javac/lambda/sqe/SAM_types/LambdaTest2_neg1.out test/tools/javac/lambda/sqe/SAM_types/NonSAM1.out test/tools/javac/lambda/sqe/SAM_types/NonSAM3.out test/tools/javac/lambda/sqe/lambdaExpression/AbstractClass_neg.out test/tools/javac/lambda/sqe/lambdaExpression/InvalidExpression5.out
diffstat 26 files changed, 396 insertions(+), 326 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Aug 08 13:42:09 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Aug 10 17:48:09 2011 +0100
@@ -86,6 +86,7 @@
     final Check chk;
     List<Warner> warnStack = List.nil();
     final Name capturedName;
+    private final SAMConversionFailure samConversionFailure;
 
     // <editor-fold defaultstate="collapsed" desc="Instantiating">
     public static Types instance(Context context) {
@@ -110,6 +111,8 @@
         capturedName = names.fromString("<captured wildcard>");
         messages = JavacMessages.instance(context);
         Options opts = Options.instance(context);
+        JCDiagnostic.Factory diags = JCDiagnostic.Factory.instance(context);
+        samConversionFailure = new SAMConversionFailure(diags);
     }
     // </editor-fold>
 
@@ -340,255 +343,250 @@
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="findSam">
-
-    /**
-     * Search for a target method that is suitable for lambda conversion.
-     *
-     * @param t the type in which the target method is to be searched
-     * @return a SAMResult instance
-     */
-    public SAMResult findSAM(Type t) {
-        if (!t.tsym.isInterface()) {
-            //t must be an abstract class or an interface
-            return new SAMResult(t, "target.for.lambda.conv.must.be.interface");
+    
+    public static class SAMConversionFailure extends RuntimeException {
+        private static final long serialVersionUID = 0;
+
+        JCDiagnostic diagnostic;
+        JCDiagnostic.Factory diags;
+
+        SAMConversionFailure(JCDiagnostic.Factory diags) {
+            this.diagnostic = null;
+            this.diags = diags;
         }
-        else if (t.tsym.kind != Kinds.TYP || (t.tsym.flags() & ABSTRACT) == 0) {
-            //t must be an abstract class or an interface
-            return new SAMResult(t, "target.for.lambda.conv.must.be.abstract");
+        SAMConversionFailure setMessage() {
+            this.diagnostic = null;
+            return this;
+        }
+        SAMConversionFailure setMessage(String key) {
+            this.diagnostic = key != null ? diags.fragment(key) : null;
+            return this;
+        }
+        SAMConversionFailure setMessage(String key, Object... args) {
+            this.diagnostic = key != null ? diags.fragment(key, args) : null;
+            return this;
+        }
+        SAMConversionFailure setMessage(JCDiagnostic diag) {
+            this.diagnostic = diag;
+            return this;
+        }
+
+        public JCDiagnostic getDiagnostic() {
+            return diagnostic;
+        }
+    }
+    
+    class DescriptorCache {
+
+        private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<TypeSymbol, Entry>();
+
+        class Entry {
+            final MethodSymbol cachedDesc;
+            final int prevMark;
+
+            public Entry(MethodSymbol cachedDesc,
+                    int prevMark) {
+                this.cachedDesc = cachedDesc;
+                this.prevMark = prevMark;
+            }
+
+            boolean matches(int mark) {
+                return  this.prevMark == mark;
+            }
+        }
+
+        MethodSymbol get(TypeSymbol origin) throws SAMConversionFailure {
+            Entry e = _map.get(origin);
+            CompoundScope members = membersClosure(origin.type, false);
+            if (e == null ||
+                    !e.matches(members.getMark())) {
+                MethodSymbol desc = findDescriptorInternal(origin, members);
+                _map.put(origin, new Entry(desc, members.getMark()));
+                return desc;
+            }
+            else {
+                return e.cachedDesc;
+            }
         }
         
-        ListBuffer<Symbol> abstracts = ListBuffer.lb();
-        int count = findSAM(t, t, abstracts, ListBuffer.<Type>lb());
-        if (abstracts.size() == 0) {
-            //t must define a suitable non-generic method
-            return new SAMResult(t, "no.target.method.for.lambda.conv");
-        } else if (abstracts.size() != count) {
-            //the target method(s) should be the only abstract members of t
-            return new SAMResult(t, "multiple.targets.for.lambda.conv");
-        } else {
-            return new SAMResult(t, abstracts.toList());
-        }
-    }    
-    //where
-    private int findSAM(Type site, Type t, ListBuffer<Symbol> buf, ListBuffer<Type> seenTypes) {
-        int count = 0;
-        if (t == Type.noType || seenTypes.contains(t)) return count;
-        seenTypes.append(t);
-        for (Scope.Entry e = t.tsym.members().elems ; e != null ; e = e.sibling) {
-            if (e.sym != null && 
-                    e.sym.kind == Kinds.MTH &&
-                    (e.sym.flags() & ABSTRACT) != 0 &&
-                    (e.sym.flags() & DEFENDER) == 0 &&
-                    !overridesObjectMethod(e.sym, t.tsym)) {
-                MethodSymbol msym = (MethodSymbol)e.sym;
-                Symbol impl = msym.implementation(site.tsym, this, false);
-                if (impl == null || (impl.flags() & ABSTRACT) != 0) {
-                    count++;
-                    Type mtype = memberType(site, msym);
-                    if (buf.isEmpty() ||
-                            (msym.name == buf.first().name &&
-                            overrideEquivalent(mtype, memberType(site, buf.first())))) {
-                        buf.append(e.sym);
+        class DescriptorFilter implements Filter<Symbol> {
+            
+            TypeSymbol origin;
+
+            DescriptorFilter(TypeSymbol origin) {
+                this.origin = origin;
+            }
+        
+            @Override
+            public boolean accepts(Symbol sym) {
+                    return sym.kind == Kinds.MTH &&
+                            (sym.flags() & ABSTRACT) != 0 &&
+                            (sym.flags() & DEFENDER) == 0 &&
+                            !overridesObjectMethod(sym) &&
+                            notOverridden(sym);
+            }
+                    
+            private boolean overridesObjectMethod(Symbol msym) {
+                for (Scope.Entry e = syms.objectType.tsym.members().lookup(msym.name) ; e.scope != null ; e = e.next()) {
+                    if (msym.overrides(e.sym, origin, Types.this, true)) {
+                        return true;
                     }
                 }
+                return false;
+            }
+            
+            private boolean notOverridden(Symbol msym) {
+                Symbol impl = ((MethodSymbol)msym).implementation(origin, Types.this, false);
+                return impl == null || (impl.flags() & ABSTRACT) != 0;
+            }
+        };
+        
+        public MethodSymbol findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws SAMConversionFailure {
+            if (!origin.isInterface()) {
+                //t must be an abstract class or an interface
+                throw samConversionFailure.setMessage("target.for.lambda.conv.must.be.interface");
+            }
+
+            ListBuffer<Symbol> abstracts = ListBuffer.lb();
+            int count = 0;
+            for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) {
+                count++;
+                Type mtype = memberType(origin.type, sym);
+                if (abstracts.isEmpty() ||
+                        (sym.name == abstracts.first().name &&
+                        overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) {
+                    abstracts.append(sym);
+                }
+            }
+            if (abstracts.isEmpty()) {
+                //t must define a suitable non-generic method
+                throw samConversionFailure.setMessage("no.target.method.for.lambda.conv", Kinds.kindName(origin), origin);
+            } else if (abstracts.size() != count) {
+                //the target method(s) should be the only abstract members of t
+                throw samConversionFailure.setMessage("incompatible.targets.for.lambda.conv", Kinds.kindName(origin), origin);
+            } else if (abstracts.size() == 1) {
+                if (abstracts.first().type.isParameterized()) {
+                    throw samConversionFailure.setMessage("invalid.generic.target.for.lambda.conv",
+                                                          abstracts.first(),
+                                                          Kinds.kindName(origin),
+                                                          origin);
+                } else {
+                    return (MethodSymbol)abstracts.first();
+                }
+            } else { // size > 1
+                for (Symbol msym : abstracts) {
+                    if (msym.type.isParameterized()) {
+                        throw samConversionFailure.setMessage("invalid.generic.target.for.lambda.conv",
+                                                              abstracts.first(),
+                                                              Kinds.kindName(origin),
+                                                              origin);
+                    }
+                }
+                MethodType mtype = mergeDescriptors(origin, abstracts.toList());
+                if (mtype == null) {
+                    //we can get here if the SAM class is ill-formed
+                    throw samConversionFailure.setMessage("incompatible.targets.for.lambda.conv", Kinds.kindName(origin), origin);
+                }
+                return new MethodSymbol(abstracts.first().flags(), abstracts.first().name, mtype, origin);
             }
         }
-        count += findSAM(site, supertype(t), buf, seenTypes);
-        for (Type i : interfaces(t)) {
-            count += findSAM(site, i, buf, seenTypes);
-        }
-        return count;
-    }
-    //where
-    private boolean overridesObjectMethod(Symbol msym, TypeSymbol tsym) {
-        for (Scope.Entry e = syms.objectType.tsym.members().lookup(msym.name) ; e.scope != null ; e = e.next()) {
-            if (msym.overrides(e.sym, tsym, this, true)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * This class is used to store the result of a SAM lookup. Usually a lookup
-     * ends up in finding a list of suitable, override-equivalent method symbols.
-     * SAMResult provides functionalities in order to instantiate the type of the
-     * target method of a SAM conversion (if such unique type exists), as well
-     * as to retrieve the accessibility flags and the name associated with such
-     * method. If no such method exists, SAMResult stores detailed info about
-     * what went wrong so that this info can be encapsulated in a richer compiler
-     * diagnostic.
-     */
-    public class SAMResult {
-        Type samType;
-        Type targetType;
-        List<Symbol> methodSyms;
-        String errKey;
-        Object[] args;
-
-        public SAMResult(Type samType, String errKey, Object... args) {
-           this(samType, List.<Symbol>nil(), errKey);
-           targetType = syms.errType;
-           setDiagnostic(errKey, args);
-        }
-
-        public SAMResult(Type samType, List<Symbol> methodSyms) {
-            this(samType, methodSyms, null);
-        }
-
-        private SAMResult(Type samType, List<Symbol> methodSyms, String errKey, Object... args) {
-            this.samType = samType;
-            this.methodSyms = methodSyms;
-            setDiagnostic(errKey, args);
-        }
-
+        
         /**
-         * Get the name of the target method
-         *
-         * @return the name of the target method
+         * Compute a synthetic type for the target SAM descriptor given a list
+         * of override-equivalent methods in the SAM type. The resulting method
+         * type is a method type that is override-equivalent and return-type
+         * substitutable with each method in the original list.
          */
-        public Name getTargetName() {
-            return methodSyms.nonEmpty() ?
-                methodSyms.head.name :
-                null;
-        }
-
-        /**
-         * Get the flags associated with the target method. Accessibility flags
-         * are computed as the 'union' of the accessibility flags associated with
-         * the methods found during a SAM lookup. For instance, if the most-public
-         * modifier found is 'protected' the target method will also have
-         * 'protected' visibility (even in the presence of other override-equivalent
-         * package-private methods).
-         *
-         * @return flags associated with the target method
-         */
-        public long getTargetFlags() {
-            long flags = 0;
-            for (Symbol s : methodSyms) {
-                flags |= s.flags() & ~ABSTRACT;
-            }
-            if ((flags & PUBLIC) != 0) {
-                flags = flags & (~PROTECTED | ~PRIVATE);
-            }
-            else if ((flags & PROTECTED) != 0) {
-                flags = flags & ~PRIVATE;
-            }
-            return flags;
-        }
-
-        /**
-         * Compute the type of the target method seen as a member of the
-         * specified SAM type. If no method has been found during the SAM
-         * lookup, no type can be instantiated. If more than one method has been
-         * found, the resulting type is computed as per lambda spec (return type
-         * is lub() of all return types).
-         *
-         * @return target method type
-         */
-        public Type getTargetType() {
-            if (targetType != null) {
-                return targetType;
-            } else {
-                if (methodSyms.size() == 1) {
-                    if (methodSyms.head.type.isParameterized()) {
-                        setDiagnostic("invalid.generic.target.for.lambda.conv");
-                        return syms.errType;
-                    } else {
-                        return memberType(samType, methodSyms.head);
-                    }
-                }
-                else {
-                    // size > 1
-                    for (Symbol msym : methodSyms) {
-                        if (msym.type.isParameterized()) {
-                            setDiagnostic("invalid.generic.target.for.lambda.conv");
-                            return syms.errType;
-                        }
-                    }
-                    Type resType = chooseSAMDescriptorReturnType();
-                    if (resType == null) {
-                        setDiagnostic("incompatible.targets.in.lambda.conv");
-                        return syms.errType;
-                    }
-                    return new MethodType(chooseSAMDescriptorArgumentTypes(),
-                            resType,
-                            chooseSAMDescriptorThrownTypes(),
-                            syms.methodClass);
-                }
-            }
-        }
-        //WHERE
-            private Type chooseSAMDescriptorReturnType() {
-                Type r = chooseSAMDescriptorReturnType(false);
-                return r != null ? r : chooseSAMDescriptorReturnType(true);
-            }
-            
-            private Type chooseSAMDescriptorReturnType(boolean rawOk) {
+        private MethodType mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) {
+            //merge return types - this is done in two phases: (i) first, the most
+            //specific return type using return type substitutability (as defined in JLS 8.4.5);
+            //(ii) if this fails, a second attempt is made using unchecked subtyping
+            boolean phase2 = false;
+            Type restype = null;
+            while (restype == null) {
                 outer: for (Symbol msym1 : methodSyms) {
-                    Type rt1 = memberType(samType, msym1).getReturnType();
+                    Type mt1 = memberType(origin.type, msym1);
                     for (Symbol msym2 : methodSyms) {
-                        Type rt2 = memberType(samType, msym2).getReturnType();
-                        if ((rt1.isRaw() && !rawOk) || !covariantReturnType(rt1, rt2, Warner.noWarnings)) {
+                        Type mt2 = memberType(origin.type, msym2);
+                        if (phase2 ?
+                                !isSubtypeInternal(mt1.getReturnType(), mt2.getReturnType()) :
+                                !returnTypeSubstitutable(mt1, mt2)) {
                             continue outer;
                         }
                     }
-                    return rt1;
+                    restype = mt1.getReturnType();
                 }
-                return null;
+                if (phase2) {
+                    break;
+                } else {
+                    phase2 = true;
+                }
             }
-
-            private List<Type> chooseSAMDescriptorArgumentTypes() {
-                outer: for (Symbol msym1 : methodSyms) {
-                    Type mt1 = memberType(samType, msym1);
-                    for (Symbol msym2 : methodSyms) {
-                        Type mt2 = memberType(samType, msym2);
-                        if (!isSubSignature(mt1, mt2)) {
-                            continue outer;
-                        }
+            if (restype == null) return null;
+            //merge argument types - simply take the signature that is a
+            //subsigature of all other signatures in the list (as per JLS 8.4.2)
+            List<Type> argtypes = null;
+            outer: for (Symbol msym1 : methodSyms) {
+                Type mt1 = memberType(origin.type, msym1);
+                for (Symbol msym2 : methodSyms) {
+                    Type mt2 = memberType(origin.type, msym2);
+                    if (!isSubSignature(mt1, mt2)) {
+                        continue outer;
                     }
-                    return mt1.getParameterTypes();
                 }
-                return erasure(memberType(samType, methodSyms.head)).getParameterTypes();
+                argtypes = mt1.getParameterTypes();
+                break;
             }
-
-            private List<Type> chooseSAMDescriptorThrownTypes() {
-                List<Type> thrown = null;
-                for (Symbol msym1 : methodSyms) {
-                    Type mt1 = memberType(samType, msym1);
-                    thrown = (thrown == null) ?
-                        mt1.getThrownTypes() :
-                        chk.intersect(mt1.getThrownTypes(), thrown);
-                }
-                return thrown;
+            if (argtypes == null) {
+                argtypes = erasure(memberType(origin.type, methodSyms.head)).getParameterTypes();
             }
-
-        public JCDiagnostic getDiagnostic(JCDiagnostic.Factory diags) {
-            return errKey != null ?
-                diags.fragment(errKey, args) :
-                null;
+            //merge thrown types - form the union of all the thrown types in
+            //all the signatures in the list
+            List<Type> thrown = null;
+            for (Symbol msym1 : methodSyms) {
+                Type mt1 = memberType(origin.type, msym1);
+                thrown = (thrown == null) ?
+                    mt1.getThrownTypes() :
+                    chk.intersect(mt1.getThrownTypes(), thrown);
+            }
+            return new MethodType(argtypes, restype, thrown, syms.methodClass);
         }
-
-        /**
-         * is the SAM class suitable for lambda conversion?
-         *
-         * @return true if an error occurred during the SAM lookup.
-         */
-        public boolean isErroneous() {
-            return getTargetType().isErroneous();
+        
+        boolean isSubtypeInternal(Type s, Type t) {
+            return (s.isPrimitive() && t.isPrimitive()) ?
+                    isSameType(t, s) :
+                    isSubtypeUnchecked(t, s);
         }
-
-        private void setDiagnostic(String key, Object... args) {
-            Object[] args2 = new Object[args.length + 3];
-            args2[0] = getTargetName();
-            args2[1] = Kinds.kindName(samType.tsym);
-            args2[2] = samType;
-            int pos = 3;
-            for (Object o : args) {
-                args2[pos] = o;
-            }
-            errKey = key;
-            this.args = args2;
+    }
+
+    private DescriptorCache descCache = new DescriptorCache();
+
+    /**
+     * Find the method descriptor associated to this class symbol - if the
+     * symbol 'origin' is not a functional interface, an exception is thrown.
+     * The returned descriptor is a method symbol whose owner is 'origin'.
+     */
+    public MethodSymbol findDescriptor(TypeSymbol origin) throws SAMConversionFailure {
+        return descCache.get(origin);
+    }
+    
+    /**
+     * Find the method descriptor associated to this class type - if the
+     * type 'site' is not a functional interface, an exception is thrown.
+     * The returned descriptor is a method type (an instantiated signature of
+     * the method descriptor symbol seen as a member of 'site').
+     */
+    public MethodType findDescriptor(Type site) throws SAMConversionFailure {
+        MethodSymbol msym = findDescriptor(site.tsym);
+        return (MethodType)memberType(site, msym);
+    }
+    
+    public boolean isSam(TypeSymbol tsym) {
+        try {
+            findDescriptor(tsym);
+            return true;
+        } catch (SAMConversionFailure ex) {
+            return false;
         }
     }
     // </editor-fold>
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Aug 08 13:42:09 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Aug 10 17:48:09 2011 +0100
@@ -1840,8 +1840,8 @@
                     identifyLambdaCandidate &&
                     clazztype.tag == CLASS &&
                     lambdaOrReferenceAllowed(tree) &&
-                    !types.findSAM(clazztype).isErroneous()) {
-                Types.SAMResult res = types.findSAM(clazztype);
+                    !types.isSam(clazztype.tsym)) {
+                MethodSymbol samDescriptor = types.findDescriptor(clazztype.tsym);
                 int count = 0;
                 boolean found = false;
                 for (Symbol sym : csym.members().getElements()) {
@@ -1849,9 +1849,9 @@
                             sym.isConstructor()) continue;
                     count++;
                     if (sym.kind != MTH ||
-                            !sym.name.equals(res.getTargetName())) continue;
+                            !sym.name.equals(samDescriptor.name)) continue;
                     Type mtype = types.memberType(clazztype, sym);
-                    if (types.overrideEquivalent(mtype, res.getTargetType())) {
+                    if (types.overrideEquivalent(mtype, types.memberType(clazztype, samDescriptor))) {
                         found = true;
                     }
                 }
@@ -2114,10 +2114,10 @@
     }
     //where
     private MethodSymbol makeLambdaSymbol(Type targetType, Symbol owner) {
-        Types.SAMResult samMethod = types.findSAM(targetType);
-        Name lambdaName = samMethod.getTargetName();
-        long lambdaFlags = samMethod.getTargetFlags() | LAMBDA;
-        Type lambdaType = samMethod.getTargetType();
+        MethodSymbol samDescriptor = types.findDescriptor(targetType.tsym);
+        Name lambdaName = samDescriptor.name;
+        long lambdaFlags = (samDescriptor.flags() | LAMBDA) & ~ABSTRACT ;
+        Type lambdaType = types.memberType(targetType, samDescriptor);
 
         return new MethodSymbol(
                 lambdaFlags,
@@ -2197,7 +2197,7 @@
 
         if (that.needsParameterInference()) {
             //add param type info in the AST
-            List<Type> actuals = types.findSAM(target).getTargetType().getParameterTypes();
+            List<Type> actuals = types.findDescriptor(target).getParameterTypes();
             List<JCVariableDecl> params = that.params;
             while (params.nonEmpty()) {
                 if (actuals.isEmpty()) {
@@ -2611,10 +2611,9 @@
 
             @Override
             Type instantiateSAM(Type to, List<Type> paramTypes) {
-                Types.SAMResult samRes = types.findSAM(to);
-                if (paramTypes != null && !samRes.isErroneous()) {
-                    Type samDesc = samRes.getTargetType();
-                    if (samDesc.getParameterTypes().size() - paramTypes.size() == 1) {
+                if (paramTypes != null && types.isSam(to.tsym)) {
+                    Type samDescriptor = types.findDescriptor(to);
+                    if (samDescriptor.getParameterTypes().size() - paramTypes.size() == 1) {
                         //if number of explicit arguments does not match the
                         //SAM descriptor arity, try to add a synthetic explicit
                         //argument, whose type is the qualifier type
@@ -2631,9 +2630,8 @@
     private Type attribMethodReference(Env<AttrContext> localEnv, InferenceContext inferenceContext, JCMemberReference tree, Type to, boolean allowBoxing) {
         Assert.check(tree.mode == JCMemberReference.ReferenceMode.INVOKE ||
                 tree.mode == JCMemberReference.ReferenceMode.NEW);
-
-        Types.SAMResult samRes = types.findSAM(to);
-        Type samDesc = samRes.getTargetType();
+        
+        Type samDesc = types.findDescriptor(to);
 
         //attrib type-arguments and receiver expr
         List<Type> typeargtypes = List.nil();
@@ -2720,7 +2718,7 @@
      * are compatible with the expected SAM descriptor. This means that (i) parameter
      * types must be identical to those of the target SAM descriptor; (ii) return
      * types must be compatible with the return type of the expected SAM descriptor;
-     * thrown types must be 'included' in the thown types list of the expected
+     * thrown types must be 'included' in the thrown types list of the expected
      * SAM descriptor.
      */
     void checkSAMCompatible(InferenceContext inferenceContext,
@@ -2730,8 +2728,7 @@
                             List<Type> thrownTypes,
                             boolean allowBoxing,
                             boolean completesNormally) {
-        Types.SAMResult samRes = types.findSAM(sam);
-        Type samDescriptor = inferenceContext.asUndetType(samRes.getTargetType(), types);
+        Type samDescriptor = inferenceContext.asUndetType(types.findDescriptor(sam), types);
 
         if (completesNormally &&
                 resultTypes.length() == 0 &&
@@ -2834,7 +2831,7 @@
                 //It is a compile-time error if any class or interface mentioned
                 //by the target SAM descriptor is not accessible - this check is
                 //necessary, as otherwise we might end up with bad generated code
-                Type samDesc = types.findSAM(pt).getTargetType();
+                Type samDesc = types.findDescriptor(pt);
                 //check args accessibility (only if implicit parameter types)
                 if (getParameterTypes() == null) {
                     for (Type arg : samDesc.getParameterTypes()) {
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Aug 08 13:42:09 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Aug 10 17:48:09 2011 +0100
@@ -485,16 +485,14 @@
                     switch (t.getPolyTag()) {
                         case POLY_REFERENCE:
                         case POLY_LAMBDA:
-                            Types.SAMResult samRes = types.findSAM(pt);
-                            if (samRes.isErroneous()) {
+                            try {
+                                types.findDescriptor(pt.tsym);
+                                return t.complete(InferenceContext.emptyContext, pt, true, true);
+                            } catch (Types.SAMConversionFailure ex) {
                                 return typeError(pos,
-                                        diags.fragment("incompatible.types.1", samRes.getDiagnostic(diags)),
+                                        diags.fragment("incompatible.types.1", ex.getDiagnostic()),
                                         t, pt);
-                            }
-                            try {
-                                return t.complete(InferenceContext.emptyContext, pt, true, true);
-                            }
-                            catch (Infer.InferenceException ex) {
+                            } catch (Infer.InferenceException ex) {
                                 return typeError(pos,
                                         diags.fragment("incompatible.types.1", ex.diagnostic),
                                         t, pt);
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Aug 08 13:42:09 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Aug 10 17:48:09 2011 +0100
@@ -652,7 +652,7 @@
                 //checking that explicit param types are equal to the ones
                 //in the SAM descriptors)
                 Type undetSAM = inferenceContext.asUndetType(formalSam, types);
-                Type target = types.findSAM(undetSAM).getTargetType();
+                Type target = types.findDescriptor(undetSAM);
                 if (!types.isSameTypes(target.getParameterTypes(), paramTypes)) {
                     throw invalidInstanceException;
                 }
@@ -755,14 +755,17 @@
                         throw cyclicInferenceException.setMessage("cyclic.lambda.inference");
                     }
                     //is the target a valid SAM?
-                    Types.SAMResult samRes = types.findSAM(pt);
-                    if (samRes.isErroneous()) {
-                        throw new Infer.InvalidInstanceException(diags).setMessage(samRes.getDiagnostic(diags));
+                    MethodType samDescriptor = null;
+                    try {
+                         samDescriptor = types.findDescriptor(pt);
+                    } catch (Types.SAMConversionFailure ex) {
+                        throw new Infer.InvalidInstanceException(diags).setMessage(ex.getDiagnostic());
                     }
+                    
                     //complete the poly type iff either (i) the lambda/mref has
                     //explicit params, or (ii) the formals in the expected SAM desc
                     //do not contain any inference var
-                    List<Type> expectedFormals = samRes.getTargetType().getParameterTypes();
+                    List<Type> expectedFormals = samDescriptor.getParameterTypes();
                     if (t.getParameterTypes() == null &&
                              Type.containsAny(expectedFormals, inferenceContext.inferenceVars())) {
                         if (inferenceContext.mode() == InferenceContext.Mode.BREAK_CYCLES) {
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Aug 08 13:42:09 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Wed Aug 10 17:48:09 2011 +0100
@@ -133,7 +133,7 @@
             }
 
             //prepend synthetic args to translated lambda method signature
-            MethodType lambdaType = (MethodType)types.findSAM(tree.targetType).getTargetType();
+            MethodType lambdaType = types.findDescriptor(tree.targetType);
             localContext.translatedSym.type = lambdaType = types.createMethodTypeWithParameters(lambdaType, TreeInfo.types(syntheticParams.toList()));
 
             //create method declaration hoisting the lambda body
@@ -274,7 +274,7 @@
      * to the symbol associated with the method reference to be bridged.
      */
     Symbol bridgeMemberReference(JCMemberReference tree, ReferenceTranslationContext localContext) {
-        Type samDesc = types.findSAM(tree.targetType).getTargetType();
+        Type samDesc = types.findDescriptor(tree.targetType);
 
         //generate the parameter list for the bridged member reference - the
         //bridge signature will match the signature of the target sam descriptor
@@ -809,7 +809,7 @@
          * descriptor
          */
         boolean needsBridge() {
-            Type samDesc = types.findSAM(tree.targetType).getTargetType();
+            Type samDesc = types.findDescriptor(tree.targetType);
             return !types.hasSameArgs(types.erasure(samDesc), types.erasure(tree.sym.type));
         }
 
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaTranslator.java	Mon Aug 08 13:42:09 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaTranslator.java	Wed Aug 10 17:48:09 2011 +0100
@@ -188,6 +188,8 @@
                 return syms.stringType;
             } else if (arg instanceof Pool.MemberReference) {
                 return syms.methodHandleType;
+            } else if (arg instanceof MethodType) {
+                return syms.methodTypeType;
             } else {
                 Assert.error("bad static arg " + arg.getClass());
                 return null;
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Mon Aug 08 13:42:09 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Aug 10 17:48:09 2011 +0100
@@ -556,6 +556,10 @@
             } else if (value instanceof String) {
                 poolbuf.appendByte(CONSTANT_String);
                 poolbuf.appendChar(pool.put(names.fromString((String)value)));
+            } else if (value instanceof MethodType) {
+                MethodType mtype = (MethodType)value;
+                poolbuf.appendByte(CONSTANT_MethodType);
+                poolbuf.appendChar(pool.put(typeSig(mtype)));
             } else if (value instanceof Type) {
                 Type type = (Type)value;
                 if (type.tag == CLASS) enterInner((ClassSymbol)type.tsym);
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Aug 08 13:42:09 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Aug 10 17:48:09 2011 +0100
@@ -175,23 +175,17 @@
     cannot access thrown type {0} in target SAM descriptor
 
 compiler.misc.no.target.method.for.lambda.conv=\
-    no target method for lambda conversion found in {1} {2}
-
-compiler.misc.incompatible.targets.in.lambda.conv=\
-    no suitable target method for lambda conversion found in {1} {2}
+    no target method for lambda conversion found in {0} {1}
+
+compiler.misc.incompatible.targets.for.lambda.conv=\
+    multiple non-overriding abstract methods found in {0} {1}
 
 compiler.misc.invalid.generic.target.for.lambda.conv=\
     invalid target for lambda conversion: method {0} in {1} {2} is generic
 
-compiler.misc.target.for.lambda.conv.must.be.abstract=\
-    the target type of a lambda conversion must be an abstract class/interface
-
 compiler.misc.target.for.lambda.conv.must.be.interface=\
     the target type of a lambda conversion must be an interface
 
-compiler.misc.multiple.targets.for.lambda.conv=\
-    the target type of a lambda conversion has multiple non-overriding abstract methods
-
 compiler.misc.no.suitable.sam.inst=\
     no instance of type {0} exists so that lambda expression can be type-checked
 
--- a/test/tools/javac/diags/examples.not-yet.txt	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/diags/examples.not-yet.txt	Wed Aug 10 17:48:09 2011 +0100
@@ -138,15 +138,13 @@
 compiler.misc.bad.defender.method                                                #LAMBDA
 compiler.misc.cyclic.lambda.inference                                            #LAMBDA
 compiler.misc.union.type                                                         #LAMBDA
-compiler.misc.incompatible.targets.in.lambda.conv                                #LAMBDA
+compiler.misc.incompatible.targets.for.lambda.conv                               #LAMBDA
 compiler.misc.infer.varargs.argument.mismatch                                    #LAMBDA
 compiler.misc.infer.varargs.argument.mismatch.1                                  #LAMBDA
 compiler.misc.invalid.generic.target.for.lambda.conv                             #LAMBDA
 compiler.misc.lambda                                                             #LAMBDA
-compiler.misc.multiple.targets.for.lambda.conv                                   #LAMBDA
 compiler.misc.no.suitable.sam.inst                                               #LAMBDA
 compiler.misc.no.target.method.for.lambda.conv                                   #LAMBDA
-compiler.misc.target.for.lambda.conv.must.be.abstract                            #LAMBDA
 compiler.misc.target.for.lambda.conv.must.be.interface                           #LAMBDA
 compiler.misc.type.req.class.disjoint                                            #LAMBDA
 compiler.misc.where.description.union                                            #LAMBDA
--- a/test/tools/javac/lambda/BadConv03.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/BadConv03.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,2 +1,2 @@
-BadConv03.java:40:11: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, BadConv03.B)), compiler.misc.type.lambda, BadConv03.B
+BadConv03.java:40:11: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, BadConv03.B)), compiler.misc.type.lambda, BadConv03.B
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/BadConv04.java	Wed Aug 10 17:48:09 2011 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that ill-formed SAM type generates right diagnostic when SAM converted
+ * @compile/fail/ref=BadConv04.out -XDrawDiagnostics BadConv04.java
+ */
+
+class BadConv04 {
+
+    interface I1 {
+        int m();
+    }
+
+    interface I2 {
+        long m();
+    }
+
+    interface SAM extends I1, I2 {}
+
+    SAM s = #{ };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/BadConv04.out	Wed Aug 10 17:48:09 2011 +0100
@@ -0,0 +1,3 @@
+BadConv04.java:40:5: compiler.err.types.incompatible.diff.ret: BadConv04.I2, BadConv04.I1, m()
+BadConv04.java:42:13: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, BadConv04.SAM)), compiler.misc.type.lambda, BadConv04.SAM
+2 errors
--- a/test/tools/javac/lambda/BadLambdaPos.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/BadLambdaPos.out	Wed Aug 10 17:48:09 2011 +0100
@@ -4,6 +4,6 @@
 BadLambdaPos.java:44:18: compiler.err.unexpected.lambda
 BadLambdaPos.java:44:34: compiler.err.unexpected.lambda
 BadLambdaPos.java:45:21: compiler.err.unexpected.lambda
-BadLambdaPos.java:49:22: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
-BadLambdaPos.java:50:28: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+BadLambdaPos.java:49:22: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
+BadLambdaPos.java:50:28: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
 8 errors
--- a/test/tools/javac/lambda/BadTargetType.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/BadTargetType.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,5 +1,5 @@
-BadTargetType.java:37:24: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
-BadTargetType.java:38:17: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
-BadTargetType.java:41:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, java.lang.Object, compiler.misc.type.lambda, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.lambda, java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object))
-BadTargetType.java:42:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, java.lang.Object, compiler.misc.type.lambda, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.lambda, java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object))
+BadTargetType.java:37:24: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
+BadTargetType.java:38:17: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
+BadTargetType.java:41:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, java.lang.Object, compiler.misc.type.lambda, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.lambda, java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.interface))
+BadTargetType.java:42:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, java.lang.Object, compiler.misc.type.lambda, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.lambda, java.lang.Object, (compiler.misc.target.for.lambda.conv.must.be.interface))
 4 errors
--- a/test/tools/javac/lambda/LambdaConv09.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/LambdaConv09.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,5 +1,5 @@
-LambdaConv09.java:63:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, LambdaConv09.Foo1)), compiler.misc.type.lambda, LambdaConv09.Foo1
-LambdaConv09.java:64:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, LambdaConv09.Foo2)), compiler.misc.type.lambda, LambdaConv09.Foo2
-LambdaConv09.java:65:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, LambdaConv09.Foo3)), compiler.misc.type.lambda, LambdaConv09.Foo3
-LambdaConv09.java:67:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, LambdaConv09.Foo5)), compiler.misc.type.lambda, LambdaConv09.Foo5
+LambdaConv09.java:63:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: kindname.interface, LambdaConv09.Foo1)), compiler.misc.type.lambda, LambdaConv09.Foo1
+LambdaConv09.java:64:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: kindname.interface, LambdaConv09.Foo2)), compiler.misc.type.lambda, LambdaConv09.Foo2
+LambdaConv09.java:65:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: kindname.interface, LambdaConv09.Foo3)), compiler.misc.type.lambda, LambdaConv09.Foo3
+LambdaConv09.java:67:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: kindname.interface, LambdaConv09.Foo5)), compiler.misc.type.lambda, LambdaConv09.Foo5
 4 errors
--- a/test/tools/javac/lambda/LambdaExpr10.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/LambdaExpr10.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,9 +1,9 @@
-LambdaExpr10.java:39:28: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
-LambdaExpr10.java:40:32: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
-LambdaExpr10.java:44:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
-LambdaExpr10.java:45:46: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
-LambdaExpr10.java:49:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
-LambdaExpr10.java:50:33: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:39:28: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:40:32: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:44:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:45:46: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:49:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:50:33: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
 LambdaExpr10.java:54:30: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: java.lang.Object)), compiler.misc.type.lambda, LambdaExpr10.Block<?>
 LambdaExpr10.java:55:44: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: java.lang.Object)), compiler.misc.type.lambda, LambdaExpr10.Block<?>
 8 errors
--- a/test/tools/javac/lambda/MethodReference04.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/MethodReference04.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,2 +1,2 @@
-MethodReference04.java:34:16: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.mref, java.lang.Object
+MethodReference04.java:34:16: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.mref, java.lang.Object
 1 error
--- a/test/tools/javac/lambda/TargetType17.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/TargetType17.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,9 +1,9 @@
-TargetType17.java:35:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, byte)), compiler.misc.type.lambda, byte
-TargetType17.java:36:23: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, short)), compiler.misc.type.lambda, short
-TargetType17.java:37:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, int)), compiler.misc.type.lambda, int
-TargetType17.java:38:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, long)), compiler.misc.type.lambda, long
-TargetType17.java:39:23: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, float)), compiler.misc.type.lambda, float
-TargetType17.java:40:25: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, double)), compiler.misc.type.lambda, double
-TargetType17.java:41:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, char)), compiler.misc.type.lambda, char
-TargetType17.java:42:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, boolean)), compiler.misc.type.lambda, boolean
+TargetType17.java:35:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, byte
+TargetType17.java:36:23: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, short
+TargetType17.java:37:19: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, int
+TargetType17.java:38:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, long
+TargetType17.java:39:23: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, float
+TargetType17.java:40:25: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, double
+TargetType17.java:41:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, char
+TargetType17.java:42:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, boolean
 8 errors
--- a/test/tools/javac/lambda/sqe/SAM_types/Helper.java	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/sqe/SAM_types/Helper.java	Wed Aug 10 17:48:09 2011 +0100
@@ -132,9 +132,7 @@
 interface UVW extends U, V, W {}
 
 // type #5:
-// QooRoo<String, Integer, Void> is _not_ a SAM type: different signatures for m
-// QooRoo<Integer, Integer, Void> is a SAM type: same signature for m
-// QooRoo<Integer, Integer, ?> is _not_ a SAM type: signatures in M use T1 and T2
+// Not a SAM because sam-ness depends on instantiation of type-variables
 interface Qoo<T> {void m(T arg);}
 interface Roo<S extends Number> {void m(S arg);}
 interface QooRoo<T1, T2 extends Number, T3> extends Qoo<T1>, Roo<T2> {}
--- a/test/tools/javac/lambda/sqe/SAM_types/LambdaTest2_SAM3.java	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/sqe/SAM_types/LambdaTest2_SAM3.java	Wed Aug 10 17:48:09 2011 +0100
@@ -40,10 +40,6 @@
     public static void main(String[] args) {
         LambdaTest2_SAM3 test = new LambdaTest2_SAM3();
 
-        //type #5:
-        test.methodQooRoo(#{Integer i -> });
-        test.methodQooRoo(#{Integer i -> System.out.println(i)});
-
         //type #7, Not SAM-convertible, through inner class only:
         test.methodFooBar(new FooBar() {
                 public int getAge(Number n) {
@@ -72,12 +68,6 @@
 
     }
 
-    //type #5:
-    void methodQooRoo(QooRoo<Integer, Integer, Void> qooroo) {
-        System.out.println("methodQooRoo(): SAM type interface QooRoo<Integer, Integer, Void> object instantiated: " + qooroo);
-        //qooroo.m(new Integer(100)); // compile error: reference to m is ambiguous, both method m(S) in Roo and method m(T) in Qoo match?
-    }
-
     //type #7: Not SAM type
     void methodFooBar(FooBar fb) {
         System.out.println("methodFooBar(): interface FooBar object instantiated: " + fb);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/sqe/SAM_types/LambdaTest2_neg1.java	Wed Aug 10 17:48:09 2011 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary  This test is for identifying SAM types #5 and instantiating non-SAM types #7 through inner class,
+             see Helper.java for SAM types
+ * @compile/fail/ref=LambdaTest2_neg1.out -XDrawDiagnostics LambdaTest2_neg1.java Helper.java
+ */
+
+public class LambdaTest2_neg1 {
+
+    public static void main(String[] args) {
+        LambdaTest2_neg1 test = new LambdaTest2_neg1();
+        //not convertible - QooRoo is not a SAM
+        test.methodQooRoo(#{Integer i -> });
+    }
+    
+    void methodQooRoo(QooRoo<Integer, Integer, Void> qooroo) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/sqe/SAM_types/LambdaTest2_neg1.out	Wed Aug 10 17:48:09 2011 +0100
@@ -0,0 +1,2 @@
+LambdaTest2_neg1.java:36:13: compiler.err.cant.apply.symbol.1: kindname.method, methodQooRoo, QooRoo<java.lang.Integer,java.lang.Integer,java.lang.Void>, compiler.misc.type.lambda, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists.1: compiler.misc.type.lambda, QooRoo<java.lang.Integer,java.lang.Integer,java.lang.Void>, (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, QooRoo))
+1 error
--- a/test/tools/javac/lambda/sqe/SAM_types/NonSAM1.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/sqe/SAM_types/NonSAM1.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,2 +1,2 @@
-NonSAM1.java:9:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: null, kindname.interface, Planet)), compiler.misc.type.lambda, Planet
+NonSAM1.java:9:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.target.method.for.lambda.conv: kindname.interface, Planet)), compiler.misc.type.lambda, Planet
 1 error
--- a/test/tools/javac/lambda/sqe/SAM_types/NonSAM3.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/sqe/SAM_types/NonSAM3.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,9 +1,9 @@
-NonSAM3.java:13:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, FooBar)), compiler.misc.type.lambda, FooBar
-NonSAM3.java:14:22: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, FooBar)), compiler.misc.type.lambda, FooBar
-NonSAM3.java:15:17: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
-NonSAM3.java:16:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
-NonSAM3.java:17:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
-NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
-NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
-NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.multiple.targets.for.lambda.conv: null, kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:13:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, FooBar)), compiler.misc.type.lambda, FooBar
+NonSAM3.java:14:22: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, FooBar)), compiler.misc.type.lambda, FooBar
+NonSAM3.java:15:17: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:16:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:17:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, DE)), compiler.misc.type.lambda, DE
+NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.incompatible.targets.for.lambda.conv: kindname.interface, DE)), compiler.misc.type.lambda, DE
 8 errors
--- a/test/tools/javac/lambda/sqe/lambdaExpression/AbstractClass_neg.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/sqe/lambdaExpression/AbstractClass_neg.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,2 +1,2 @@
-AbstractClass_neg.java:14:17: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, AbstractClass_neg.SAM)), compiler.misc.type.lambda, AbstractClass_neg.SAM
+AbstractClass_neg.java:14:17: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, AbstractClass_neg.SAM
 1 error
--- a/test/tools/javac/lambda/sqe/lambdaExpression/InvalidExpression5.out	Mon Aug 08 13:42:09 2011 +0100
+++ b/test/tools/javac/lambda/sqe/lambdaExpression/InvalidExpression5.out	Wed Aug 10 17:48:09 2011 +0100
@@ -1,2 +1,2 @@
-InvalidExpression5.java:10:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+InvalidExpression5.java:10:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface)), compiler.misc.type.lambda, java.lang.Object
 1 error