### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java,v retrieving revision 1.84 diff -u -r1.84 TypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java 11 Apr 2007 19:43:54 -0000 1.84 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java 13 Sep 2007 20:10:06 -0000 @@ -162,8 +162,15 @@ // iterate superclass to avoid recording interfaces if searched supertype is class if (erasureIsClass) { while ((currentType = currentType.superclass()) != null) { - if (currentType.id == wellKnownErasureID || (!currentType.isTypeVariable() && !currentType.isIntersectionType() && currentType.erasure().id == wellKnownErasureID)) + if (currentType.id == wellKnownErasureID) return currentType; + switch(currentType.kind()) { + case Binding.PARAMETERIZED_TYPE : + case Binding.RAW_TYPE : + case Binding.ARRAY_TYPE : + if (currentType.erasure().id == wellKnownErasureID) + return currentType; + } } return null; } @@ -191,9 +198,15 @@ for (int i = 0; i < nextPosition; i++) { currentType = interfacesToVisit[i]; - if (currentType.id == wellKnownErasureID || (!currentType.isTypeVariable() && !currentType.isIntersectionType() && currentType.erasure().id == wellKnownErasureID)) + if (currentType.id == wellKnownErasureID) return currentType; - + switch(currentType.kind()) { + case Binding.PARAMETERIZED_TYPE : + case Binding.RAW_TYPE : + case Binding.ARRAY_TYPE : + if (currentType.erasure().id == wellKnownErasureID) + return currentType; + } ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { int itsLength = itsInterfaces.length; @@ -216,7 +229,8 @@ public TypeBinding findSuperTypeWithSameErasure(TypeBinding otherType) { if (this == otherType) return this; if (otherType == null) return null; - switch(kind()) { + int kind; + switch(kind = kind()) { case Binding.ARRAY_TYPE : ArrayBinding arrayType = (ArrayBinding) this; int otherDim = otherType.dimensions(); @@ -253,13 +267,34 @@ case Binding.RAW_TYPE : case Binding.WILDCARD_TYPE : // do not allow type variables/intersection types to match with erasures for free - if (!otherType.isTypeVariable() && !otherType.isIntersectionType()) otherType = otherType.erasure(); - if (this == otherType || (!isTypeVariable() && !isIntersectionType() && erasure() == otherType)) return this; + switch(otherType.kind()) { + case Binding.PARAMETERIZED_TYPE : + case Binding.RAW_TYPE : + case Binding.ARRAY_TYPE : + otherType = otherType.erasure(); + } + if (this == otherType) + return this; + switch(kind) { + case Binding.PARAMETERIZED_TYPE : + case Binding.RAW_TYPE : + case Binding.ARRAY_TYPE : + if (erasure() == otherType) + return this; + } ReferenceBinding currentType = (ReferenceBinding)this; if (!otherType.isInterface()) { while ((currentType = currentType.superclass()) != null) { - if (currentType == otherType || (!currentType.isTypeVariable() && !currentType.isIntersectionType() && currentType.erasure() == otherType)) return currentType; + if (currentType == otherType) + return currentType; + switch(currentType.kind()) { + case Binding.PARAMETERIZED_TYPE : + case Binding.RAW_TYPE : + case Binding.ARRAY_TYPE : + if (currentType.erasure() == otherType) + return currentType; + } } return null; } @@ -287,9 +322,15 @@ for (int i = 0; i < nextPosition; i++) { currentType = interfacesToVisit[i]; - if (currentType == otherType || (!currentType.isTypeVariable() && !currentType.isIntersectionType() && currentType.erasure() == otherType)) + if (currentType == otherType) return currentType; - + switch(currentType.kind()) { + case Binding.PARAMETERIZED_TYPE : + case Binding.RAW_TYPE : + case Binding.ARRAY_TYPE : + if (currentType.erasure() == otherType) + return currentType; + } ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); if (itsInterfaces != Binding.NO_SUPERINTERFACES) { int itsLength = itsInterfaces.length; Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java,v retrieving revision 1.60 diff -u -r1.60 TypeVariableBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 15 May 2007 14:39:22 -0000 1.60 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 13 Sep 2007 20:10:06 -0000 @@ -75,13 +75,22 @@ if (!wildcardBound.isCompatibleWith(superclassBound)) return TypeConstants.MISMATCH; } else { - TypeBinding match = ((ReferenceBinding)wildcardBound).findSuperTypeWithSameErasure(superclassBound); + TypeBinding match = wildcardBound.findSuperTypeWithSameErasure(superclassBound); if (match != null) { if (!match.isIntersectingWith(superclassBound)) { return TypeConstants.MISMATCH; } } else { - return TypeConstants.MISMATCH; + match = superclassBound.findSuperTypeWithSameErasure(wildcardBound); + if (match != null) { + if (!match.isIntersectingWith(wildcardBound)) { + return TypeConstants.MISMATCH; + } + } else { + if (!wildcardBound.isTypeVariable() && !superclassBound.isTypeVariable()) { + return TypeConstants.MISMATCH; + } + } } } } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java,v retrieving revision 1.19 diff -u -r1.19 CaptureBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java 6 Jul 2006 11:20:36 -0000 1.19 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java 13 Sep 2007 20:10:06 -0000 @@ -101,25 +101,33 @@ switch (wildcard.boundKind) { case Wildcard.EXTENDS : // still need to capture bound supertype as well so as not to expose wildcards to the outside (111208) - TypeBinding substitutedWildcardBound = originalWildcardBound.capture(scope, this.position); + TypeBinding capturedWildcardBound = originalWildcardBound.capture(scope, this.position); if (wildcard.bound.isInterface()) { this.superclass = substitutedVariableSuperclass; // merge wildcard bound into variable superinterfaces using glb if (substitutedVariableInterfaces == Binding.NO_SUPERINTERFACES) { - this.superInterfaces = new ReferenceBinding[] { (ReferenceBinding) substitutedWildcardBound }; + this.superInterfaces = new ReferenceBinding[] { (ReferenceBinding) capturedWildcardBound }; } else { int length = substitutedVariableInterfaces.length; System.arraycopy(substitutedVariableInterfaces, 0, substitutedVariableInterfaces = new ReferenceBinding[length+1], 1, length); - substitutedVariableInterfaces[0] = (ReferenceBinding) substitutedWildcardBound; + substitutedVariableInterfaces[0] = (ReferenceBinding) capturedWildcardBound; this.superInterfaces = Scope.greaterLowerBound(substitutedVariableInterfaces); } } else { - // per construction the wildcard bound is a subtype of variable superclass - this.superclass = wildcard.bound.isArrayType() ? substitutedVariableSuperclass : (ReferenceBinding) substitutedWildcardBound; + // the wildcard bound should be a subtype of variable superclass + // it may occur that the bound is less specific, then consider glb (202404) + if (capturedWildcardBound.isArrayType() || capturedWildcardBound == this) { + this.superclass = substitutedVariableSuperclass; + } else { + this.superclass = (ReferenceBinding) capturedWildcardBound; + if (this.superclass.isSuperclassOf(substitutedVariableSuperclass)) { + this.superclass = substitutedVariableSuperclass; + } + } this.superInterfaces = substitutedVariableInterfaces; } - this.firstBound = substitutedWildcardBound; - if ((substitutedWildcardBound.tagBits & TagBits.HasTypeVariable) == 0) + this.firstBound = capturedWildcardBound; + if ((capturedWildcardBound.tagBits & TagBits.HasTypeVariable) == 0) this.tagBits &= ~TagBits.HasTypeVariable; break; case Wildcard.UNBOUND : #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.642 diff -u -r1.642 GenericTypeTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java 13 Sep 2007 16:51:29 -0000 1.642 +++ src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java 13 Sep 2007 20:10:21 -0000 @@ -21182,11 +21182,6 @@ " Store> store1;\n" + " ^\n" + "Bound mismatch: The type T is not a valid substitute for the bounded parameter > of the type Key\n" + - "----------\n" + - "2. ERROR in X.java (at line 6)\n" + - " Store> store2;\n" + - " ^^^^^^^^^^^\n" + - "Bound mismatch: The type ? extends T is not a valid substitute for the bounded parameter > of the type Key\n" + "----------\n"); } //check fault tolerance, in spite of bound mismatch, still pass param type for further resolving message send @@ -33911,23 +33906,18 @@ "Type mismatch: cannot convert from capture#4-of ? extends S to capture#1-of ? extends Long\n" + "----------\n"); } -//https://bugs.eclipse.org/bugs/show_bug.cgi?id=159214 +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=159214 - variation public void test1044() { - this.runNegativeTest( + this.runConformTest( new String[] { "X.java", "class X {\n" + " X x;\n" + "}", // ================= }, - "----------\n" + - "1. ERROR in X.java (at line 2)\n" + - " X x;\n" + - " ^^^^^^^^^^^^^^^^\n" + - "Bound mismatch: The type ? extends Object is not a valid substitute for the bounded parameter of the type X\n" + - "----------\n"); + ""); } -//https://bugs.eclipse.org/bugs/show_bug.cgi?id=159214 +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=159214 - variation public void test1045() { this.runConformTest( new String[] { @@ -38712,23 +38702,11 @@ "}\n", // ================= }, "----------\n" + - "1. ERROR in X.java (at line 10)\n" + - " D d2 = null;\n" + - " ^^^^^^^^^^^\n" + - "Bound mismatch: The type ? extends A is not a valid substitute for the bounded parameter of the type D\n" + - "----------\n" + - "2. ERROR in X.java (at line 11)\n" + + "1. ERROR in X.java (at line 11)\n" + " D d3 = null;\n" + " ^\n" + "Bound mismatch: The type C is not a valid substitute for the bounded parameter of the type D\n" + - "----------\n" -// TODO should be: -// "----------\n" + -// "1. ERROR in X.java (at line 11)\n" + -// " D d3 = null;\n" + -// " ^\n" + -// "Bound mismatch: The type C is not a valid substitute for the bounded parameter of the type D\n" + -// "----------\n" + "----------\n" ); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=202404 - variation @@ -38940,4 +38918,46 @@ "The final field X.mObj cannot be assigned\n" + "----------\n"); } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=202404 - variation +public void test1165() { + this.runNegativeTest( + new String[] { + "X.java", + " interface A {}\n" + + " class B implements A {}\n" + + " class C implements A{}\n" + + " \n" + + " class D {}\n" + + "\n" + + "public class X {\n" + + " void foo() {\n" + + " D d1 = null;\n" + + " D d2 = null;\n" + + " D d3 = null;\n" + + " D d4 = null;\n" + + " }\n" + + "}\n", // ================= + }, + "----------\n" + + "1. ERROR in X.java (at line 11)\n" + + " D d3 = null;\n" + + " ^\n" + + "Bound mismatch: The type C is not a valid substitute for the bounded parameter of the type D\n" + + "----------\n" + ); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=203318 +public void test1166() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " T get() { return null; };\n" + + " void foo(X x) {\n" + + " x.get().intValue(); \n" + + " }\n" + + "}\n", // ================= + }, + ""); +} }