Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2013-12-05 22:26:14 +0000
committerStephan Herrmann2013-12-05 22:26:14 +0000
commit160d5d061fcfc93582f0fe36646007e32719bbb7 (patch)
tree203f6c604fb663851c757f4ec06aaabace0388bc
parent35cbca7e1c2b3f9e91f39afaa6acf75948770ff1 (diff)
downloadeclipse.jdt.core-160d5d061fcfc93582f0fe36646007e32719bbb7.tar.gz
eclipse.jdt.core-160d5d061fcfc93582f0fe36646007e32719bbb7.tar.xz
eclipse.jdt.core-160d5d061fcfc93582f0fe36646007e32719bbb7.zip
Fix GenericsRegressionTest.testBug413958_2(): avoid CaptureBinding18 as
intersection with inconsistent parameterization (was causing non-determinism). Also handle multiple upper bounds in more situations
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java97
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java3
2 files changed, 98 insertions, 2 deletions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
index 0af93f39b5..b3c2d8f086 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
@@ -25,13 +25,24 @@ public class CaptureBinding18 extends CaptureBinding {
super(contextType, sourceName, 0, captureID, environment);
}
- public void setUpperBounds(TypeBinding[] upperBounds, ReferenceBinding javaLangObject) {
+ public boolean setUpperBounds(TypeBinding[] upperBounds, ReferenceBinding javaLangObject) {
this.upperBounds = upperBounds;
if (upperBounds.length > 0)
this.firstBound = upperBounds[0];
int numReferenceInterfaces = 0;
for (int i = 0; i < upperBounds.length; i++) {
TypeBinding aBound = upperBounds[i];
+ if (!aBound.isWildcard() && !aBound.isTypeVariable() && aBound.isProperType(false)) {
+ // check for inconsistency between any two real types:
+ for (int j = 0; j < upperBounds.length; j++) {
+ if (i == j) continue;
+ TypeBinding otherBound = upperBounds[j];
+ if (!otherBound.isWildcard() && !otherBound.isTypeVariable() && otherBound.isProperType(false))
+ if (aBound.erasure().isCompatibleWith(otherBound.erasure()))
+ if (!aBound.isCompatibleWith(otherBound))
+ return false;
+ }
+ }
if (aBound instanceof ReferenceBinding) {
if (this.superclass == null && aBound.isClass())
this.superclass = (ReferenceBinding) upperBounds[i];
@@ -49,6 +60,7 @@ public class CaptureBinding18 extends CaptureBinding {
}
if (this.superclass == null)
this.superclass = javaLangObject;
+ return true;
}
public TypeBinding clone(TypeBinding enclosingType) {
@@ -61,6 +73,17 @@ public class CaptureBinding18 extends CaptureBinding {
return super.getMethods(selector);
}
+ public TypeBinding erasure() {
+ if (this.upperBounds != null && this.upperBounds.length > 1) {
+ ReferenceBinding[] erasures = new ReferenceBinding[this.upperBounds.length];
+ for (int i = 0; i < this.upperBounds.length; i++) {
+ erasures[i] = (ReferenceBinding) this.upperBounds[i].erasure(); // FIXME cast?
+ }
+ return new IntersectionCastTypeBinding(erasures, this.environment);
+ }
+ return super.erasure();
+ }
+
/**
* @see TypeBinding#isEquivalentTo(TypeBinding)
*/
@@ -102,6 +125,78 @@ public class CaptureBinding18 extends CaptureBinding {
return super.isCompatibleWith(otherType, captureScope);
}
+ public TypeBinding findSuperTypeOriginatingFrom(TypeBinding otherType) {
+ if (this.upperBounds != null && this.upperBounds.length > 1) {
+ for (int i = 0; i < this.upperBounds.length; i++) {
+ TypeBinding candidate = this.upperBounds[i].findSuperTypeOriginatingFrom(otherType);
+ if (candidate != null)
+ return candidate;
+ // TODO: do we need explicit handling of cases where several upperBounds produce a non-null candidate?
+ }
+ }
+ return super.findSuperTypeOriginatingFrom(otherType);
+ }
+
+ TypeBinding substituteInferenceVariable(InferenceVariable var, TypeBinding substituteType) {
+ if (this.inRecursiveFunction) return this;
+ this.inRecursiveFunction = true;
+ try {
+ boolean haveSubstitution = false;
+ ReferenceBinding currentSuperclass = this.superclass;
+ if (currentSuperclass != null) {
+ currentSuperclass = (ReferenceBinding) currentSuperclass.substituteInferenceVariable(var, substituteType);
+ haveSubstitution |= TypeBinding.notEquals(currentSuperclass, this.superclass);
+ }
+ ReferenceBinding[] currentSuperInterfaces = null;
+ if (this.superInterfaces != null) {
+ int length = this.superInterfaces.length;
+ if (haveSubstitution)
+ System.arraycopy(this.superInterfaces, 0, currentSuperInterfaces=new ReferenceBinding[length], 0, length);
+ for (int i = 0; i < length; i++) {
+ ReferenceBinding currentSuperInterface = this.superInterfaces[i];
+ if (currentSuperInterface != null) {
+ currentSuperInterface = (ReferenceBinding) currentSuperInterface.substituteInferenceVariable(var, substituteType);
+ if (TypeBinding.notEquals(currentSuperInterface, this.superInterfaces[i])) {
+ if (currentSuperInterfaces == null)
+ System.arraycopy(this.superInterfaces, 0, currentSuperInterfaces=new ReferenceBinding[length], 0, length);
+ currentSuperInterfaces[i] = currentSuperInterface;
+ haveSubstitution = true;
+ }
+ }
+ }
+ }
+ TypeBinding[] currentUpperBounds = null;
+ if (this.upperBounds != null) {
+ int length = this.upperBounds.length;
+ if (haveSubstitution)
+ System.arraycopy(this.upperBounds, 0, currentUpperBounds=new TypeBinding[length], 0, length);
+ for (int i = 0; i < length; i++) {
+ TypeBinding currentBound = this.upperBounds[i];
+ if (currentBound != null) {
+ currentBound = currentBound.substituteInferenceVariable(var, substituteType);
+ if (TypeBinding.notEquals(currentBound, this.upperBounds[i])) {
+ if (currentUpperBounds == null)
+ System.arraycopy(this.upperBounds, 0, currentUpperBounds=new TypeBinding[length], 0, length);
+ currentUpperBounds[i] = currentBound;
+ haveSubstitution = true;
+ }
+ }
+ }
+ }
+ if (haveSubstitution) {
+ CaptureBinding18 newCapture = (CaptureBinding18) clone(enclosingType());
+ newCapture.superclass = currentSuperclass;
+ newCapture.superInterfaces = currentSuperInterfaces;
+ newCapture.upperBounds = currentUpperBounds;
+ newCapture.tagBits = this.tagBits;
+ return newCapture;
+ }
+ return this;
+ } finally {
+ this.inRecursiveFunction = false;
+ }
+ }
+
boolean isProperType(boolean admitCapture18) {
return admitCapture18;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
index 5ed8e7e788..8694c4102a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
@@ -546,7 +546,8 @@ public class InferenceContext18 {
TypeBinding[] glbs = Scope.greaterLowerBound(substitutedUpperBounds, this.scope, this.environment);
if (glbs == null)
return false;
- typeVariable.setUpperBounds(glbs, this.object);
+ if (!typeVariable.setUpperBounds(glbs, this.object))
+ return false;
}
return true;
}

Back to the top