8176714: javac is wrongly assuming that field JCMemberReference.overloadKind has been assigned to
Reviewed-by: mcimadamore
1.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Fri Mar 24 13:04:32 2017 +0000
1.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Fri Mar 24 06:40:28 2017 -0700
1.3 @@ -1,5 +1,5 @@
1.4 /*
1.5 - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
1.6 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.8 *
1.9 * This code is free software; you can redistribute it and/or modify it
1.10 @@ -362,14 +362,9 @@
1.11
1.12 TreeMapper treeMapper = new TreeMapper(context);
1.13 //TODO: to further refine the analysis, try all rewriting combinations
1.14 - LocalCacheContext localCacheContext = argumentAttr.withLocalCacheContext();
1.15 - try {
1.16 - deferredAttr.attribSpeculative(fakeBlock, env, attr.statInfo, treeMapper,
1.17 - t -> new AnalyzeDeferredDiagHandler(context));
1.18 - } finally {
1.19 - localCacheContext.leave();
1.20 - }
1.21 -
1.22 + deferredAttr.attribSpeculative(fakeBlock, env, attr.statInfo, treeMapper,
1.23 + t -> new AnalyzeDeferredDiagHandler(context),
1.24 + argumentAttr.withLocalCacheContext());
1.25 context.treeMap.entrySet().forEach(e -> {
1.26 context.treesToAnalyzer.get(e.getKey())
1.27 .process(e.getKey(), e.getValue(), context.errors.nonEmpty());
2.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java Fri Mar 24 13:04:32 2017 +0000
2.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java Fri Mar 24 06:40:28 2017 -0700
2.3 @@ -1,5 +1,5 @@
2.4 /*
2.5 - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
2.6 + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2.8 *
2.9 * This code is free software; you can redistribute it and/or modify it
2.10 @@ -260,8 +260,10 @@
2.11 public void visitReference(JCMemberReference tree) {
2.12 //perform arity-based check
2.13 Env<AttrContext> localEnv = env.dup(tree);
2.14 - JCExpression exprTree = (JCExpression)deferredAttr.attribSpeculative(tree.getQualifierExpression(), localEnv,
2.15 - attr.memberReferenceQualifierResult(tree));
2.16 + JCExpression exprTree;
2.17 + exprTree = (JCExpression)deferredAttr.attribSpeculative(tree.getQualifierExpression(), localEnv,
2.18 + attr.memberReferenceQualifierResult(tree),
2.19 + withLocalCacheContext());
2.20 JCMemberReference mref2 = new TreeCopier<Void>(attr.make).copy(tree);
2.21 mref2.expr = exprTree;
2.22 Symbol lhsSym = TreeInfo.symbol(exprTree);
2.23 @@ -277,9 +279,9 @@
2.24 (res.flags() & Flags.VARARGS) != 0 ||
2.25 (TreeInfo.isStaticSelector(exprTree, tree.name.table.names) &&
2.26 exprTree.type.isRaw() && !exprTree.type.hasTag(ARRAY))) {
2.27 - tree.overloadKind = JCMemberReference.OverloadKind.OVERLOADED;
2.28 + tree.setOverloadKind(JCMemberReference.OverloadKind.OVERLOADED);
2.29 } else {
2.30 - tree.overloadKind = JCMemberReference.OverloadKind.UNOVERLOADED;
2.31 + tree.setOverloadKind(JCMemberReference.OverloadKind.UNOVERLOADED);
2.32 }
2.33 //return a plain old deferred type for this
2.34 setResult(tree, deferredAttr.new DeferredType(tree, env));
3.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Fri Mar 24 13:04:32 2017 +0000
3.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Fri Mar 24 06:40:28 2017 -0700
3.3 @@ -1525,7 +1525,9 @@
3.4 isBooleanOrNumeric(env, condTree.falsepart);
3.5 case APPLY:
3.6 JCMethodInvocation speculativeMethodTree =
3.7 - (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
3.8 + (JCMethodInvocation)deferredAttr.attribSpeculative(
3.9 + tree, env, unknownExprInfo,
3.10 + argumentAttr.withLocalCacheContext());
3.11 Symbol msym = TreeInfo.symbol(speculativeMethodTree.meth);
3.12 Type receiverType = speculativeMethodTree.meth.hasTag(IDENT) ?
3.13 env.enclClass.type :
3.14 @@ -1536,10 +1538,13 @@
3.15 JCExpression className =
3.16 removeClassParams.translate(((JCNewClass)tree).clazz);
3.17 JCExpression speculativeNewClassTree =
3.18 - (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
3.19 + (JCExpression)deferredAttr.attribSpeculative(
3.20 + className, env, unknownTypeInfo,
3.21 + argumentAttr.withLocalCacheContext());
3.22 return primitiveOrBoxed(speculativeNewClassTree.type);
3.23 default:
3.24 - Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
3.25 + Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo,
3.26 + argumentAttr.withLocalCacheContext()).type;
3.27 return primitiveOrBoxed(speculativeType);
3.28 }
3.29 }
4.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Fri Mar 24 13:04:32 2017 +0000
4.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Fri Mar 24 06:40:28 2017 -0700
4.3 @@ -1,5 +1,5 @@
4.4 /*
4.5 - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
4.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4.8 *
4.9 * This code is free software; you can redistribute it and/or modify it
4.10 @@ -56,6 +56,9 @@
4.11 import java.util.WeakHashMap;
4.12 import java.util.function.Function;
4.13
4.14 +import com.sun.source.tree.MemberReferenceTree;
4.15 +import com.sun.tools.javac.tree.JCTree.JCMemberReference.OverloadKind;
4.16 +
4.17 import static com.sun.tools.javac.code.TypeTag.*;
4.18 import static com.sun.tools.javac.tree.JCTree.Tag.*;
4.19
4.20 @@ -148,6 +151,27 @@
4.21 return super.visitNewClass(node, p);
4.22 }
4.23 }
4.24 +
4.25 + @Override @DefinedBy(Api.COMPILER_TREE)
4.26 + public JCTree visitMemberReference(MemberReferenceTree node, Void p) {
4.27 + JCMemberReference t = (JCMemberReference) node;
4.28 + JCExpression expr = copy(t.expr, p);
4.29 + List<JCExpression> typeargs = copy(t.typeargs, p);
4.30 + /** once the value for overloadKind is determined for a copy, it can be safely forwarded to
4.31 + * the copied tree, we want to profit from that
4.32 + */
4.33 + JCMemberReference result = new JCMemberReference(t.mode, t.name, expr, typeargs) {
4.34 + @Override
4.35 + public void setOverloadKind(OverloadKind overloadKind) {
4.36 + super.setOverloadKind(overloadKind);
4.37 + if (t.getOverloadKind() == null) {
4.38 + t.setOverloadKind(overloadKind);
4.39 + }
4.40 + }
4.41 + };
4.42 + result.pos = t.pos;
4.43 + return result;
4.44 + }
4.45 };
4.46 deferredCopier = new TypeMapping<Void> () {
4.47 @Override
4.48 @@ -446,11 +470,17 @@
4.49 */
4.50 JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
4.51 return attribSpeculative(tree, env, resultInfo, treeCopier,
4.52 - (newTree)->new DeferredAttrDiagHandler(log, newTree));
4.53 + (newTree)->new DeferredAttrDiagHandler(log, newTree), null);
4.54 + }
4.55 +
4.56 + JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, LocalCacheContext localCache) {
4.57 + return attribSpeculative(tree, env, resultInfo, treeCopier,
4.58 + (newTree)->new DeferredAttrDiagHandler(log, newTree), localCache);
4.59 }
4.60
4.61 <Z> JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, TreeCopier<Z> deferredCopier,
4.62 - Function<JCTree, DeferredDiagnosticHandler> diagHandlerCreator) {
4.63 + Function<JCTree, DeferredDiagnosticHandler> diagHandlerCreator,
4.64 + LocalCacheContext localCache) {
4.65 final JCTree newTree = deferredCopier.copy(tree);
4.66 Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner)));
4.67 speculativeEnv.info.isSpeculative = true;
4.68 @@ -461,6 +491,9 @@
4.69 } finally {
4.70 new UnenterScanner(env.toplevel.modle).scan(newTree);
4.71 log.popDiagnosticHandler(deferredDiagnosticHandler);
4.72 + if (localCache != null) {
4.73 + localCache.leave();
4.74 + }
4.75 }
4.76 }
4.77 //where
4.78 @@ -847,6 +880,7 @@
4.79
4.80 @Override
4.81 public void visitReference(JCMemberReference tree) {
4.82 + Assert.checkNonNull(tree.getOverloadKind());
4.83 Check.CheckContext checkContext = resultInfo.checkContext;
4.84 Type pt = resultInfo.pt;
4.85 if (!inferenceContext.inferencevars.contains(pt)) {
4.86 @@ -856,8 +890,9 @@
4.87 checkContext.report(null, ex.getDiagnostic());
4.88 }
4.89 Env<AttrContext> localEnv = env.dup(tree);
4.90 - JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
4.91 - attr.memberReferenceQualifierResult(tree));
4.92 + JCExpression exprTree;
4.93 + exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
4.94 + attr.memberReferenceQualifierResult(tree), argumentAttr.withLocalCacheContext());
4.95 ListBuffer<Type> argtypes = new ListBuffer<>();
4.96 for (Type t : types.findDescriptorType(pt).getParameterTypes()) {
4.97 argtypes.append(Type.noType);
4.98 @@ -1125,7 +1160,7 @@
4.99 Type descType = types.findDescriptorType(pt);
4.100 List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
4.101 if (freeArgVars.nonEmpty() &&
4.102 - tree.overloadKind == JCMemberReference.OverloadKind.OVERLOADED) {
4.103 + tree.getOverloadKind() == JCMemberReference.OverloadKind.OVERLOADED) {
4.104 stuckVars.addAll(freeArgVars);
4.105 depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType()));
4.106 }
4.107 @@ -1190,7 +1225,7 @@
4.108 @Override
4.109 public void visitReference(JCMemberReference tree) {
4.110 super.visitReference(tree);
4.111 - if (tree.overloadKind == JCMemberReference.OverloadKind.OVERLOADED) {
4.112 + if (tree.getOverloadKind() == JCMemberReference.OverloadKind.OVERLOADED) {
4.113 stuck = true;
4.114 }
4.115 }
5.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java Fri Mar 24 13:04:32 2017 +0000
5.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java Fri Mar 24 06:40:28 2017 -0700
5.3 @@ -1,5 +1,5 @@
5.4 /*
5.5 - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
5.6 + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5.8 *
5.9 * This code is free software; you can redistribute it and/or modify it
5.10 @@ -2133,7 +2133,7 @@
5.11 public Type varargsElement;
5.12 public PolyKind refPolyKind;
5.13 public boolean ownerAccessible;
5.14 - public OverloadKind overloadKind;
5.15 + private OverloadKind overloadKind;
5.16 public Type referentType;
5.17
5.18 public enum OverloadKind {
5.19 @@ -2174,7 +2174,7 @@
5.20 }
5.21 }
5.22
5.23 - protected JCMemberReference(ReferenceMode mode, Name name, JCExpression expr, List<JCExpression> typeargs) {
5.24 + public JCMemberReference(ReferenceMode mode, Name name, JCExpression expr, List<JCExpression> typeargs) {
5.25 this.mode = mode;
5.26 this.name = name;
5.27 this.expr = expr;
5.28 @@ -2205,6 +2205,20 @@
5.29 public boolean hasKind(ReferenceKind kind) {
5.30 return this.kind == kind;
5.31 }
5.32 +
5.33 + /**
5.34 + * @return the overloadKind
5.35 + */
5.36 + public OverloadKind getOverloadKind() {
5.37 + return overloadKind;
5.38 + }
5.39 +
5.40 + /**
5.41 + * @param overloadKind the overloadKind to set
5.42 + */
5.43 + public void setOverloadKind(OverloadKind overloadKind) {
5.44 + this.overloadKind = overloadKind;
5.45 + }
5.46 }
5.47
5.48 /**
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/test/tools/javac/T8176714/FieldOverloadKindNotAssignedTest.java Fri Mar 24 06:40:28 2017 -0700
6.3 @@ -0,0 +1,104 @@
6.4 +/*
6.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.7 + *
6.8 + * This code is free software; you can redistribute it and/or modify it
6.9 + * under the terms of the GNU General Public License version 2 only, as
6.10 + * published by the Free Software Foundation.
6.11 + *
6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6.15 + * version 2 for more details (a copy is included in the LICENSE file that
6.16 + * accompanied this code).
6.17 + *
6.18 + * You should have received a copy of the GNU General Public License version
6.19 + * 2 along with this work; if not, write to the Free Software Foundation,
6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6.21 + *
6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6.23 + * or visit www.oracle.com if you need additional information or have any
6.24 + * questions.
6.25 + */
6.26 +
6.27 +/*
6.28 + * @test
6.29 + * @bug 8176714
6.30 + * @summary javac is wrongly assuming that field JCMemberReference.overloadKind has been assigned to
6.31 + * @library /tools/javac/lib
6.32 + * @modules jdk.compiler/com.sun.source.util
6.33 + * jdk.compiler/com.sun.tools.javac.api
6.34 + * jdk.compiler/com.sun.tools.javac.code
6.35 + * jdk.compiler/com.sun.tools.javac.file
6.36 + * jdk.compiler/com.sun.tools.javac.tree
6.37 + * jdk.compiler/com.sun.tools.javac.util
6.38 + * @build DPrinter
6.39 + * @run main FieldOverloadKindNotAssignedTest
6.40 + */
6.41 +
6.42 +import java.net.URI;
6.43 +import java.util.Arrays;
6.44 +
6.45 +import javax.tools.JavaCompiler;
6.46 +import javax.tools.JavaFileObject;
6.47 +import javax.tools.SimpleJavaFileObject;
6.48 +import javax.tools.ToolProvider;
6.49 +
6.50 +import com.sun.source.tree.CompilationUnitTree;
6.51 +import com.sun.source.util.JavacTask;
6.52 +import com.sun.tools.javac.file.JavacFileManager;
6.53 +import com.sun.tools.javac.tree.JCTree;
6.54 +import com.sun.tools.javac.tree.JCTree.JCMemberReference;
6.55 +import com.sun.tools.javac.tree.TreeScanner;
6.56 +import com.sun.tools.javac.util.Assert;
6.57 +import com.sun.tools.javac.util.Context;
6.58 +
6.59 +public class FieldOverloadKindNotAssignedTest {
6.60 + public static void main(String... args) throws Exception {
6.61 + new FieldOverloadKindNotAssignedTest().run();
6.62 + }
6.63 +
6.64 + void run() throws Exception {
6.65 + Context context = new Context();
6.66 + JavacFileManager.preRegister(context);
6.67 + final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
6.68 + JavacTask ct = (JavacTask)tool.getTask(null, null, null, null, null, Arrays.asList(new JavaSource()));
6.69 + Iterable<? extends CompilationUnitTree> elements = ct.parse();
6.70 + ct.analyze();
6.71 + Assert.check(elements.iterator().hasNext());
6.72 + JCTree topLevel = (JCTree)elements.iterator().next();
6.73 + new TreeScanner() {
6.74 + @Override
6.75 + public void visitReference(JCMemberReference tree) {
6.76 + Assert.check(tree.getOverloadKind() != null);
6.77 + }
6.78 + }.scan(topLevel);
6.79 + }
6.80 +
6.81 + static class JavaSource extends SimpleJavaFileObject {
6.82 +
6.83 + String source =
6.84 + "import java.util.function.*;\n" +
6.85 +
6.86 + "class Test {\n" +
6.87 + " void m(Predicate<String> psi) {}\n" +
6.88 + " void m(Function<String, String> fss) {}\n" +
6.89 +
6.90 + " void foo(boolean b) {\n" +
6.91 + " m(b ? s -> false : Test::g);\n" +
6.92 + " }\n" +
6.93 +
6.94 + " static boolean g(String s) { return false; }\n" +
6.95 + " static boolean g(Integer i) { return false; }\n" +
6.96 + "}";
6.97 +
6.98 + public JavaSource() {
6.99 + super(URI.create("myfo:/Foo.java"), JavaFileObject.Kind.SOURCE);
6.100 + }
6.101 +
6.102 + @Override
6.103 + public CharSequence getCharContent(boolean ignoreEncodingErrors) {
6.104 + return source;
6.105 + }
6.106 + }
6.107 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/test/tools/javac/T8176714/TimingOfMReferenceCheckingTest01.java Fri Mar 24 06:40:28 2017 -0700
7.3 @@ -0,0 +1,42 @@
7.4 +/*
7.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7.7 + *
7.8 + * This code is free software; you can redistribute it and/or modify it
7.9 + * under the terms of the GNU General Public License version 2 only, as
7.10 + * published by the Free Software Foundation.
7.11 + *
7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7.15 + * version 2 for more details (a copy is included in the LICENSE file that
7.16 + * accompanied this code).
7.17 + *
7.18 + * You should have received a copy of the GNU General Public License version
7.19 + * 2 along with this work; if not, write to the Free Software Foundation,
7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7.21 + *
7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7.23 + * or visit www.oracle.com if you need additional information or have any
7.24 + * questions.
7.25 + */
7.26 +
7.27 +/*
7.28 + * @test
7.29 + * @bug 8176714
7.30 + * @summary javac is wrongly assuming that field JCMemberReference.overloadKind has been assigned to
7.31 + * @compile TimingOfMReferenceCheckingTest01.java
7.32 + */
7.33 +
7.34 +import java.util.function.*;
7.35 +
7.36 +public class TimingOfMReferenceCheckingTest01 {
7.37 + <Z> void g(Consumer<Z> fzr, Z z) {}
7.38 +
7.39 + void test(boolean cond) {
7.40 + g(cond ? this::m : this::m, "");
7.41 + }
7.42 +
7.43 + void m(String s) {}
7.44 + void m(Integer i) {}
7.45 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/test/tools/javac/T8176714/TimingOfMReferenceCheckingTest02.java Fri Mar 24 06:40:28 2017 -0700
8.3 @@ -0,0 +1,47 @@
8.4 +/*
8.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8.7 + *
8.8 + * This code is free software; you can redistribute it and/or modify it
8.9 + * under the terms of the GNU General Public License version 2 only, as
8.10 + * published by the Free Software Foundation.
8.11 + *
8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
8.15 + * version 2 for more details (a copy is included in the LICENSE file that
8.16 + * accompanied this code).
8.17 + *
8.18 + * You should have received a copy of the GNU General Public License version
8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
8.21 + *
8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
8.23 + * or visit www.oracle.com if you need additional information or have any
8.24 + * questions.
8.25 + */
8.26 +
8.27 +/*
8.28 + * @test
8.29 + * @bug 8176714
8.30 + * @summary javac is wrongly assuming that field JCMemberReference.overloadKind has been assigned to
8.31 + * @compile TimingOfMReferenceCheckingTest02.java
8.32 + */
8.33 +
8.34 +import java.util.function.*;
8.35 +
8.36 +public class TimingOfMReferenceCheckingTest02 {
8.37 + <Z> void g(Consumer<Z> fzr, Z z) {}
8.38 + <T> T f(T t) { return null; }
8.39 +
8.40 + void test(boolean cond) {
8.41 + g(cond ?
8.42 + f(cond ?
8.43 + this::m :
8.44 + this::m) :
8.45 + this::m, "");
8.46 + }
8.47 +
8.48 + void m(String s) {}
8.49 + void m(Integer i) {}
8.50 +}