Mon, 17 Jun 2013 20:29:31 -0700
8013789: Compiler should emit bridges in interfaces
Summary: paired with 8015402: Lambda metafactory should not attempt to determine bridge methods
Reviewed-by: vromero
Contributed-by: maurizio.cimadamore@oracle.com
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Mon Jun 17 14:46:01 2013 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Mon Jun 17 20:29:31 2013 -0700 1.3 @@ -33,10 +33,15 @@ 1.4 import java.util.Set; 1.5 import java.util.WeakHashMap; 1.6 1.7 +import javax.tools.JavaFileObject; 1.8 + 1.9 import com.sun.tools.javac.code.Attribute.RetentionPolicy; 1.10 import com.sun.tools.javac.code.Lint.LintCategory; 1.11 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; 1.12 +import com.sun.tools.javac.comp.AttrContext; 1.13 import com.sun.tools.javac.comp.Check; 1.14 +import com.sun.tools.javac.comp.Enter; 1.15 +import com.sun.tools.javac.comp.Env; 1.16 import com.sun.tools.javac.jvm.ClassReader; 1.17 import com.sun.tools.javac.util.*; 1.18 import static com.sun.tools.javac.code.BoundKind.*; 1.19 @@ -83,6 +88,7 @@ 1.20 final boolean allowDefaultMethods; 1.21 final ClassReader reader; 1.22 final Check chk; 1.23 + final Enter enter; 1.24 JCDiagnostic.Factory diags; 1.25 List<Warner> warnStack = List.nil(); 1.26 final Name capturedName; 1.27 @@ -109,6 +115,7 @@ 1.28 allowDefaultMethods = source.allowDefaultMethods(); 1.29 reader = ClassReader.instance(context); 1.30 chk = Check.instance(context); 1.31 + enter = Enter.instance(context); 1.32 capturedName = names.fromString("<captured wildcard>"); 1.33 messages = JavacMessages.instance(context); 1.34 diags = JCDiagnostic.Factory.instance(context); 1.35 @@ -603,6 +610,84 @@ 1.36 return site; 1.37 } 1.38 } 1.39 + 1.40 + /** 1.41 + * Create a symbol for a class that implements a given functional interface 1.42 + * and overrides its functional descriptor. This routine is used for two 1.43 + * main purposes: (i) checking well-formedness of a functional interface; 1.44 + * (ii) perform functional interface bridge calculation. 1.45 + */ 1.46 + public ClassSymbol makeFunctionalInterfaceClass(Env<AttrContext> env, Name name, List<Type> targets, long cflags) { 1.47 + Assert.check(targets.nonEmpty() && isFunctionalInterface(targets.head)); 1.48 + Symbol descSym = findDescriptorSymbol(targets.head.tsym); 1.49 + Type descType = findDescriptorType(targets.head); 1.50 + ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass()); 1.51 + csym.completer = null; 1.52 + csym.members_field = new Scope(csym); 1.53 + MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym); 1.54 + csym.members_field.enter(instDescSym); 1.55 + Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym); 1.56 + ctype.supertype_field = syms.objectType; 1.57 + ctype.interfaces_field = targets; 1.58 + csym.type = ctype; 1.59 + csym.sourcefile = ((ClassSymbol)csym.owner).sourcefile; 1.60 + return csym; 1.61 + } 1.62 + 1.63 + /** 1.64 + * Find the minimal set of methods that are overridden by the functional 1.65 + * descriptor in 'origin'. All returned methods are assumed to have different 1.66 + * erased signatures. 1.67 + */ 1.68 + public List<Symbol> functionalInterfaceBridges(TypeSymbol origin) { 1.69 + Assert.check(isFunctionalInterface(origin)); 1.70 + Symbol descSym = findDescriptorSymbol(origin); 1.71 + CompoundScope members = membersClosure(origin.type, false); 1.72 + ListBuffer<Symbol> overridden = ListBuffer.lb(); 1.73 + outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) { 1.74 + if (m2 == descSym) continue; 1.75 + else if (descSym.overrides(m2, origin, Types.this, false)) { 1.76 + for (Symbol m3 : overridden) { 1.77 + if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) || 1.78 + (m3.overrides(m2, origin, Types.this, false) && 1.79 + (pendingBridges((ClassSymbol)origin, m3.enclClass()) || 1.80 + (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) { 1.81 + continue outer; 1.82 + } 1.83 + } 1.84 + overridden.add(m2); 1.85 + } 1.86 + } 1.87 + return overridden.toList(); 1.88 + } 1.89 + //where 1.90 + private Filter<Symbol> bridgeFilter = new Filter<Symbol>() { 1.91 + public boolean accepts(Symbol t) { 1.92 + return t.kind == Kinds.MTH && 1.93 + t.name != names.init && 1.94 + t.name != names.clinit && 1.95 + (t.flags() & SYNTHETIC) == 0; 1.96 + } 1.97 + }; 1.98 + private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) { 1.99 + //a symbol will be completed from a classfile if (a) symbol has 1.100 + //an associated file object with CLASS kind and (b) the symbol has 1.101 + //not been entered 1.102 + if (origin.classfile != null && 1.103 + origin.classfile.getKind() == JavaFileObject.Kind.CLASS && 1.104 + enter.getEnv(origin) == null) { 1.105 + return false; 1.106 + } 1.107 + if (origin == s) { 1.108 + return true; 1.109 + } 1.110 + for (Type t : interfaces(origin.type)) { 1.111 + if (pendingBridges((ClassSymbol)t.tsym, s)) { 1.112 + return true; 1.113 + } 1.114 + } 1.115 + return false; 1.116 + } 1.117 // </editor-fold> 1.118 1.119 /** 1.120 @@ -2643,6 +2728,7 @@ 1.121 public boolean accepts(Symbol s) { 1.122 return s.kind == Kinds.MTH && 1.123 s.name == msym.name && 1.124 + (s.flags() & SYNTHETIC) == 0 && 1.125 s.isInheritedIn(site.tsym, Types.this) && 1.126 overrideEquivalent(memberType(site, s), memberType(site, msym)); 1.127 }
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Jun 17 14:46:01 2013 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Jun 17 20:29:31 2013 -0700 2.3 @@ -2314,13 +2314,12 @@ 2.4 if (pt() != Type.recoveryType) { 2.5 target = targetChecker.visit(target, that); 2.6 lambdaType = types.findDescriptorType(target); 2.7 - chk.checkFunctionalInterface(that, target); 2.8 } else { 2.9 target = Type.recoveryType; 2.10 lambdaType = fallbackDescriptorType(that); 2.11 } 2.12 2.13 - setFunctionalInfo(that, pt(), lambdaType, target, resultInfo.checkContext.inferenceContext()); 2.14 + setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext); 2.15 2.16 if (lambdaType.hasTag(FORALL)) { 2.17 //lambda expression target desc cannot be a generic method 2.18 @@ -2662,13 +2661,12 @@ 2.19 if (pt() != Type.recoveryType) { 2.20 target = targetChecker.visit(pt(), that); 2.21 desc = types.findDescriptorType(target); 2.22 - chk.checkFunctionalInterface(that, target); 2.23 } else { 2.24 target = Type.recoveryType; 2.25 desc = fallbackDescriptorType(that); 2.26 } 2.27 2.28 - setFunctionalInfo(that, pt(), desc, target, resultInfo.checkContext.inferenceContext()); 2.29 + setFunctionalInfo(localEnv, that, pt(), desc, target, resultInfo.checkContext); 2.30 List<Type> argtypes = desc.getParameterTypes(); 2.31 2.32 Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = 2.33 @@ -2870,31 +2868,37 @@ 2.34 * might contain inference variables, we might need to register an hook in the 2.35 * current inference context. 2.36 */ 2.37 - private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, 2.38 - final Type descriptorType, final Type primaryTarget, InferenceContext inferenceContext) { 2.39 - if (inferenceContext.free(descriptorType)) { 2.40 - inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { 2.41 + private void setFunctionalInfo(final Env<AttrContext> env, final JCFunctionalExpression fExpr, 2.42 + final Type pt, final Type descriptorType, final Type primaryTarget, final CheckContext checkContext) { 2.43 + if (checkContext.inferenceContext().free(descriptorType)) { 2.44 + checkContext.inferenceContext().addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { 2.45 public void typesInferred(InferenceContext inferenceContext) { 2.46 - setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), 2.47 - inferenceContext.asInstType(primaryTarget), inferenceContext); 2.48 + setFunctionalInfo(env, fExpr, pt, inferenceContext.asInstType(descriptorType), 2.49 + inferenceContext.asInstType(primaryTarget), checkContext); 2.50 } 2.51 }); 2.52 } else { 2.53 - ListBuffer<TypeSymbol> targets = ListBuffer.lb(); 2.54 + ListBuffer<Type> targets = ListBuffer.lb(); 2.55 if (pt.hasTag(CLASS)) { 2.56 if (pt.isCompound()) { 2.57 - targets.append(primaryTarget.tsym); //this goes first 2.58 + targets.append(types.removeWildcards(primaryTarget)); //this goes first 2.59 for (Type t : ((IntersectionClassType)pt()).interfaces_field) { 2.60 if (t != primaryTarget) { 2.61 - targets.append(t.tsym); 2.62 + targets.append(types.removeWildcards(t)); 2.63 } 2.64 } 2.65 } else { 2.66 - targets.append(pt.tsym); 2.67 + targets.append(types.removeWildcards(primaryTarget)); 2.68 } 2.69 } 2.70 fExpr.targets = targets.toList(); 2.71 - fExpr.descriptorType = descriptorType; 2.72 + if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && 2.73 + pt != Type.recoveryType) { 2.74 + //check that functional interface class is well-formed 2.75 + ClassSymbol csym = types.makeFunctionalInterfaceClass(env, 2.76 + names.empty, List.of(fExpr.targets.head), ABSTRACT); 2.77 + chk.checkImplementations(env.tree, csym, csym); 2.78 + } 2.79 } 2.80 } 2.81 2.82 @@ -4550,9 +4554,6 @@ 2.83 @Override 2.84 public void visitLambda(JCLambda that) { 2.85 super.visitLambda(that); 2.86 - if (that.descriptorType == null) { 2.87 - that.descriptorType = syms.unknownType; 2.88 - } 2.89 if (that.targets == null) { 2.90 that.targets = List.nil(); 2.91 } 2.92 @@ -4564,9 +4565,6 @@ 2.93 if (that.sym == null) { 2.94 that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol); 2.95 } 2.96 - if (that.descriptorType == null) { 2.97 - that.descriptorType = syms.unknownType; 2.98 - } 2.99 if (that.targets == null) { 2.100 that.targets = List.nil(); 2.101 }
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Jun 17 14:46:01 2013 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Jun 17 20:29:31 2013 -0700 3.3 @@ -2267,24 +2267,6 @@ 3.4 c.flags_field |= ACYCLIC; 3.5 } 3.6 3.7 - /** 3.8 - * Check that functional interface methods would make sense when seen 3.9 - * from the perspective of the implementing class 3.10 - */ 3.11 - void checkFunctionalInterface(JCTree tree, Type funcInterface) { 3.12 - ClassType c = new ClassType(Type.noType, List.<Type>nil(), null); 3.13 - ClassSymbol csym = new ClassSymbol(0, names.empty, c, syms.noSymbol); 3.14 - c.interfaces_field = List.of(types.removeWildcards(funcInterface)); 3.15 - c.supertype_field = syms.objectType; 3.16 - c.tsym = csym; 3.17 - csym.members_field = new Scope(csym); 3.18 - Symbol descSym = types.findDescriptorSymbol(funcInterface.tsym); 3.19 - Type descType = types.findDescriptorType(funcInterface); 3.20 - csym.members_field.enter(new MethodSymbol(PUBLIC, descSym.name, descType, csym)); 3.21 - csym.completer = null; 3.22 - checkImplementations(tree, csym, csym); 3.23 - } 3.24 - 3.25 /** Check that all methods which implement some 3.26 * method conform to the method they implement. 3.27 * @param tree The class definition whose members are checked.
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Jun 17 14:46:01 2013 -0700 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Jun 17 20:29:31 2013 -0700 4.3 @@ -100,6 +100,9 @@ 4.4 /** Flag for alternate metafactories indicating the lambda object has multiple targets */ 4.5 public static final int FLAG_MARKERS = 1 << 1; 4.6 4.7 + /** Flag for alternate metafactories indicating the lambda object requires multiple bridges */ 4.8 + public static final int FLAG_BRIDGES = 1 << 2; 4.9 + 4.10 private class KlassInfo { 4.11 4.12 /** 4.13 @@ -321,7 +324,7 @@ 4.14 int refKind = referenceKind(sym); 4.15 4.16 //convert to an invokedynamic call 4.17 - result = makeMetaFactoryIndyCall(tree, context.needsAltMetafactory(), context.isSerializable(), refKind, sym, indy_args); 4.18 + result = makeMetaFactoryIndyCall(context, refKind, sym, indy_args); 4.19 } 4.20 4.21 private JCIdent makeThis(Type type, Symbol owner) { 4.22 @@ -382,7 +385,7 @@ 4.23 4.24 4.25 //build a sam instance using an indy call to the meta-factory 4.26 - result = makeMetaFactoryIndyCall(tree, localContext.needsAltMetafactory(), localContext.isSerializable(), localContext.referenceKind(), refSym, indy_args); 4.27 + result = makeMetaFactoryIndyCall(localContext, localContext.referenceKind(), refSym, indy_args); 4.28 } 4.29 4.30 /** 4.31 @@ -908,10 +911,11 @@ 4.32 /** 4.33 * Generate an indy method call to the meta factory 4.34 */ 4.35 - private JCExpression makeMetaFactoryIndyCall(JCFunctionalExpression tree, boolean needsAltMetafactory, 4.36 - boolean isSerializable, int refKind, Symbol refSym, List<JCExpression> indy_args) { 4.37 + private JCExpression makeMetaFactoryIndyCall(TranslationContext<?> context, 4.38 + int refKind, Symbol refSym, List<JCExpression> indy_args) { 4.39 + JCFunctionalExpression tree = context.tree; 4.40 //determine the static bsm args 4.41 - Type mtype = types.erasure(tree.descriptorType); 4.42 + Type mtype = types.erasure(tree.getDescriptorType(types)); 4.43 MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym); 4.44 List<Object> staticArgs = List.<Object>of( 4.45 new Pool.MethodHandle(ClassFile.REF_invokeInterface, 4.46 @@ -934,25 +938,40 @@ 4.47 List.<Type>nil(), 4.48 syms.methodClass); 4.49 4.50 - Name metafactoryName = needsAltMetafactory ? 4.51 + Name metafactoryName = context.needsAltMetafactory() ? 4.52 names.altMetaFactory : names.metaFactory; 4.53 4.54 - if (needsAltMetafactory) { 4.55 + if (context.needsAltMetafactory()) { 4.56 ListBuffer<Object> markers = ListBuffer.lb(); 4.57 - for (Symbol t : tree.targets.tail) { 4.58 - if (t != syms.serializableType.tsym) { 4.59 - markers.append(t); 4.60 + for (Type t : tree.targets.tail) { 4.61 + if (t.tsym != syms.serializableType.tsym) { 4.62 + markers.append(t.tsym); 4.63 } 4.64 } 4.65 - int flags = isSerializable? FLAG_SERIALIZABLE : 0; 4.66 + int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0; 4.67 boolean hasMarkers = markers.nonEmpty(); 4.68 - flags |= hasMarkers ? FLAG_MARKERS : 0; 4.69 + boolean hasBridges = context.bridges.nonEmpty(); 4.70 + if (hasMarkers) { 4.71 + flags |= FLAG_MARKERS; 4.72 + } 4.73 + if (hasBridges) { 4.74 + flags |= FLAG_BRIDGES; 4.75 + } 4.76 staticArgs = staticArgs.append(flags); 4.77 if (hasMarkers) { 4.78 staticArgs = staticArgs.append(markers.length()); 4.79 staticArgs = staticArgs.appendList(markers.toList()); 4.80 } 4.81 - if (isSerializable) { 4.82 + if (hasBridges) { 4.83 + staticArgs = staticArgs.append(context.bridges.length() - 1); 4.84 + for (Symbol s : context.bridges) { 4.85 + Type s_erasure = s.erasure(types); 4.86 + if (!types.isSameType(s_erasure, samSym.erasure(types))) { 4.87 + staticArgs = staticArgs.append(s.erasure(types)); 4.88 + } 4.89 + } 4.90 + } 4.91 + if (context.isSerializable()) { 4.92 addDeserializationCase(refKind, refSym, tree.type, samSym, 4.93 tree, staticArgs, indyType); 4.94 } 4.95 @@ -1299,7 +1318,6 @@ 4.96 4.97 // Make lambda holding the new-class call 4.98 JCLambda slam = make.Lambda(params, nc); 4.99 - slam.descriptorType = tree.descriptorType; 4.100 slam.targets = tree.targets; 4.101 slam.type = tree.type; 4.102 slam.pos = tree.pos; 4.103 @@ -1634,23 +1652,30 @@ 4.104 /** the enclosing translation context (set for nested lambdas/mref) */ 4.105 TranslationContext<?> prev; 4.106 4.107 + /** list of methods to be bridged by the meta-factory */ 4.108 + List<Symbol> bridges; 4.109 + 4.110 TranslationContext(T tree) { 4.111 this.tree = tree; 4.112 this.owner = owner(); 4.113 this.depth = frameStack.size() - 1; 4.114 this.prev = context(); 4.115 + ClassSymbol csym = 4.116 + types.makeFunctionalInterfaceClass(attrEnv, names.empty, tree.targets, ABSTRACT | INTERFACE); 4.117 + this.bridges = types.functionalInterfaceBridges(csym); 4.118 } 4.119 4.120 /** does this functional expression need to be created using alternate metafactory? */ 4.121 boolean needsAltMetafactory() { 4.122 - return (tree.targets.length() > 1 || 4.123 - isSerializable()); 4.124 + return tree.targets.length() > 1 || 4.125 + isSerializable() || 4.126 + bridges.length() > 1; 4.127 } 4.128 4.129 /** does this functional expression require serialization support? */ 4.130 boolean isSerializable() { 4.131 - for (Symbol target : tree.targets) { 4.132 - if (types.asSuper(target.type, syms.serializableType.tsym) != null) { 4.133 + for (Type target : tree.targets) { 4.134 + if (types.asSuper(target, syms.serializableType.tsym) != null) { 4.135 return true; 4.136 } 4.137 } 4.138 @@ -1833,7 +1858,7 @@ 4.139 } 4.140 4.141 Type generatedLambdaSig() { 4.142 - return types.erasure(tree.descriptorType); 4.143 + return types.erasure(tree.getDescriptorType(types)); 4.144 } 4.145 } 4.146 4.147 @@ -1909,7 +1934,7 @@ 4.148 } 4.149 4.150 Type bridgedRefSig() { 4.151 - return types.erasure(types.findDescriptorSymbol(tree.targets.head).type); 4.152 + return types.erasure(types.findDescriptorSymbol(tree.targets.head.tsym).type); 4.153 } 4.154 } 4.155 }
5.1 --- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Mon Jun 17 14:46:01 2013 -0700 5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Mon Jun 17 20:29:31 2013 -0700 5.3 @@ -68,6 +68,7 @@ 5.4 private TreeMaker make; 5.5 private Enter enter; 5.6 private boolean allowEnums; 5.7 + private boolean allowInterfaceBridges; 5.8 private Types types; 5.9 private final Resolve resolve; 5.10 5.11 @@ -91,6 +92,7 @@ 5.12 Source source = Source.instance(context); 5.13 allowEnums = source.allowEnums(); 5.14 addBridges = source.addBridges(); 5.15 + allowInterfaceBridges = source.allowDefaultMethods(); 5.16 types = Types.instance(context); 5.17 make = TreeMaker.instance(context); 5.18 resolve = Resolve.instance(context); 5.19 @@ -252,7 +254,8 @@ 5.20 5.21 // Create a bridge method symbol and a bridge definition without a body. 5.22 Type bridgeType = meth.erasure(types); 5.23 - long flags = impl.flags() & AccessFlags | SYNTHETIC | BRIDGE; 5.24 + long flags = impl.flags() & AccessFlags | SYNTHETIC | BRIDGE | 5.25 + (origin.isInterface() ? DEFAULT : 0); 5.26 if (hypothetical) flags |= HYPOTHETICAL; 5.27 MethodSymbol bridge = new MethodSymbol(flags, 5.28 meth.name, 5.29 @@ -387,11 +390,12 @@ 5.30 } 5.31 } 5.32 // where 5.33 - Filter<Symbol> overrideBridgeFilter = new Filter<Symbol>() { 5.34 + private Filter<Symbol> overrideBridgeFilter = new Filter<Symbol>() { 5.35 public boolean accepts(Symbol s) { 5.36 return (s.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) != SYNTHETIC; 5.37 } 5.38 }; 5.39 + 5.40 /** 5.41 * @param method The symbol for which a bridge might have to be added 5.42 * @param impl The implementation of method 5.43 @@ -999,8 +1003,9 @@ 5.44 ListBuffer<JCTree> bridges = new ListBuffer<JCTree>(); 5.45 if (false) //see CR: 6996415 5.46 bridges.appendList(addOverrideBridgesIfNeeded(tree, c)); 5.47 - if ((tree.sym.flags() & INTERFACE) == 0) 5.48 - addBridges(tree.pos(), tree.sym, bridges); 5.49 + if (allowInterfaceBridges || (tree.sym.flags() & INTERFACE) == 0) { 5.50 + addBridges(tree.pos(), c, bridges); 5.51 + } 5.52 tree.defs = bridges.toList().prependList(tree.defs); 5.53 } 5.54 tree.type = erasure(tree.type);
6.1 --- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java Mon Jun 17 14:46:01 2013 -0700 6.2 +++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java Mon Jun 17 20:29:31 2013 -0700 6.3 @@ -641,10 +641,12 @@ 6.4 polyKind = PolyKind.POLY; 6.5 } 6.6 6.7 - /** target descriptor inferred for this functional expression. */ 6.8 - public Type descriptorType; 6.9 /** list of target types inferred for this functional expression. */ 6.10 - public List<TypeSymbol> targets; 6.11 + public List<Type> targets; 6.12 + 6.13 + public Type getDescriptorType(Types types) { 6.14 + return types.findDescriptorType(targets.head); 6.15 + } 6.16 } 6.17 6.18 /**
7.1 --- a/test/tools/javac/lambda/lambdaExpression/LambdaTest6.java Mon Jun 17 14:46:01 2013 -0700 7.2 +++ b/test/tools/javac/lambda/lambdaExpression/LambdaTest6.java Mon Jun 17 20:29:31 2013 -0700 7.3 @@ -105,7 +105,7 @@ 7.4 Class returnType = m.getReturnType(); 7.5 assertTrue(types.remove(returnType.getName())); 7.6 } 7.7 - assertTrue(types.isEmpty()); 7.8 + assertTrue(types.size() == 1); //there's a bridge 7.9 } 7.10 7.11
8.1 --- a/test/tools/javac/lambda/methodReference/BridgeMethod.java Mon Jun 17 14:46:01 2013 -0700 8.2 +++ b/test/tools/javac/lambda/methodReference/BridgeMethod.java Mon Jun 17 20:29:31 2013 -0700 8.3 @@ -112,6 +112,6 @@ 8.4 Class<?> returnType = m.getReturnType(); 8.5 assertTrue(types.remove(returnType.getName())); 8.6 } 8.7 - assertTrue(types.isEmpty()); 8.8 + assertTrue(types.size() == 1); //there's a bridge 8.9 } 8.10 }