diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 7f61db958b83..cd42cb7b2235 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -142,7 +142,7 @@ Other improvements and bug fixes: **Closed issues:** -eisop#433, eisop#792, eisop#863, eisop#1015, eisop#1074, eisop#1801, eisop#1819. +eisop#433, eisop#786, eisop#792, eisop#863, eisop#1015, eisop#1074, eisop#1801, eisop#1819. Version 3.49.5-eisop1 (April 26, 2026) diff --git a/framework/src/main/java/org/checkerframework/framework/type/GenericAnnotatedTypeFactory.java b/framework/src/main/java/org/checkerframework/framework/type/GenericAnnotatedTypeFactory.java index a8eae969d9a8..1f290cd3ef2d 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/GenericAnnotatedTypeFactory.java +++ b/framework/src/main/java/org/checkerframework/framework/type/GenericAnnotatedTypeFactory.java @@ -122,7 +122,6 @@ import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; -import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; @@ -935,18 +934,6 @@ public QualifierPolymorphism getQualifierPolymorphism() { // Factory Methods for the appropriate annotator classes // ********************************************************************** - @Override - protected void postDirectSuperTypes( - AnnotatedTypeMirror type, List supertypes) { - super.postDirectSuperTypes(type, supertypes); - if (type.getKind() == TypeKind.DECLARED) { - for (AnnotatedTypeMirror supertype : supertypes) { - Element elt = ((DeclaredType) supertype.getUnderlyingType()).asElement(); - addComputedTypeAnnotations(elt, supertype); - } - } - } - /** * Returns the primary annotation with {@code clazz} on {@code expression}'s type, at a * particular location. The returned annotation may be null even if the expression should have a diff --git a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java index 92e007a13b4a..b55e85600656 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -322,6 +322,10 @@ private List supertypesFromElement( adt.setIsUnderlyingTypeRaw(); } } + + for (AnnotatedDeclaredType adt : supertypes) { + atypeFactory.addComputedTypeAnnotations(adt.getUnderlyingType().asElement(), adt); + } return supertypes; } @@ -351,7 +355,14 @@ private List supertypesFromTree( TypeElement elem = TreeUtils.elementFromDeclaration(classTree); if (elem.getKind() == ElementKind.ENUM) { - supertypes.add(createEnumSuperType(type, elem)); + // Unlike the extends/implements supertypes above (which come from + // getAnnotatedTypeFromTypeTree already defaulted), the enum super type is built + // via toAnnotatedType(..., false) and is undefaulted. The element path defaults + // every supertype in a trailing loop; the tree path has none, so default it here. + AnnotatedDeclaredType enumSuperType = createEnumSuperType(type, elem); + atypeFactory.addComputedTypeAnnotations( + enumSuperType.getUnderlyingType().asElement(), enumSuperType); + supertypes.add(enumSuperType); } if (type.isUnderlyingTypeRaw()) { for (AnnotatedDeclaredType adt : supertypes) { diff --git a/framework/tests/viewpointtest/GenericSelfContainedCrash.java b/framework/tests/viewpointtest/GenericSelfContainedCrash.java new file mode 100644 index 000000000000..b53e78b7d124 --- /dev/null +++ b/framework/tests/viewpointtest/GenericSelfContainedCrash.java @@ -0,0 +1,9 @@ +// Test case for EISOP issue #786: +// https://github.com/eisop/checker-framework/issues/786 +public class GenericSelfContainedCrash { + interface Box {} + + static class BoxImpl implements Box {} + + protected BoxImpl field; +}