Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spurious resource leak type.argument error on uses of method(SomeClass.class) #6666

Open
Calvin-L opened this issue Jun 11, 2024 · 2 comments

Comments

@Calvin-L
Copy link
Contributor

Given

import org.checkerframework.checker.mustcall.qual.InheritableMustCall;

public abstract class DotClass {

  abstract <T> void setup(Class<T> cls);

  public void run() {
    setup(Resource.class);
  }

  @InheritableMustCall("free")
  public static class Resource {
    public void free() {
    }
  }

}

The resource leak checker reports

DotClass.java:11: error: [type.argument] incompatible type argument for type parameter T extends @MustCall Object of DotClass.setup.
    setup(Resource.class);
         ^
  found   : @MustCall("free") Resource
  required: @MustCall Object

I am not sure why the Checker Framework infers T = @MustCall("free") Resource. Manually specifying the type parameter silences the warning, but is incredibly ugly:

this.<@MustCall({}) Resource>setup(Resource.class);

An awkward cast will also silence the warning:

setup((Class<@MustCall({}) Resource>)Resource.class);

But, it would be nice if the original code were accepted as-is without one of these verbose modifications.

@Calvin-L Calvin-L changed the title Spurious resource leak generics error on uses of method(SomeClass.class) Spurious resource leak type.argument error on uses of method(SomeClass.class) Jun 11, 2024
@msridhar
Copy link
Contributor

@skehrli does this issue relate to the defaulting changes you and @mernst were proposing for type variables? Maybe we could pull in that change separate from your other work?

@kelloggm
Copy link
Contributor

kelloggm commented Jul 1, 2024

I investigated this problem and I don't think it's related to the changes that @skehrli and @mernst were proposing. I don't observe quite the same issue that @Calvin-L reported on master, but a very similar one:

checker/tests/resourceleak/ClassLiteral.java:15: error: [type.arguments.not.inferred] Could not infer type arguments for ClassLiteral.setup
    setup(Resource.class);
         ^
  unsatisfiable constraint: @MustCall("free") Resource <: @MustCall Object
1 error

The problem doesn't seem to be (directly) related to the type that the RLC is assigning to Resource.class. For example, the following code passes the typechecker (which is consistent with @Calvin-L's notes about workarounds via casting):

  public static void test() {
    // A test for the failed constraint. Surprisingly, this assignment
    // does NOT fail, so the bad constraint is coming from somewhere else.
    @MustCall() Object obj = Resource.class;
  }

I think the problem is either with type inference or with the interaction between the inheritable class annotation @InheritableMustCall and type inference. @smillst, since you have been working on changes to type inference, I wonder if you have any idea what might cause this sort of behavior? The type of Resource.class should not be related to the type of Resource in the RLC, but it seems like it is.

Maybe this is related to the fact that the RLC implements the inheritability of @InheritableMustCall by modifying how the explicit annotations on Elements are computed (in MustCallAnnotatedTypeFactory)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants