Bug 91728 - [compiler] [1.5] internal compiler reports a bug javac only a warning
Summary: [compiler] [1.5] internal compiler reports a bug javac only a warning
Status: RESOLVED WORKSFORME
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 3.1 RC2   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-04-18 08:30 EDT by Ralf Behle CLA
Modified: 2005-06-09 10:34 EDT (History)
2 users (show)

See Also:


Attachments
Patch for jdt/core (4.33 KB, patch)
2005-06-07 09:39 EDT, Philipe Mulet CLA
no flags Details | Diff
Patch for compiler tests (2.18 KB, patch)
2005-06-07 09:40 EDT, Philipe Mulet CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ralf Behle CLA 2005-04-18 08:30:58 EDT
For the given program eclipse reports an error. In the declaration of B.test.
Javac only reports a reports due to an unchecked conversion.

import java.util.*;

public class A<S> {
	
	public static <U> A<U> test() {
		return null;
	}
        
}

class B extends A<Set> {
	
	public static B test() {
		return null;
	}
	
}
Comment 1 Philipe Mulet CLA 2005-04-18 11:04:39 EDT
Reproduced in M6.
Comment 2 Kent Johnson CLA 2005-05-27 12:10:24 EDT
So this case causes a return type compatibility error:

class A<T> {
  A<Object> test() { return null; }
}
class B extends A<C> {
  // cannot override test() in A; attempting to use incompatible return type
  B test() { return null; }
}
class C {}

but in this case its an unchecked conversion warning:

class A<T> {
  <Unused> A<Object> test3() { return null; }
}
class B extends A<C> {
  // warning: test() in B overrides <Unused>test() in A; return type requires 
unchecked conversion
  B test3() { return null; }
}
class C {}


Why?
Comment 3 Philipe Mulet CLA 2005-06-07 09:37:03 EDT
I would suspect that comment#2 reveals a bug.

I am guessing that our substitution mechanisms should be made smarter. Instead
of stealing other variables, and missing ones (in this case) replaced with upper
bounds (old code was incorrectly using #erasure()); it should use proper
inference algorithm to compute based on arguments and expected types.

See attached patch.
Comment 4 Philipe Mulet CLA 2005-06-07 09:39:30 EDT
Created attachment 22507 [details]
Patch for jdt/core

Note1: that substitute computation will be more expensive (i.e. do we compute
as little as we need?). 

Note2: if old code is left in place, it should still replace unbound variables
with #upperBound() instead of erasure, and not bother when both method
parameters counts are not identical.
Comment 5 Philipe Mulet CLA 2005-06-07 09:40:20 EDT
Created attachment 22509 [details]
Patch for compiler tests
Comment 6 Philipe Mulet CLA 2005-06-07 09:49:02 EDT
My patch fails GenericTypeTest#test355 (no more name clash)
Comment 7 Kent Johnson CLA 2005-06-07 14:36:35 EDT
testcases already exist as 52 & 53

With the patch & this case:

class X extends Y { <X1, X2> X2 foo(Class<X2> c) { return null; } }
class Y { <Y1, Y2> Y1 foo(Class<Y1> c) { return null; } }

I see the substitute method for Y.foo created as X2 foo(Class<X2>) instead of 
X1 foo(Class<X1>).
Comment 8 Philipe Mulet CLA 2005-06-07 15:06:58 EDT
Actually, according to the spec, we should reject this program.

Details from spec expert:
"B.test() hides X.test(), because the signature of B.test() is a 
subsignature of that of X.test(): the signature of B.test() is (), which 
is the same as the erasure of <U>(), the signature of X.test().

Hence, we have the requirement that the return type of B.test() be 
return-type-substitutable for taht of X.test(), namely, we expect that:

either B <: X<U>, or B can be converted to a subtype of X<U> by 
unchecked conversion, or B = |X<U>|.

Unchecked conversion does not apply since B is not a parameterized type.
B is equal to |X<U>| = X.

So, is B <: X<U>?  No. So this should be illegal."
Comment 9 Kent Johnson CLA 2005-06-07 15:39:04 EDT
Given the confirmation that the spec says this case is an error and not a 
conversion warning, we are going to close this PR.

Expect this problem to be fixed in a new version of javac.
Comment 10 Kent Johnson CLA 2005-06-09 10:34:22 EDT
This case works 'properly' as it reports the unchecked warning:

class Try {
    public static void main(String[] args) {
        new Ex().method2(new Integer(1));
    }
}

class Top<TC> {
    <TM> void method2(TM mTop) { System.out.println("Top"); }
}

class Ex<C> extends Top<C> {
    @Override <M> void method2(M mEx) { System.out.println("Ex"); }
}
Comment 11 Kent Johnson CLA 2005-06-09 10:34:42 EDT
Sorry wrong PR.