Bug 106744 - [1.5][compiler] Wrong type inference leads to compile error
Summary: [1.5][compiler] Wrong type inference leads to compile error
Status: RESOLVED WORKSFORME
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2 M2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 163560 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-08-11 10:00 EDT by Olivier Thomann CLA
Modified: 2006-12-06 05:37 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Olivier Thomann CLA 2005-08-11 10:00:03 EDT
Using 3.2M1 candidate, the following code doesn't compile.

p/Ann.java
----------
package p;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.CONSTRUCTOR;

@Target(CONSTRUCTOR)
@Retention(RUNTIME)
public @interface Ann {
	String message();
}
--------------------------------------------------------------
p/X.java
--------
package p;

import java.lang.reflect.Constructor;

public class X {
	public static void main(String[] args) {
        final Class<Ann> AnnClass = Ann.class;
	    Constructor[] constrs = X.class.getConstructors();
        for (Constructor constructor  : constrs) {
            final String message = constructor.getAnnotation(AnnClass).message();
            System.out.println(message);
        }
	}
}


The compiler infers Annotation as the type for
constructor.getAnnotation(AnnClass) instead of Ann. Then message() is reported
as undefined for the type Annotation.

The signature of Constructor.getAnnotation(...) is:
    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
       ...
    }
So I would expect p.Ann as the return type.
Comment 1 Olivier Thomann CLA 2005-08-11 10:01:57 EDT
javac compiles that code. But if you replace:
        final Class<Ann> AnnClass = Ann.class;
with:
        final Class AnnClass = Ann.class;
then javac reports the same error as we do.
Comment 2 Philipe Mulet CLA 2005-08-11 10:29:19 EDT
Interestingly, we accept the following:
public class X {
	public static void main(String[] args) {
		try {
		    X.class.getConstructor(new Class[0]).getAnnotation(Ann.class).message();
		} catch(Exception e) {
		}
	}
}

@interface Ann {
	String message();
}
Comment 3 Philipe Mulet CLA 2005-08-11 16:07:11 EDT
Weird. Javac accepts the following code:

import java.lang.reflect.Constructor;

public class X {
  void bar(Constructor constructor, Class<Ann> ann) {
    constructor.getAnnotation(ann).message();  // OK
  }
}
@interface Ann {
  String message();
}


but rejects:


public class X {
  void bar(Constructor constructor, Class<Ann> ann) {
    constructor.getAnnotation(ann).message();  // KO - cannot find method
#message() for Annotation
  }
}
class Constructor<V> {
  <T extends Annotation> T getAnnotation(Class<T> c) { return null; }
}

class Annotation {}
class Ann extends Annotation {
  void message() {}
}


I am a bit puzzled by this difference in behavior, and am wondering if
Annotation#getAnnotation(...) is meant to be treated in a special way (which no
longer occurs in second example when defining source types) in a similar fashion
as Object#getClass(...).

Couldn't find any mention of this in the spec though.
Comment 4 Philipe Mulet CLA 2005-08-12 05:10:54 EDT
Suspicion is that this is a bug in javac, and the code should be rejected.
Added GenericTypeTest#test800-802.
Comment 5 Philipe Mulet CLA 2005-09-05 04:09:24 EDT
Closing as javac bug.
Comment 6 Maxime Daniel CLA 2006-12-05 11:31:15 EST
*** Bug 163560 has been marked as a duplicate of this bug. ***
Comment 7 Philipe Mulet CLA 2006-12-06 05:37:37 EST
Javac bug is http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6400189