8033483: Should ignore nested lambda bodies during overload resolution
Reviewed-by: mcimadamore, dlsmith
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jul 09 16:32:05 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jul 09 10:49:32 2014 -0400
@@ -516,13 +516,11 @@
}
}
if (!progress) {
- DeferredAttrContext dac = this;
- while (dac != emptyDeferredAttrContext) {
- if (dac.mode == AttrMode.SPECULATIVE) {
- //unsticking does not take place during overload
- break;
+ if (insideOverloadPhase()) {
+ for (DeferredAttrNode deferredNode: deferredAttrNodes) {
+ deferredNode.dt.tree.type = Type.noType;
}
- dac = dac.parent;
+ return;
}
//remove all variables that have already been instantiated
//from the list of stuck variables
@@ -538,6 +536,17 @@
}
}
}
+
+ private boolean insideOverloadPhase() {
+ DeferredAttrContext dac = this;
+ if (dac == emptyDeferredAttrContext) {
+ return false;
+ }
+ if (dac.mode == AttrMode.SPECULATIVE) {
+ return true;
+ }
+ return dac.parent.insideOverloadPhase();
+ }
}
/**
@@ -598,6 +607,8 @@
return false;
}
} else {
+ Assert.check(!deferredAttrContext.insideOverloadPhase(),
+ "attribution shouldn't be happening here");
ResultInfo instResultInfo =
resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt));
dt.check(instResultInfo, dummyStuckPolicy, basicCompleter);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.java Wed Jul 09 10:49:32 2014 -0400
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8033483
+ * @summary Should ignore nested lambda bodies during overload resolution
+ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest1.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest1.java
+ */
+
+class IgnoreLambdaBodyDuringResolutionTest1 {
+ interface SAM<T> {
+ T action(T t);
+ }
+
+ <T> T m(SAM<T> op) {
+ return null;
+ }
+
+ class B {
+ B x() {
+ return this;
+ }
+ }
+
+ class C {}
+
+ void foo(B arg) {}
+ void foo(C arg) {}
+
+ void bar() {
+ foo(m(arg -> new B()));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.out Wed Jul 09 10:49:32 2014 -0400
@@ -0,0 +1,2 @@
+IgnoreLambdaBodyDuringResolutionTest1.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.B), IgnoreLambdaBodyDuringResolutionTest1, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.C), IgnoreLambdaBodyDuringResolutionTest1
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.java Wed Jul 09 10:49:32 2014 -0400
@@ -0,0 +1,34 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8033483
+ * @summary Should ignore nested lambda bodies during overload resolution
+ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest2.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest2.java
+ */
+
+class IgnoreLambdaBodyDuringResolutionTest2 {
+ interface SAM<S> {
+ boolean test(S t);
+ }
+
+ <I, T extends I> I bar(final T l) {
+ return null;
+ }
+
+ class D<D1, D2> {
+ void foo() {
+ m(bar(e -> false));
+ }
+
+ void m(Class<D1> arg) {}
+ void m(SAM<D2> arg) {}
+ }
+
+ class F {
+ void foo() {
+ m(bar((String e) -> false));
+ }
+
+ <F1> void m(Class<F1> arg) {}
+ <F2> void m(SAM<F2> arg) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.out Wed Jul 09 10:49:32 2014 -0400
@@ -0,0 +1,6 @@
+IgnoreLambdaBodyDuringResolutionTest2.java:19:13: compiler.err.ref.ambiguous: m, kindname.method, m(java.lang.Class<D1>), IgnoreLambdaBodyDuringResolutionTest2.D, kindname.method, m(IgnoreLambdaBodyDuringResolutionTest2.SAM<D2>), IgnoreLambdaBodyDuringResolutionTest2.D
+IgnoreLambdaBodyDuringResolutionTest2.java:19:18: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Object))
+IgnoreLambdaBodyDuringResolutionTest2.java:19:14: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Class<D1>, <any>, kindname.class, IgnoreLambdaBodyDuringResolutionTest2.D<D1,D2>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class)))
+IgnoreLambdaBodyDuringResolutionTest2.java:28:13: compiler.err.ref.ambiguous: m, kindname.method, <F1>m(java.lang.Class<F1>), IgnoreLambdaBodyDuringResolutionTest2.F, kindname.method, <F2>m(IgnoreLambdaBodyDuringResolutionTest2.SAM<F2>), IgnoreLambdaBodyDuringResolutionTest2.F
+IgnoreLambdaBodyDuringResolutionTest2.java:28:14: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class))
+5 errors