Bug 276800 - [1.5][compiler] Eclipse compiler shows error on javac-valid construct
Summary: [1.5][compiler] Eclipse compiler shows error on javac-valid construct
Status: VERIFIED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.4.2   Edit
Hardware: All All
: P3 normal with 3 votes (vote)
Target Milestone: 4.12 M1   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-18 21:36 EDT by Zorzella Mising name CLA
Modified: 2019-04-09 02:20 EDT (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zorzella Mising name CLA 2009-05-18 21:36:25 EDT
Build ID: M20090211-1700

The snippet below is a self-contained minimized portion that repros a problem I found. The problem manifested in an test that uses the well-known EasyMock, so I preserved the EasyMock class names, prefixed by "Z", to give it the right flavor, but it's completely self contained.

javac compiles this code, and it seems valid, but Eclipse complains:

The method andReturn(capture#1-of ? extends SomeTest.Baz) in the type SomeTest.ZIExpectationsSetters<capture#1-of ? extends SomeTest.Baz> is not applicable for the arguments (SomeTest.Baz)

*******************

public class SomeTest {

  public void testFoo() throws Exception {
  
    Bar<? extends Baz> bar = null;
    Baz baz = null;
    ZEasyMock.expect(bar.get()).andReturn(baz);    
  }
  
  static class Baz {}

  interface Bar<T> {
    T get();
  }
  
  static class ZEasyMock {
  
    public static <T> ZIExpectationSetters<T> expect(T value) {
      return null;
    }

  }
  
  interface ZIExpectationSetters<T> {
    /*IExpectationSetters<T>*/ void andReturn(T value);
  }  
}
Comment 1 Kent Johnson CLA 2009-05-19 14:22:09 EDT
Need to check but believe this is a javac bug. In this case:

class X {
	void a(J<? extends X> j, X x) {
		aHelp(j.getX()).andReturn(x); // javac accepts
	}
	<T> I<T> aHelp(T v) { return null; }

	void b(J<? extends X> j, X x) {
		bHelp(j).andReturn(x); // javac reports error
		  // required: capture#1 of ? extends X
		  // found: X
	}
	<T> I<T> bHelp(J<T> j) { return null; }
}
interface J<T> { T getX(); }
interface I<T> { void andReturn(T value); }

javac reports an error when the result of I<T> bHelp(J<T> j) is sent andReturn(x) but not for I<T> aHelp(T v)

eclipse treats both cases the same since the return type of aHelp and bHelp is  capture of ? extends X, and the expected type of andReturn is X
Comment 2 Kent Johnson CLA 2009-05-20 11:41:06 EDT
Similar to https://bugs.eclipse.org/bugs/show_bug.cgi?id=271160#c2
Comment 3 Kent Johnson CLA 2009-05-20 11:49:56 EDT
This case shows that eclipse is inconsistent - it appears that we do not use the expected return type to infer the return type of a nested message send.


class X {
	<T> I<T> foo(T v) { return null; }

	void testReturnType(J<? extends X> j) {
		X x = j.get();
		I<X> a = foo(x); // javac & eclipse accept

		I<X> a2 = foo(j.get()); // javac accepts, eclipse reports error
	}
}

interface J<T> { T get(); }
interface I<T> {}
Comment 4 Srikanth Sankaran CLA 2011-08-18 01:04:15 EDT
There was a query about the status of this bug in the forums.
I'll take a look at this for 3.8
Comment 5 Stephan Herrmann CLA 2012-04-15 10:49:06 EDT
Informal assessment:

bar : 
   Bar<? extends SomeTest.Baz>
bar.get() : 
   capture#1-of ? extends SomeTest.Baz
ZEasyMock.expect(bar.get()) :
   ZIExpectationSetters<capture#1-of ? extends SomeTest.Baz>
argument value in andReturn :
   capture#1-of ? extends SomeTest.Baz

In parameter position no type is conform to <? extends X>


Changing the declaration of bar to
    Bar<? super Baz> bar = null;

makes all compilers happy 
(except that bar can only be null and shouldn't be dereferenced :) ).


Thus I'm leaning towards closing as INVALID.

Did I miss anything?
Comment 6 Stephan Herrmann CLA 2012-04-15 12:14:54 EDT
(In reply to comment #3)
> This case shows that eclipse is inconsistent - it appears that we do not use
> the expected return type to infer the return type of a nested message send.
> 
> 
> class X {
>     <T> I<T> foo(T v) { return null; }
> 
>     void testReturnType(J<? extends X> j) {
>         X x = j.get();
>         I<X> a = foo(x); // javac & eclipse accept
> 
>         I<X> a2 = foo(j.get()); // javac accepts, eclipse reports error
>     }
> }
> 
> interface J<T> { T get(); }
> interface I<T> {}

That's a different problem requiring separate investigation.
Error message is:
  Type mismatch: cannot convert from I<capture#2-of ? extends X> to I<X>

Without context this message would seem correct to me. It would require further digging in the JLS whether the capture#2-of part must be retained or can be substituted by the upper bound when inferring types of foo().

Srikanth, can you recall/reconstruct whether the forum question related to comment 0 or comment 3?
Comment 7 Srikanth Sankaran CLA 2012-05-09 05:43:44 EDT
(In reply to comment #6)

> Srikanth, can you recall/reconstruct whether the forum question related to
> comment 0 or comment 3?

No :(. I am moving this out to later as I don't expect to get to this
for 3.8. Sorry.
Comment 8 Eclipse Genie CLA 2019-03-28 14:26:21 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.
Comment 9 Stephan Herrmann CLA 2019-04-02 13:40:55 EDT
We consider the deviation re comment 0 as a bug in javac.

Regarding comment 3 both compiler agree on accepting (at compliance 1.8).
Comment 10 Manoj N Palat CLA 2019-04-09 02:20:44 EDT
Verified for Eclipse 4.12 M1 with Build id: I20190408-1800