Bug 163370 - [1.5][compiler] Incorrect ambiguous method error
Summary: [1.5][compiler] Incorrect ambiguous method error
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.3 M4   Edit
Assignee: Maxime Daniel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 165074 168167 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-11-03 13:47 EST by Olivier Thomann CLA
Modified: 2006-12-15 09:24 EST (History)
6 users (show)

See Also:


Attachments
Exploratory patch (5.30 KB, patch)
2006-11-23 09:40 EST, Maxime Daniel CLA
no flags Details | Diff
Fix for this bug and bug 165620 + new test case (8.42 KB, patch)
2006-11-24 09:24 EST, Maxime Daniel CLA
no flags Details | Diff
Better patch (thx to kent) (20.08 KB, patch)
2006-12-05 00:35 EST, Maxime Daniel CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Olivier Thomann CLA 2006-11-03 13:47:57 EST
Using HEAD (3.3M3), the following code doesn't compile:

[
interface I<E> {
}

class Y<E> {}

public class X<E extends Y<E>> implements I<E> {
	
    public static <E extends Y<E>> X<E> bar(X<E> s) {
        return null;
    }

    public static <E extends Y<E>> X<E> bar(I<E> c) {
    	return null;
    }

    public static <E extends Y<E>> X<E> foo(X<E> s) {
        X<E> result = bar(s);
        return result;
    }
}
]

We report:
----------
1. ERROR in D:\tests_sources\X.java (at line 17)
	X<E> result = bar(s);
	              ^^^
The method bar(X<E>) is ambiguous for the type X<E>
----------
1 problem (1 error)

javac 1.5.0_09 and 1.6b104 compile it without an error.
Comment 1 Ruth Alkema CLA 2006-11-13 08:47:22 EST
The following doesn't compile either:
public class Foo {
  private enum Type {
    A, B, C
  }

  public static void test() {
    EnumSet<Type> set = EnumSet.allOf(Type.class);
    EnumSet<Type> set2;

    set2 = EnumSet.copyOf(set);
  }
}
Comment 2 Olivier Thomann CLA 2006-11-18 14:20:53 EST
*** Bug 165074 has been marked as a duplicate of this bug. ***
Comment 3 Maxime Daniel CLA 2006-11-20 07:42:20 EST
Released AmbiguousMethodTest#test044, active in R3_2_maintenance branch, inactive in HEAD branch.
Comment 4 Maxime Daniel CLA 2006-11-23 09:40:09 EST
Created attachment 54414 [details]
Exploratory patch

The idea is to rawify only bounds that use type arguments in their definition, in order to stop recursive behaviors. Here, when creating the tiebreak method for <E extends Y<E>> X<E> foo(X<E> p), E would be substituted by Y#RAW (whereas in a concrete case like T extends Y<String> T would still be substituted by Y<String>).
Do not release this patch as it is know (privileged speed).
Comment 5 Maxime Daniel CLA 2006-11-24 09:24:33 EST
Created attachment 54477 [details]
Fix for this bug and bug 165620 + new test case

This new patch:
- is cleaner than the previous one;
- gets the modifications operated to fix 165620;
- adds a test for the multi variables case (AmbiguousMethodTest#46).

The multi variables case seems to be covered by what the second patch for bug 165620 proposed. Only added a supplementary test.
Comment 6 Kent Johnson CLA 2006-11-24 12:34:55 EST
I don't believe this problem is restricted to static methods, see bug 159711.

If we replace test23 with the following, we'll see that instance methods have the same issues as static methods :

public void test023() {
this.runConformTest(
  new String[] {
    "X.java",
    "import java.util.*;\n" + 
    "public class X {\n" +
    "  public static void staticFoo(Collection<?> p) {\n" +
    "    System.out.print(1);\n" +
    "  }\n" +
    "  public static <T extends List<?>> void staticFoo(T p) {\n" + 
    "    System.out.print(2);\n" +
    "  }\n" +
    "  public void foo(Collection<?> p) {\n" +
    "    System.out.print(1);\n" +
    "  }\n" +
    "  public <T extends List<?>> void foo(T p) {\n" + 
    "    System.out.print(2);\n" +
    "  }\n" +
    "  public static void main(String[] args) {\n" + 
    "    staticFoo(new ArrayList<String>(Arrays.asList(\"\")));\n" + 
    "    new X().foo(new ArrayList<String>(Arrays.asList(\"\")));\n" + 
    "  }\n" +
    "}"
  },
  "22");
}
Comment 7 Kent Johnson CLA 2006-11-24 12:50:24 EST
None of the tests included in the latest patch fail if the fix for bug 159711 is removed.

Are we on the right track or should we start over with the above test23() ?
Comment 8 Kent Johnson CLA 2006-11-24 15:58:14 EST
We do not have a problem choosing between these 2 methods:

void foo(Collection<?> p) {}
void foo(List<?> p) {}

but we do with these:

void foo(Collection<?> p) {}
<T extends List<?>> void foo(T p) {}

in this case, List#RAW is compatible with Collection<?> but we turn it down in Scope.isAcceptableMethod() because of a hierarchy check (line 2505) that looks odd.
Comment 9 Maxime Daniel CLA 2006-11-27 04:25:25 EST
(In reply to comment #8)
> We do not have a problem choosing between these 2 methods:
> 
> void foo(Collection<?> p) {}
> void foo(List<?> p) {}
> 
> but we do with these:
> 
> void foo(Collection<?> p) {}
> <T extends List<?>> void foo(T p) {}
> 
> in this case, List#RAW is compatible with Collection<?> but we turn it down in
> Scope.isAcceptableMethod() because of a hierarchy check (line 2505) that looks
> odd.
> 

I believe this one is tracked by bug 121024 (not digged into it, but the upper bound for the second method would be Object, which is not a Collection; if so, the suggestion for bug 121024 to keep more information into upper bounds should help).
Comment 10 Kent Johnson CLA 2006-11-27 11:31:35 EST
Released for 3.3 M4 in HEAD stream
Comment 11 Maxime Daniel CLA 2006-11-28 07:15:01 EST
(In reply to comment #8)
> We do not have a problem choosing between these 2 methods:
> 
> void foo(Collection<?> p) {}
> void foo(List<?> p) {}
> 
> but we do with these:
> 
> void foo(Collection<?> p) {}
> <T extends List<?>> void foo(T p) {}
> 
> in this case, List#RAW is compatible with Collection<?> but we turn it down in
> Scope.isAcceptableMethod() because of a hierarchy check (line 2505) that looks
> odd.
> 
The following test case passes (for us and javac):
public class X {
  void foo(Collection<?> p) {}
  <T extends List<?>> void foo(T p) {}
	public static void main(String[] args) {
		List l = null;
		new X().foo(l);
	}
}
interface Collection<T> {}
interface List<T> {}

Could you please be more specific?
Comment 12 Maxime Daniel CLA 2006-12-05 00:35:55 EST
Created attachment 55018 [details]
Better patch (thx to kent)
Comment 13 Olivier Thomann CLA 2006-12-11 15:09:52 EST
Verified for 3.3M4 with I20061211-1119
Comment 14 Olivier Thomann CLA 2006-12-15 09:24:38 EST
*** Bug 168167 has been marked as a duplicate of this bug. ***