Bug 108014 - [generics] cannot override when returning T (but stranger)
Summary: [generics] cannot override when returning T (but stranger)
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-08-25 13:17 EDT by Samuel Gélineau CLA
Modified: 2005-08-26 07:58 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Samuel Gélineau CLA 2005-08-25 13:17:38 EDT
this bug is a sequel to Bug #107898 (currently resolved), which apparently only
fixed part of the problem.

under the same strange circumstances which enabled the first bug, @Override
fails to work properly and overiding the method anyway does nothing:


class Bug_Provider {
  public void enable_bug(Object argument) {}
}

class Bug_Checker<T> extends Bug_Provider {
  public T is_bug_enabled() {
    return (T) new Boolean(true);
  }
}

public class Bug {
  public static void main(String[] args) throws InterruptedException {
    final Bug_Checker<Boolean> first = new Bug_Checker<Boolean>() {
      @Override // compiler agrees, this is an override
      public Boolean is_bug_enabled() {
        return new Boolean(false);
      }
    };
    System.out.println("is bug enabled? " + first.is_bug_enabled()); // false

    first.enable_bug(null);

    final Bug_Checker<Boolean> second = new Bug_Checker<Boolean>() {
      //@Override // compiler disagrees now!
      public Boolean is_bug_enabled() {
        return new Boolean(false);
      }
    };
    System.out.println("is bug enabled? " +second.is_bug_enabled()); // true!
  }
}


note that if the second override of is_bug_enabled is declared to return Object
instead, it does override the original method (although @Override thinks
otherwise). instead, the compiler should return an error, like it does when the
bug is disabled.
Comment 1 Andrew Clement CLA 2005-08-25 14:13:01 EDT
Well ... a last minute fix went in for a local type problem ... and it appears
to be playing up a bit here, when I uncomment the 2nd @Override and compile the
program, it blows up:

C:\Bug.java [error] Internal compiler error
java.lang.IllegalStateException: Expecting raw type
	at org.aspectj.weaver.TypeFactory.createParameterizedType(TypeFactory.java:42)
	at org.aspectj.weaver.World.resolveToReferenceType(World.java:262)
	at org.aspectj.weaver.World.resolve(World.java:205)
	at org.aspectj.weaver.World.resolve(World.java:127)
	at
org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory.fromEclipse(EclipseFactory.java:125)
	at
org.aspectj.ajdt.internal.compiler.lookup.EclipseSourceType.getSuperclass(EclipseSourceType.java:115)
	at org.aspectj.weaver.ReferenceType.getSuperclass(ReferenceType.java:443)
	at
org.aspectj.ajdt.internal.compiler.problem.AjProblemReporter.methodMustOverride(AjProblemReporter.java:356)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.resolveStatements(MethodDeclaration.java:153)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolve(AbstractMethodDeclaration.java:400)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1076)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1105)

tracing this a little further I put a breakpoint on EclipseSourceType.isGeneric
and the binding being queried is:

Anonymous type : (id=NoId)
final class $Local$ extends Bug_Checker<java.lang.Boolean>
	enclosing type : Bug
/*   methods   */
java.lang.Boolean is_bug_enabled() 

when I would have expected it to answer TRUE.  Possibly an incorrect lookup of
$Local$ has caused us to put a parameterized type in as the generic type when it
shouldn't have...
Comment 2 Samuel Gélineau CLA 2005-08-25 15:20:11 EDT
indeed, in my before-the-last-minute-fix version of ajc, uncommenting the second
override yields an error which does mention $Local$:


[error] can't find type $Local$
        
[error] can't find type $Local$
        
/home/user/sgelin3/dev/java/ajc/108014-pending/Bug.java:25 [error] The method
is_bug_enabled() of type new Bug_Checker<Boolean>(){} must override a superclass
method
public Boolean is_bug_enabled() {
               ^^^^^^^^^

3 errors
Comment 3 Adrian Colyer CLA 2005-08-26 07:58:07 EDT
The $Local$ issue was occuring because we were trying to put out a message that
the method did not override the super method (and at the point the message was
issued, we hadn't assigned a constant pool name to the inner type). 

The underlying bug was that we didn't think the method overrode a super method.
The call to enable_bug(null) was signifcant in that it caused us to go looking
up the hierarchy for an exact method match, based on the inferred argument type.
When passing an Object this finds the method in Bug_Provider that takes an
Object. When passing null that method is only seen as a *candidate* match, and
we have to do some more work. In the "more work" we happened to also look at
ITDs made on the type (none in this case) and a horrible side-effect of not
finding any was to remove all knowledge of methods in the type of the receiver
(in your program, the type of first). This erased all trace of is_bug_enabled in
the anonymous Bug_Checker<Boolean> class , leaving the program to bind the
second message send to the supertype method and also causing the bad override
message.

This whole mess should now be cleared up, and a fix is checked into the tree.
We're going to release 1.5.0 M3a with the fix for this bug and also bug 108050
included.