diff --git a/framework/src/org/checkerframework/framework/type/DefaultTypeHierarchy.java b/framework/src/org/checkerframework/framework/type/DefaultTypeHierarchy.java index 5a643197cff..a389bbf96cb 100644 --- a/framework/src/org/checkerframework/framework/type/DefaultTypeHierarchy.java +++ b/framework/src/org/checkerframework/framework/type/DefaultTypeHierarchy.java @@ -314,18 +314,6 @@ protected boolean isSubtypeOfAll(final AnnotatedTypeMirror subtype, return true; } - protected boolean isSubtypeOfAny(final AnnotatedTypeMirror subtype, - final Iterable supertypes, - final VisitHistory visited ) { - for (final AnnotatedTypeMirror supertype : supertypes) { - if (isSubtype(subtype, supertype, visited)) { - return true; - } - } - - return false; - } - protected boolean areAllSubtypes(final Iterable subtypes, final AnnotatedTypeMirror supertype, final VisitHistory visited) { @@ -338,18 +326,6 @@ protected boolean areAllSubtypes(final Iterable s return true; } - protected boolean areAnySubtypes(final Iterable subtypes, - final AnnotatedTypeMirror supertype, - final VisitHistory visited) { - for (final AnnotatedTypeMirror subtype : subtypes) { - if (isSubtype(subtype, supertype, visited)) { - return true; - } - } - - return false; - } - protected boolean areEqual(final AnnotatedTypeMirror type1, final AnnotatedTypeMirror type2 ) { return equalityComparer.areEqual(type1, type2); } @@ -541,7 +517,14 @@ public Boolean visitDeclared_Typevar(AnnotatedDeclaredType subtype, AnnotatedTyp @Override public Boolean visitDeclared_Union(AnnotatedDeclaredType subtype, AnnotatedUnionType supertype, VisitHistory visited) { - return visitUnionSupertype(subtype, supertype, visited); + Types types = checker.getTypeUtils(); + for (AnnotatedDeclaredType supertypeAltern : supertype.getAlternatives()) { + if (TypesUtils.isErasedSubtype(types, subtype.getUnderlyingType(), supertypeAltern.getUnderlyingType()) + && isSubtype(subtype, supertypeAltern)) { + return true; + } + } + return false; } @Override @@ -553,24 +536,63 @@ public Boolean visitDeclared_Wildcard(AnnotatedDeclaredType subtype, AnnotatedWi // Intersection as subtype @Override public Boolean visitIntersection_Declared(AnnotatedIntersectionType subtype, AnnotatedDeclaredType supertype, VisitHistory visited) { - return visitIntersectionSubtype(subtype, supertype, visited); + for (AnnotatedDeclaredType subtypeI : subtype.directSuperTypes()) { + Types types = checker.getTypeUtils(); + if (TypesUtils.isErasedSubtype(types, subtypeI.getUnderlyingType(), supertype.getUnderlyingType()) + && isSubtype(subtypeI, supertype)) { + return true; + } + } + return false; } @Override public Boolean visitIntersection_Primitive(AnnotatedIntersectionType subtype, AnnotatedPrimitiveType supertype, VisitHistory visited) { - return visitIntersectionSubtype(subtype, supertype, visited); + for (AnnotatedDeclaredType subtypeI : subtype.directSuperTypes()) { + if (TypesUtils.isBoxedPrimitive(subtypeI.getUnderlyingType()) && isSubtype(subtypeI, supertype)) { + return true; + } + } + return false; } @Override public Boolean visitIntersection_Intersection(AnnotatedIntersectionType subtype, AnnotatedIntersectionType supertype, VisitHistory visited) { - return visitIntersectionSubtype(subtype, supertype, visited); + Types types = checker.getTypeUtils(); + for (AnnotatedDeclaredType subtypeI : subtype.directSuperTypes()) { + for (AnnotatedDeclaredType supertypeI : supertype.directSuperTypes()) { + if (TypesUtils.isErasedSubtype(types, subtypeI.getUnderlyingType(), supertypeI.getUnderlyingType()) + && !isSubtype(subtypeI, supertypeI)) { + return false; + } + } + } + return true; } @Override public Boolean visitIntersection_Null(AnnotatedIntersectionType subtype, AnnotatedNullType supertype, VisitHistory visited) { // this can occur through capture conversion/comparing bounds - return visitIntersectionSubtype(subtype, supertype, visited); + for (AnnotatedDeclaredType subtypeI : subtype.directSuperTypes()) { + if (isPrimarySubtype(subtypeI, supertype)) { + return true; + } + } + return false; + } + + @Override + public Boolean visitIntersection_Typevar(AnnotatedIntersectionType subtype, AnnotatedTypeVariable supertype, VisitHistory visited) { + // this can occur through capture conversion/comparing bounds + for (AnnotatedDeclaredType subtypeI : subtype.directSuperTypes()) { + Types types = checker.getTypeUtils(); + if (TypesUtils.isErasedSubtype(types, subtypeI.getUnderlyingType(), supertype.getUnderlyingType()) + && isSubtype(subtypeI, supertype)) { + return true; + } + } + return false; } //------------------------------------------------------------------------ @@ -604,7 +626,12 @@ public Boolean visitNull_Null(AnnotatedNullType subtype, AnnotatedNullType super @Override public Boolean visitNull_Union(AnnotatedNullType subtype, AnnotatedUnionType supertype, VisitHistory visited) { - return visitUnionSupertype(subtype, supertype, visited); + for (AnnotatedDeclaredType supertypeAltern : supertype.getAlternatives()) { + if (isSubtype(subtype, supertypeAltern)) { + return true; + } + } + return false; } @Override @@ -719,11 +746,7 @@ public Boolean visitTypevar_Typevar(AnnotatedTypeVariable subtype, AnnotatedType // @X T xt = ...; T t = ..; // xt = t; // - // we do not want to implement visitIntersection_Typevar because that would make it ok - // to call is subtype on an intersection and typevar which shouldn't happen - // instead we perform the subtyping here - return visitIntersectionSubtype((AnnotatedIntersectionType) subtype.getUpperBound(), - supertype.getLowerBound(), visited); + return visit(subtype.getUpperBound(), supertype.getLowerBound(), visited); } } @@ -798,13 +821,6 @@ protected boolean visitIntersectionSupertype(AnnotatedTypeMirror subtype, Annota return isSubtypeOfAll(subtype, supertype.directSuperTypes(), visited); } - /** - * An intersection is a subtype if any of its bounds is a subtype of supertype - */ - protected boolean visitIntersectionSubtype(AnnotatedIntersectionType subtype, AnnotatedTypeMirror supertype, VisitHistory visited) { - return areAnySubtypes(subtype.directSuperTypes(), supertype, visited); - } - /** * A type variable is a supertype if its lower bound is above subtype. */ @@ -826,13 +842,6 @@ protected boolean visitTypevarSubtype(AnnotatedTypeVariable subtype, AnnotatedTy return checkAndSubtype(upperBound, supertype, visited); } - /** - * A union is a supertype if ONE of its alternatives is a supertype of subtype - */ - protected boolean visitUnionSupertype(AnnotatedTypeMirror subtype, AnnotatedUnionType supertype, VisitHistory visited) { - return isSubtypeOfAny(subtype, supertype.getAlternatives(), visited); - } - /** * A union type is a subtype if ALL of its alternatives are subtypes of supertype */