SUGGESTED FIX
It turns out that the changes to Resolve.java to fix 5046972 were incorrect.
See
http://javac.sfbay/java/jdk/ws/tools/gjc/FIXES/2004/05/24/5046972/webrev/src/share/classes/com/sun/tools/javac/comp/Resolve.java.udiff.html
Part of the changes for 5046972 are fine: the local variable staticOnly is
set more correctly and that is actually enough to fix 5046972.
However, the fix for 5046972 also changes when to look at member types
which is not correct. Type variables are not membertypes. So the fix for
this bug is to undo some of the changes made for 5046972:
@@ -928,13 +928,8 @@
return e.sym;
}
}
-
- JCClassDecl encl;
- if (env1.baseClause) {
- encl = (JCClassDecl)env1.tree;
- } else {
- sym = findMemberType(env1, env1.enclClass.sym.type, name,
- env1.enclClass.sym);
+ sym = findMemberType(
+ env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
if (staticOnly && sym.kind == TYP &&
sym.type.tag == CLASS &&
sym.type.getEnclosingType().tag == CLASS &&
@@ -943,8 +938,8 @@
return new StaticError(sym);
else if (sym.exists()) return sym;
else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
- encl = env1.enclClass;
- }
+
+ JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
if ((encl.sym.flags() & STATIC) != 0)
staticOnly = true;
}
An alternative view of this situation is to diff against the version
before 5046972 and the suggested fix for this bug. There are some changes
that were caused by API changes for JSR 269 and com.sun.source. Ignoring
this, it is clear that the fix now only is concerned with determining
if the current environment is static or not:
@@ -883,19 +932,19 @@
env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
if (staticOnly && sym.kind == TYP &&
sym.type.tag == CLASS &&
- sym.type.outer().tag == CLASS &&
+ sym.type.getEnclosingType().tag == CLASS &&
env1.enclClass.sym.type.isParameterized() &&
- sym.type.outer().isParameterized())
+ sym.type.getEnclosingType().isParameterized())
return new StaticError(sym);
else if (sym.exists()) return sym;
else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
- if ((env1.enclClass.sym.flags() & STATIC) != 0 &&
- (env1.tree.tag != Tree.CLASSDEF || env1.tree == env1.enclClass))
+ JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
+ if ((encl.sym.flags() & STATIC) != 0)
staticOnly = true;
}
- if (env.tree.tag != Tree.IMPORT) {
+ if (env.tree.tag != JCTree.IMPORT) {
sym = findGlobalType(env, env.toplevel.namedImportScope, name);
if (sym.exists()) return sym;
else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
|
|
|
SUGGESTED FIX
Webrev of changes: http://sa.sfbay/projects/langtools/bugid_summary.pl?bugid=5060485
See also attachment: 5060485.tar.gz
|
|
|
SUGGESTED FIX
No that doesn't work, since this program must compile:
public class Method<T extends Number> {
static class Y {}
<Y extends Number> void test() {
Method<Y> m = null;
Number n = m.get();
}
T get() {
return null;
}
}
|
|
|
SUGGESTED FIX
The solution is fairly simple: Resolve.findType looks at "any other type"
before looking at member types. So we just rearrange the code to look
at member types before "any other type".
|
|
|
EVALUATION
The exact words are:
"Within a class C, a declaration d of a member type named n shadows the
declarations of any other types named n that are in scope at the point
where d occurs."
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.5
Since the compiler looks at "any other types" before it looks at
member types, it is incorrect.
|
|
|
CONVERTED DATA
BugTraq+ Release Management Values
COMMIT TO FIX:
dragon
mustang
|
|
|
EVALUATION
This is definitely a bug. The type parameter should be shadowed, or the
shadowing should be illegal (need to check the JLS).
###@###.### 2004-06-09
The shadowing rules for type parameters are not yet in the JLS. I'm sure
the compiler is wrong in its current behavior, but I don't know what the correct
behavior should be. Reassigning to spec for JLS3.
For reference, here is a program that should clearly be an error, for one of
two (or more) reasons, but I don't know which:
interface I1 {}
interface I2 {}
class A<T extends I1> {
class T implements I2 {}
void f(T t) {
I1 i = t;
}
}
###@###.### 2004-06-13
JLS 8.5, Member types, states that a declaration of a member type shadows the
declarations of any other type of the same name that is in scope.
Hence, the compile is in error, and the smaller example above is illegal
because if f, T referes to the member type that is a subtype of I2 not I1.
###@###.### 2004-07-09
|
|
|
|