Annotation Interface MustCallAlias


This polymorphic annotation represents an either-or must-call obligation. This annotation should always be used in pairs. On a method, it is written on some formal parameter type and on the method return type. On a constructor, it is written on some formal parameter type and on the result type. Fulfilling the must-call obligation of one is equivalent to fulfilling the must-call obligation of the other. Beyond its impact as a polymorphic annotation on MustCall types, the Resource Leak Checker uses MustCallAlias annotations to more precisely determine when a must-call obligation has been satisfied.

This annotation is useful for wrapper objects. For example, consider the declaration of java.net.Socket#getOutputStream:

 @MustCall("close")
 class Socket {
   @MustCallAlias OutputStream getOutputStream(@MustCallAlias Socket this) { ... }
 }
Calling close() on the returned OutputStream will close the underlying socket, but the Socket may also be closed directly, which has the same effect.

Type system semantics

Within the Must Call Checker's type system, @MustCallAlias annotations have a semantics different from a standard polymorphic annotation, in that the relevant actual parameter type and return type at a call site are not equated in all cases. Given an actual parameter p passed in a @MustCallAlias position at a call site, the return type of the call is defined as follows:
  • If the base return type has a non-empty @InheritableMustCall("m") annotation on its declaration, and p has a non-empty @MustCall type, then the return type is @MustCall("m").
  • In all other cases, the return type has the same @MustCall type as p.
PolyMustCall has an identical type system semantics. This special treatment is required to allow for a wrapper object to have a must-call method with a different name than the must-call method name for the wrapped object.

Verifying @MustCallAlias annotations

Suppose that @MustCallAlias is written on the type of formal parameter p.

For a constructor:

  • The constructor must always write p into exactly one field f of the new object.
  • Field f must be annotated @Owning.
For a method:
  • All return sites must be calls to other methods or constructors with @MustCallAlias return types, and this method's @MustCallAlias parameter must be passed in the MustCallAlias position to that method or constructor (i.e., the calls must pass @MustCallAlias parameter through a chain of @MustCallAlias-annotated parameters and returns).
When the -AnoResourceAliases command-line argument is passed to the checker, this annotation is treated identically to PolyMustCall. That is, the annotation still impacts MustCall types as a polymorphic annotation (see "Type system semantics" above), but it is not used by the Resource Leak Checker to more precisely reason about when obligations have been satisfied.
See the Checker Framework Manual:
Resource Leak Checker, Qualifier polymorphism