typetools / typetools/checker-framework

Incorrect RLC inference of EnsuresCalledMethods for outer-class fields released by inner-class methods

Open
#6,988 3 comments 0 reactions 1 assignee View on GitHub

@iamsanjaymalakar is already working on this.

Since Mar 13, 2025.

bug ResourceLeakChecker
Dominant language
Java
Stars
1.1k
Forks
440
Avg merge
1d 12h
Merged PRs (30d)
134

Description

The inference for Resource Leak Checker's (RLC) annotations incorrectly infers the EnsuresCalledMethods annotation on outer-class resources that are closed by methods within an inner class.

For example:

class Foo {
    @Owning private final FileWriter fileWriter; 

    public Foo(File file) throws IOException {
        this.fileWriter = new FileWriter(file);
    }

    private class InnerFoo {
        // The inference incorrectly produces:
        // @EnsuresCalledMethods(value = { "this.fileWriter" }, methods = { "close" })
        public void close() throws IOException {
            fileWriter.close();
        }
    }
}

Here, the field fileWriter is declared and owned by the outer class Foo. However, since it is closed inside the inner class InnerFoo, the inference incorrectly annotates it as:

@EnsuresCalledMethods(value = { "this.fileWriter" }, methods = { "close" })

The reference this.fileWriter is incorrect because fileWriter is not a field of the inner class (InnerFoo), but a field of the outer class (Foo). If the annotation should be allowed at all, it needs to properly reference the field as belonging to the outer class.

Additionally, this situation raises some questions about intended behavior:

  • Should inference allow inner-class methods to ensure called methods on outer-class fields?
  • If yes, what should the correct syntax for referencing the outer-class field be? (e.g., Foo.this.fileWriter)
  • Given that the method performing the close operation belongs to the inner class, what should the inferred method name for InheritableMustCall annotation on the outer class be? In this scenario, it clearly cannot use the inner-class method directly as that method isn't accessible in the outer-class context.

I need some clarifications on the intended semantics and proper annotation references.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.