Bug 100869 - [1.5][compiler] The eclipse compiler thinks my method is ambiguous but javac does not.
Summary: [1.5][compiler] The eclipse compiler thinks my method is ambiguous but javac ...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal with 3 votes (vote)
Target Milestone: 3.2 M5   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 105645 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-06-20 11:50 EDT by Chris Stretch CLA
Modified: 2006-05-30 04:26 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Stretch CLA 2005-06-20 11:50:34 EDT
The code below produces an error at the function call of m in class C.
     "The method m(String) is ambiguous for the type B"
javac from jdk1.5.0_03 compiles the code without warnings.

Removing the "extends A" from class B removes the problem.
Removing the "extends Comparable<T>" from A and B removes the problem.

I have been unable to find a formal description of the java generics but I can't
see how method m can be considered ambiguous.



----------------------------Start of test\C.java------------------------------
package test;

abstract class A
{
  abstract <T extends Comparable<T>> void m(T x);
}

class B extends A
{
  <T extends Comparable<T>> void m(T x)
  {
  }
}

public class C
{ 
  public static void main(String[] args)
  {
    new B().m("");
  }

}

--------------------End of test\C.java--------------------------

Results from eclipse Problems window:

Severity        2
Description     The method m(String) is ambiguous for the type B
Resource        C.java
In Folder       TestT/test
Location        line 19
Comment 1 Kent Johnson CLA 2005-06-20 14:35:21 EDT
Need to change TypeVariableBinding.isInterchangeableWith() to:

for (int i = 0; i < length; i++) {
  if (this.superInterfaces[i] != otherVariable.superInterfaces[i]) {
    if (this.superInterfaces[i].erasure() != otherVariable.superInterfaces
[i].erasure())
      return false; // no way it can match after substitution
    break identical;
  }
}
		identical: {
			if (this.superclass != otherVariable.superclass) {
				if (this.superclass.erasure() != 
otherVariable.superclass.erasure())
					return false; // no way it can match 
after substitution
				break identical;
			}
			for (int i = 0; i < length; i++) {
				if (this.superInterfaces[i] != 
otherVariable.superInterfaces[i]) {
					if (this.superInterfaces[i].erasure() !
= otherVariable.superInterfaces[i].erasure())
						return false; // no way it can 
match after substitution
					break identical;
				}
			}
			return true;
		}
		// need substitutions
		Substitution subst = new Substitution() {
			public LookupEnvironment environment() { return 
environment; }
			public boolean isRawSubstitution() { return false; }
			public TypeBinding substitute(TypeVariableBinding 
typeVariable) {
				return typeVariable == otherVariable ? 
TypeVariableBinding.this : typeVariable;
			}
		};
		if (this.superclass != Scope.substitute(subst, 
otherVariable.superclass))
			return false;
		for (int i = 0; i < length; i++)
			if (this.superInterfaces[i] != Scope.substitute(subst, 
otherVariable.superInterfaces[i]))
				return false;
		return true;
	}
Comment 2 Kent Johnson CLA 2005-06-20 14:36:01 EDT
That should have read...

Need to change TypeVariableBinding.isInterchangeableWith() to:

for (int i = 0; i < length; i++) {
  if (this.superInterfaces[i] != otherVariable.superInterfaces[i]) {
    if (this.superInterfaces[i].erasure() != otherVariable.superInterfaces
[i].erasure())
      return false; // no way it can match after substitution
    break identical;
  }
}
Comment 3 Andrew Zhezherun CLA 2005-06-21 09:57:03 EDT
The following code also cannot be compiled
by RC3:

public class Bug {
	public static interface Interface1<E> {
		public void method(E object);
	}
	
	public static interface Interface2<E> {
		public void method(E obj);
	}

	public static interface Interface3<E> extends Interface1<E>, 
Interface2<E> {
	}

	public static class Class1 implements Interface3<String> {
		public void method(String o) {
			System.out.println(o);
		}
	}

	public static void main(String[] args) {
		Interface3<String> object1 = new Class1();

		// Eclipse thinks this call is ambiguous
		object1.method("Hello world"); 
	}
}
Comment 4 Caspian Rychlik-Prince CLA 2005-06-23 05:42:16 EDT
Is there an ETA on this fix? It turns out to be a critical blocker for us as 
after a huge 3 week generics refactoring operation we can't get our code to 
compile now because of this error.

Perhaps it'll make it into tonight's build? :)
Comment 5 Kent Johnson CLA 2005-06-23 10:24:57 EDT
We do not have a fix for it yet.

I would guess a couple weeks unless extra incentive is emailed to an offshore 
account. ;)


Seriously - its on top of the list so cross your fingers.
Comment 6 Caspian Rychlik-Prince CLA 2005-06-23 11:18:49 EDT
That's great - in the meantime folk might want to know that the problem isn't 
exhibited in 3.1M7, so we've regressed back to that milestone release for now.
Comment 7 Kent Johnson CLA 2005-08-02 16:47:18 EDT
*** Bug 105645 has been marked as a duplicate of this bug. ***
Comment 8 Kent Johnson CLA 2005-09-19 15:16:18 EDT
Philippe, this one will be fixed when the tiebreak method for:

<T extends Comparable<T>> void m(T x)

is  void m(Comparable<String> x)  instead of  void m(Comparable<T> x)

We also need to make sure the tieBreak method for:

<T> void m(Comparable<String> x)

is  void m(Comparable<String> x)  instead of  void m(Comparable#RAW x)
Comment 9 Philipe Mulet CLA 2005-09-23 06:18:43 EDT
Fix will not be ready for 3.1.1, removing target milestone "3.1.1"
Comment 10 D.H.Akehurst CLA 2005-11-07 06:27:11 EST
Please can you fix this.

I make heavy use of a class/interface OrderedSet<E> that extends the std Java
List<E> and Set<E> classes. This bug means that all the code is uncompilable
due to the 'method X is ambiguous' error. I'm currently using version 3.1.0 
and would really like to use the later versions, but can't due to this bug.
Comment 11 Kent Johnson CLA 2006-01-26 12:55:20 EST
I've tried the 2 cases described in this PR (with the latest 3.2 intergration build) and recent changes in the last few months have fixed these cases.

Please open new PRs for any other cases which are still failing.


Added AmbiguousMethodTest test1 and test2 for these cases.
Comment 12 David Audel CLA 2006-02-14 08:56:54 EST
Verified for 3.2 M5 using build I20060214-0010