This is the finding when I do #1434.
For explicitly annotated intersection types, CF choose the primary annotation for the intersection from the first bound in the qualifier hierarchy, rather than computing a semantically meaningful qualifier such as the GLB of the bound annotations.
This makes diagnostics order-sensitive. In the Tainting Checker, @Untainted <: @Tainted, so it is surprising that:
(@Tainted Object & @Untainted I)
is treated as:
@Tainted Object & @Tainted I
and the explicit @Untainted annotation is reported as ignored.
Minimal Test Case
import org.checkerframework.checker.tainting.qual.Tainted;
import org.checkerframework.checker.tainting.qual.Untainted;
class TaintedIntersectionOrder {
interface I {}
void firstBoundTainted() {
@Untainted Object x = (@Tainted Object & @Untainted I) null;
}
void firstBoundUntainted() {
@Untainted Object x = (@Untainted Object & @Tainted I) null;
}
}
Command
./checker/bin/javac \
-processor org.checkerframework.checker.tainting.TaintingChecker \
TaintedIntersectionOrder.java
Actual Output
TaintedIntersectionOrder.java:9: error: [assignment.type.incompatible] incompatible types in assignment.
@Untainted Object x = (@Tainted Object & @Untainted I) null;
^
found : @Tainted Object & @Tainted I
required: @Untainted Object
TaintedIntersectionOrder.java:9: warning: [explicit.annotation.ignored] The qualifier @Untainted is ignored in favor of @Tainted. Either delete @Untainted or change it to @Tainted.
@Untainted Object x = (@Tainted Object & @Untainted I) null;
^
TaintedIntersectionOrder.java:14: warning: [explicit.annotation.ignored] The qualifier @Tainted is ignored in favor of @Untainted. Either delete @Tainted or change it to @Untainted.
@Untainted Object x = (@Untainted Object & @Tainted I) null;
^
1 error
2 warnings
Expected / Question
Is this intended behavior? If the intersection combines annotations from multiple bounds in the same hierarchy, should the primary annotation be computed using the qualifier hierarchy instead of depending on the first bound?
For Tainting, it seems like @Untainted Object & @Tainted I and @Tainted Object & @Untainted I should not produce opposite “ignored annotation” choices solely due to bound order.
How should this behave for hierarchies like PICO or viewpoint test checker, for example, @Immutable Object & @Mutable SomeInterface? If the qualifiers' GLB is bottom, should the Checker Framework reject the intersection type as uninhabitable, or is there a use case where such an intersection should remain expressible with a warning?
This is the finding when I do #1434.
For explicitly annotated intersection types, CF choose the primary annotation for the intersection from the first bound in the qualifier hierarchy, rather than computing a semantically meaningful qualifier such as the GLB of the bound annotations.
This makes diagnostics order-sensitive. In the Tainting Checker,
@Untainted <: @Tainted, so it is surprising that:is treated as:
and the explicit
@Untaintedannotation is reported as ignored.Minimal Test Case
Command
Actual Output
Expected / Question
Is this intended behavior? If the intersection combines annotations from multiple bounds in the same hierarchy, should the primary annotation be computed using the qualifier hierarchy instead of depending on the first bound?
For Tainting, it seems like
@Untainted Object & @Tainted Iand@Tainted Object & @Untainted Ishould not produce opposite “ignored annotation” choices solely due to bound order.How should this behave for hierarchies like PICO or viewpoint test checker, for example,
@Immutable Object & @Mutable SomeInterface? If the qualifiers' GLB is bottom, should the Checker Framework reject the intersection type as uninhabitable, or is there a use case where such an intersection should remain expressible with a warning?