Units Checker and null literals

57 views
Skip to first unread message

John Hovell

unread,
Aug 1, 2018, 1:25:53 PM8/1/18
to Checker Framework discussion
I have some projects that I am upgrading from checker 1.x to 2.x and getting some new failures that I am not sure how to resolve:

For example:

error: [return.type.incompatible] incompatible types in return.
            return null;
                   ^
 found   : @UnknownUnits  null
 required: @frac(Prefix.deci) Float

The error makes sense, but I am wondering if there is some way I can annotate my return of null to include the units. 

@frac is a custom units annotation I wrote for fractions but figure it would be the same for @m (meters) or a different unit

@frac @Nullable public Float myMethod(final String param) {
        if (param.equals("foo") {
            return null;
        }

        return MyCustomUnitsTools.FRAC * 3f;
    }

I have searched documentation for how to annotate null literals but haven't found how to handle this case, or if my code needs refactoring if there is a better pattern to follow. Is there a way to resolve these sorts of errors or a better pattern to follow for nullable units?

Thanks!

Werner Dietl

unread,
Aug 1, 2018, 2:53:38 PM8/1/18
to John Hovell, Jeff Luo, CF Discuss
Hi John,

thanks for the report! `null` actually is the bottom in the type
hierarchy and for built-in units annotations this works as you expect.
I've opened issue
https://github.com/typetools/checker-framework/issues/2087 to look
into why this doesn't work for custom units.

Best,
cu, WMD.
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "Checker Framework discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to checker-framework-...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
http://www.google.com/profiles/wdietl

Jeff Luo

unread,
Aug 1, 2018, 2:57:13 PM8/1/18
to John Hovell, Checker Framework discussion
Hi John,

The type of the null literal is programatically set by Units Checker to be @UnitsBottom, which is the bottom type of all units qualifiers. It shouldn't be necessary to annotate or cast, the null literal to any other unit as it is always a subtype of every unit.

I tried to reproduce your snippet in our live demo tool, but I'm not seeing any errors when using one of the built-in units as the return type. The issue here is that somehow null takes on @UnknownUnits as its unit when it shouldn't at all.

If absolutely necessary, you can cast the null literal, ie:  return (@m Float) null;

Jeff

On Wed, Aug 1, 2018 at 1:25 PM John Hovell <jho...@sunrun.com> wrote:
--

---
You received this message because you are subscribed to the Google Groups "Checker Framework discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to checker-framework-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
Jeff Luo
PhD Candidate, ECE, UWaterloo

John Hovell

unread,
Aug 1, 2018, 10:15:36 PM8/1/18
to Checker Framework discussion
Thanks all. I will try to put together a test case if this is not expected behavior. It could be a bug/issue on my end as the project is rather large/complex. I thought it might be because I had some checker 1.x classes sitting around on the class path but I cleaned that up and am still seeing the same behavior but need to do some more work to create an example.

I'll see if I can re-create in a simple project (using that demo tool assuming I can reproduce it there) and get back to you all. Thank you for the replies!
To unsubscribe from this group and stop receiving emails from it, send an email to checker-framework-discuss+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

John Hovell

unread,
Aug 4, 2018, 3:05:41 PM8/4/18
to Checker Framework discussion

John Hovell

unread,
Aug 4, 2018, 3:05:53 PM8/4/18
to Checker Framework discussion
I created a simple test but unfortunately it causes the checker framework to crash. Maybe this would be a good place to start? Not sure if that's because I am defining annotations as inner static classes but wasn't sure how else to do it in the demo tool.

Error: Could not load class 'Test.frac' for field 'quantity' in annotation @org.checkerframework.checker.units.qual.UnitsMultiple(quantity=Test.frac.class, prefix=org.checkerframework.checker.units.qual.Prefix.centi); The Checker Framework crashed.  Please report the crash.  To see the full stack trace invoke the compiler with -AprintErrorStack


http://eisop.uwaterloo.ca/live/#mode=display&code=import+org.checkerframework.checker.units.qual.*%3B%0A%0Aimport+org.checkerframework.framework.qual.SubtypeOf%3B%0A%0Aimport+java.lang.annotation.Documented%3B%0Aimport+java.lang.annotation.ElementType%3B%0Aimport+java.lang.annotation.Retention%3B%0Aimport+java.lang.annotation.RetentionPolicy%3B%0Aimport+java.lang.annotation.Target%3B%0A%0Apublic+class+Test+%7B%0A%0A++++/**%0A+++++*+Fraction%0A+++++*/%0A++++%40Documented%0A++++%40Retention(RetentionPolicy.RUNTIME)%0A++++%40Target(%7BElementType.TYPE_USE,+ElementType.TYPE_PARAMETER%7D)%0A++++%40SubtypeOf(UnknownUnits.class)%0A++++public+static+%40interface+frac+%7B%0A++++++++Prefix+value()+default+Prefix.one%3B%0A++++%7D%0A++++%0A++++/**%0A+++++*+Percent%0A+++++*/%0A++++%40Documented%0A++++%40Retention(RetentionPolicy.RUNTIME)%0A++++%40Target(%7BElementType.TYPE_USE,+ElementType.TYPE_PARAMETER%7D)%0A++++%40SubtypeOf(UnknownUnits.class)%0A++++%40UnitsMultiple(quantity%3Dfrac.class,+prefix%3DPrefix.centi)%0A++++public+static+%40interface+pct+%7B%0A++++%7D%0A%0A++++public+%40pct+Float+test(final+String+param)+%7B%0A++++++++if+(param.equals(%22foo%22))+%7B%0A++++++++++++return+null%3B%0A++++++++%7D%0A++++++%0A++++++++return+toFrac(3f)%3B%0A++++%7D%0A++++%0A++++%40SuppressWarnings(%22units%22)%0A++++%40pct+Float+toFrac(float+number)+%7B%0A++++++++return+number%3B%0A++++%7D%0A++++++++%0A%7D&typeSystem=units


Thanks all for the help!

On Wednesday, August 1, 2018 at 7:15:36 PM UTC-7, John Hovell wrote:

Werner Dietl

unread,
Aug 4, 2018, 4:05:39 PM8/4/18
to John Hovell, CF Discuss
Hi John,

re 1) In this example you have:

public @Nullable @m Float[] test(final String param) {
if (param.equals("foo")) {
return null;
}

The Units Checker is not complaining about this, but the Nullness
Checker gives you the correct error:

Error: [return.type.incompatible] incompatible types in return.
found : null
required: @Initialized @Nullable Float @Initialized @NonNull []

You probably meant `@m Float @Nullable []` as the return type. You
want to express that the method returns a possibly null array of @m
Float objects.
So you need to put the @Nullable in front of the array and the @m in
front of the component type.
The error message tries to highlight this by showing the `@NonNull []`
array type.
Does this make sense now?

re 2) Thanks for letting us know about the restriction with inner
static classes. I've filed
https://github.com/typetools/checker-framework/issues/2090 to look
into fixing this.
However, when I change your example to use top-level classes, I do not
get an error from the Units Checker about the return null.
Can you reproduce the original problem
https://github.com/typetools/checker-framework/issues/2087 with
top-level classes?

Best,
cu, WMD.
>>>> To unsubscribe from this group and stop receiving emails from it, send an email to checker-framework-...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>> --
>>> Jeff Luo
>>> PhD Candidate, ECE, UWaterloo
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "Checker Framework discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to checker-framework-...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
http://www.google.com/profiles/wdietl
Reply all
Reply to author
Forward
0 new messages