### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java,v retrieving revision 1.647 diff -u -r1.647 GenericTypeTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java 25 Sep 2007 09:29:17 -0000 1.647 +++ src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java 25 Sep 2007 15:28:12 -0000 @@ -39346,4 +39346,165 @@ }, ""); } +public void test1179() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {}\n" + + "\n", // ================= + }, + "----------\n" + + "1. ERROR in X.java (at line 1)\n" + + " public class X {}\n" + + " ^\n" + + "The type V is not an interface; it cannot be specified as a bounded parameter\n" + + "----------\n"); +} +public void test1180() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public static , R extends S & T> R max1(T arg1, S arg2) {\n" + + " return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + + " }\n" + + "\n" + + " public static , S, R extends S & Comparable> R max2(T arg1, S arg2) {\n" + + " return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + + " }\n" + + "\n" + + " public static , S, R extends Comparable> R max3(T arg1, S arg2) {\n" + + " return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + + " }\n" + + "\n" + + " public static void main(String[] args) {\n" + + " }\n" + + "}\n", // ================= + }, + "----------\n" + + "1. ERROR in X.java (at line 2)\n" + + " public static , R extends S & T> R max1(T arg1, S arg2) {\n" + + " ^\n" + + "Cannot specify any additional bound T when first bound is a type parameter\n" + + "----------\n" + + "2. WARNING in X.java (at line 3)\n" + + " return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Type safety: Unchecked cast from Object to R\n" + + "----------\n" + + "3. ERROR in X.java (at line 6)\n" + + " public static , S, R extends S & Comparable> R max2(T arg1, S arg2) {\n" + + " ^^^^^^^^^^\n" + + "Cannot specify any additional bound Comparable when first bound is a type parameter\n" + + "----------\n" + + "4. WARNING in X.java (at line 7)\n" + + " return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Type safety: Unchecked cast from Object to R\n" + + "----------\n" + + "5. WARNING in X.java (at line 11)\n" + + " return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Type safety: Unchecked cast from Object to R\n" + + "----------\n"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=204534 +public void _test1181() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public static , R extends S & T> R max(T arg1, S arg2) {\n" + + " return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + + " }\n" + + "\n" + + " public static , S, R extends S & Comparable> R max(T arg1, S arg2) {\n" + + " return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + + " }\n" + + "\n" + + " public static , S, R extends Comparable> R max(T arg1, S arg2) {\n" + + " return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + + " }\n" + + "\n" + + " public static void main(String[] args) {\n" + + " }\n" + + "}\n", // ================= + }, + "should not see errors like: R cannot be resolved to a type"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=204536 +public void test1182() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + "}\n", // ================= + }, + "----------\n" + + "1. ERROR in X.java (at line 1)\n" + + " public class X {\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n" + + "2. ERROR in X.java (at line 1)\n" + + " public class X {\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n" + + "3. ERROR in X.java (at line 1)\n" + + " public class X {\n" + + " ^^^^^^\n" + + "The type Object is not an interface; it cannot be specified as a bounded parameter\n" + + "----------\n"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=204536 - variation +public void test1183() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void foo(T t) {\n" + + " t.run();\n" + + " }\n" + + " \n" + + "}\n", // ================= + }, + "----------\n" + + "1. ERROR in X.java (at line 1)\n" + + " public class X {\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=204536 - variation +public void test1184() { + // check that unresolved first bound got erased into Object (and not Runnable) + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " T get() { return null; }\n" + + " void foo(X x) {\n" + + " Runnable r = x.get();\n" + + " }\n" + + " \n" + + "}\n", // ================= + }, + "----------\n" + + "1. ERROR in X.java (at line 1)\n" + + " public class X {\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n" + + "2. WARNING in X.java (at line 3)\n" + + " void foo(X x) {\n" + + " ^\n" + + "X is a raw type. References to generic type X should be parameterized\n" + + "----------\n" + + "3. ERROR in X.java (at line 4)\n" + + " Runnable r = x.get();\n" + + " ^^^^^^^\n" + + "Type mismatch: cannot convert from Object to Runnable\n" + + "----------\n"); +} } #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java,v retrieving revision 1.313 diff -u -r1.313 Scope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 24 Sep 2007 22:49:54 -0000 1.313 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 25 Sep 2007 15:28:14 -0000 @@ -447,11 +447,16 @@ return null; // incompatible } + /** + * Connect type variable supertypes, and returns true if no problem was detected + * @param typeParameters + * @param checkForErasedCandidateCollisions + */ protected boolean connectTypeVariables(TypeParameter[] typeParameters, boolean checkForErasedCandidateCollisions) { if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) return true; - boolean noProblems = true; Map invocations = new HashMap(2); - nextVariable : for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) { + boolean foundProblem = false; + nextVariable: for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) { TypeParameter typeParameter = typeParameters[i]; TypeVariableBinding typeVariable = typeParameter.binding; if (typeVariable == null) return false; @@ -464,95 +469,101 @@ TypeReference typeRef = typeParameter.type; if (typeRef == null) continue nextVariable; + boolean isFirstBoundTypeVariable = false; TypeBinding superType = this.kind == METHOD_SCOPE ? typeRef.resolveType((BlockScope)this, false/*no bound check*/) : typeRef.resolveType((ClassScope)this); if (superType == null) { typeVariable.tagBits |= TagBits.HierarchyHasProblems; - noProblems = false; - continue nextVariable; - } - typeRef.resolvedType = superType; // hold onto the problem type - if (superType.isArrayType()) { - problemReporter().boundCannotBeArray(typeRef, superType); - continue nextVariable; - } - boolean isTypeVariableFirstBound = superType.isTypeVariable(); - if (isTypeVariableFirstBound) { - TypeVariableBinding varSuperType = (TypeVariableBinding) superType; - if (varSuperType.rank >= typeVariable.rank && varSuperType.declaringElement == typeVariable.declaringElement) { - problemReporter().forwardTypeVariableReference(typeParameter, varSuperType); - typeVariable.tagBits |= TagBits.HierarchyHasProblems; - noProblems = false; - continue nextVariable; - } - } - ReferenceBinding superRefType = (ReferenceBinding) superType; - if (superRefType.isFinal()) - problemReporter().finalVariableBound(typeVariable, typeRef); - if (!superType.isInterface()) { - typeVariable.superclass = superRefType; } else { - typeVariable.superInterfaces = new ReferenceBinding[] {superRefType}; + typeRef.resolvedType = superType; // hold onto the problem type + firstBound: { + switch (superType.kind()) { + case Binding.ARRAY_TYPE : + problemReporter().boundCannotBeArray(typeRef, superType); + typeVariable.tagBits |= TagBits.HierarchyHasProblems; + break firstBound; // do not keep first bound + case Binding.TYPE_PARAMETER : + isFirstBoundTypeVariable = true; + TypeVariableBinding varSuperType = (TypeVariableBinding) superType; + if (varSuperType.rank >= typeVariable.rank && varSuperType.declaringElement == typeVariable.declaringElement) { + problemReporter().forwardTypeVariableReference(typeParameter, varSuperType); + typeVariable.tagBits |= TagBits.HierarchyHasProblems; + break firstBound; // do not keep first bound + } + break; + default : + if (((ReferenceBinding) superType).isFinal()) { + problemReporter().finalVariableBound(typeVariable, typeRef); + } + break; + } + ReferenceBinding superRefType = (ReferenceBinding) superType; + if (!superType.isInterface()) { + typeVariable.superclass = superRefType; + } else { + typeVariable.superInterfaces = new ReferenceBinding[] {superRefType}; + } + typeVariable.firstBound = superRefType; // first bound used to compute erasure + } } - typeVariable.firstBound = superRefType; // first bound used to compute erasure TypeReference[] boundRefs = typeParameter.bounds; if (boundRefs != null) { - for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) { + nextBound: for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) { typeRef = boundRefs[j]; superType = this.kind == METHOD_SCOPE ? typeRef.resolveType((BlockScope)this, false) : typeRef.resolveType((ClassScope)this); if (superType == null) { typeVariable.tagBits |= TagBits.HierarchyHasProblems; - noProblems = false; - continue nextVariable; - } - typeRef.resolvedType = superType; // hold onto the problem type - if (isTypeVariableFirstBound && j == 0) { - problemReporter().noAdditionalBoundAfterTypeVariable(typeRef); - } - if (superType.isArrayType()) { - problemReporter().boundCannotBeArray(typeRef, superType); - continue nextVariable; - } - superRefType = (ReferenceBinding) superType; - if (!superType.isInterface()) { - problemReporter().boundMustBeAnInterface(typeRef, superType); - typeVariable.tagBits |= TagBits.HierarchyHasProblems; - noProblems = false; - continue nextVariable; - } - // check against superclass - if (checkForErasedCandidateCollisions && typeVariable.firstBound == typeVariable.superclass) { - if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef)) { - noProblems = false; - continue nextVariable; + continue nextBound; + } else { + typeRef.resolvedType = superType; // hold onto the problem type + if (isFirstBoundTypeVariable && j == 0) { + problemReporter().noAdditionalBoundAfterTypeVariable(typeRef); + typeVariable.tagBits |= TagBits.HierarchyHasProblems; + //continue nextBound; - keep these bounds to minimize secondary errors } - } - // check against superinterfaces - for (int index = typeVariable.superInterfaces.length; --index >= 0;) { - ReferenceBinding previousInterface = typeVariable.superInterfaces[index]; - if (previousInterface == superRefType) { - problemReporter().duplicateBounds(typeRef, superType); + if (superType.isArrayType()) { + problemReporter().boundCannotBeArray(typeRef, superType); + typeVariable.tagBits |= TagBits.HierarchyHasProblems; + continue nextBound; + } + ReferenceBinding superRefType = (ReferenceBinding) superType; + if (!superType.isInterface()) { + problemReporter().boundMustBeAnInterface(typeRef, superType); typeVariable.tagBits |= TagBits.HierarchyHasProblems; - noProblems = false; - continue nextVariable; + continue nextBound; } - if (checkForErasedCandidateCollisions) { - if (hasErasedCandidatesCollisions(superType, previousInterface, invocations, typeVariable, typeRef)) { - noProblems = false; - continue nextVariable; + // check against superclass + if (checkForErasedCandidateCollisions && typeVariable.firstBound == typeVariable.superclass) { + if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef)) { + continue nextBound; + } + } + // check against superinterfaces + for (int index = typeVariable.superInterfaces.length; --index >= 0;) { + ReferenceBinding previousInterface = typeVariable.superInterfaces[index]; + if (previousInterface == superRefType) { + problemReporter().duplicateBounds(typeRef, superType); + typeVariable.tagBits |= TagBits.HierarchyHasProblems; + continue nextBound; + } + if (checkForErasedCandidateCollisions) { + if (hasErasedCandidatesCollisions(superType, previousInterface, invocations, typeVariable, typeRef)) { + continue nextBound; + } } } + int size = typeVariable.superInterfaces.length; + System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size); + typeVariable.superInterfaces[size] = superRefType; } - int size = typeVariable.superInterfaces.length; - System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size); - typeVariable.superInterfaces[size] = superRefType; } } + foundProblem |= (typeVariable.tagBits & TagBits.HierarchyHasProblems) != 0; } - return noProblems; + return !foundProblem; } public ArrayBinding createArrayType(TypeBinding type, int dimension) {