Bug 163590 - [1.5][compiler] Incompatible type bounds message points to the generic type instead of its type parameter
Summary: [1.5][compiler] Incompatible type bounds message points to the generic type i...
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 M5   Edit
Assignee: Maxime Daniel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-11-06 15:34 EST by Greg Gibeling CLA
Modified: 2007-02-05 11:30 EST (History)
1 user (show)

See Also:


Attachments
Fix + test cases (8.91 KB, patch)
2007-01-26 07:13 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 Greg Gibeling CLA 2006-11-06 15:34:43 EST
Given code:
public class A<X extends B & C> {}
public interface B { public int method(); }
public interface C { public boolean method(); }

The error will be reported for A, not X.  Furthermore the error is inspecific as to the fact that it is B and C which have incompatible return types.  For example if B or C had superinterfaces with "method" the error for X would list ALL declarations of "method".
Comment 1 Olivier Thomann CLA 2006-11-07 09:22:26 EST
Using HEAD, we return:
----------
1. ERROR in D:\tests_sources\test\A.java (at line 1)
	public class A<X extends B & C> {}
	             ^
The return type is incompatible with C.method(), B.method()
----------
1 problem (1 error)

Javac 1.5.0_09 and 1.6b104 are compiling it without any error.
Comment 2 Olivier Thomann CLA 2006-11-07 09:30:06 EST
Not a regression from 3.2.0.
3.2.0 reports exactly the same error.
Comment 3 Maxime Daniel CLA 2007-01-24 12:03:44 EST
From JLS 3 4.9, I would contend that we rightly complain, because no class could implement both B and C - and javac would be wrong in that case (Philippe, do I miss something?). Note that javac complain if we attempt to have a class Y implement both B and C, with or without implementations for method.
This would leave us with some need to improve the error message. I believe that the message as described in comment #1 makes plainly clear that the problem has to do with C#method and B#method. Which leaves us with A being underlined instead of X. I will investigate how easy (or difficult) it would be to do so.
Comment 4 Philipe Mulet CLA 2007-01-24 12:59:50 EST
I somehow remember that there are cases where the complaint is deferred until actually trying to instantiate such an object; where a standard bound mismatch will arise from not being able to satisfy both constraints.

So maybe we could be doing too much work eagerly.
Something to check:

public class A<X extends B & C> {
  void foo(X x) {
     x.method();
  }
}
public interface B { public int method(); }
public interface C { public boolean method(); }

I would assume that if #method() gets invoked some complaint is issued.
Comment 5 Philipe Mulet CLA 2007-01-24 13:01:14 EST
Side-note, even if complaining on type parameter was too harsh, it would still be a useful notification (warning) to emit, so end users would notice the problem sooner than later.
Comment 6 Maxime Daniel CLA 2007-01-25 02:38:36 EST
Upon:
public class X<T extends I & J> {
  void foo(T t) {
	t.method();
	t.bar();
	if (t.CONSTANT > 0);
  }
}
interface I {
  public int method();
  void bar();
}
interface J {
  public boolean method();
  static final int CONSTANT = 0;
}
javac says:
X.java:3: reference to method is ambiguous, both method method() in J and method
 method() in I match
        t.method();
         ^
1 error

Which shows that method is unusable, but bar and CONSTANT can be used. This would support the view that we should defer the diagnostic.

However, I can still not convince myself that JLS 3 4.9 authorizes that situation, because I cannot build a suitable intersection type. Would you see this as a bug in the spec, or do I miss something about intersection types building or their relationship to variables bounds?
Comment 7 Maxime Daniel CLA 2007-01-25 05:48:38 EST
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5061359 says that this is a javac bug, fixed in 1.7 b03. Checked with 1.7 b05 and it complains as we do (except that we misplace the caret).

So I will attempt to fix the caret position, and consider that we are right in raising an error.
Comment 8 Greg Gibeling CLA 2007-01-25 10:27:24 EST
Three things:
1) I cannot imagine any way the java spec could fail to make the declaration "X<T extends I & J>" in comment #6 invalid, as java does not use return types as part of the dynamic signature of a method.  Without reading the JLS, just from a language theory standpoint, the combination of I&J must be invalid, and so should be reported, presumeably ASAP.  As further evidence I have no idea how such a combination could ever be represented in the java reflection API, nor how dispatch could be handled.

Clearly it is impossible to staticly declare a class which matches T, such a class would result in a compiler error.  That leaves proxies and direct bytecode generation as the only ways to get such a class, both of which, to my knowledge, have the same expressive power as static declaration.  This means that there can never be an instance of T.  As the person coding X, wouldn't you want to know that early if possible?

2) I would like to make sure while people are looking at this that there is a passing test which ensures the following code compiles without error:

public class A<X extends B & C> {}
public interface B { public int method(); }
public interface C { public int method(); }

3) Thanks a lot for working on this.  It's was a pain is my butt.
Comment 9 Maxime Daniel CLA 2007-01-26 02:31:31 EST
You're welcome.
I'll add your suggested test case close to the others for the sake of completeness if it is not obviously the same as a pre-existing one.
Comment 10 Maxime Daniel CLA 2007-01-26 07:12:27 EST
Aligning title with conclusions.
Comment 11 Maxime Daniel CLA 2007-01-26 07:13:56 EST
Created attachment 57585 [details]
Fix + test cases

Fixes the caret position, adds test cases specific for the bug, tunes the pre-existing test cases that were written with a wrong caret position.
Comment 12 Maxime Daniel CLA 2007-01-26 07:19:04 EST
Released for 3.3 M5.
Comment 13 David Audel CLA 2007-02-05 11:30:45 EST
Verified for 3.3 M5 using warm-up build I20070205-0009