Closed ZacSweers closed 2 years ago
Thanks, @ZacSweers. We haven't tested with the latest CF release yet. I'm mostly on holiday until August 1 so I won't be able to personally look until then. In the meantime, a workaround may be to keep just the Checker Framework dataflow-nullaway artifact at 3.22.2. Having multiple CF versions floating around can sometimes cause problems, but since dataflow-nullaway is shadowed just for NullAway, it should be fine 🤞
I can definitely repro this by bumping CF on NullAway's master branch. Will take a look at the root cause, but, either way, until the next NullAway release is out, forcing dataflow-nullaway
to be 3.22.2 should be both necessary and sufficient to work around this.
Edit: Fun fact, quick delta debugging shows that this is being caused by this CF commit specifically causing input.getValueOfSubNode(node)
here to sometimes return null
, which were asserting was non-null (hey, good example of the risks of suppressing NullAway, even when we think we understand the object state preconditions!). Adding this for context in case I get dragged to something else before I have the time to debug this further, but please feel free to ignore this discussion until you are back from vacation, Manu. I'll keep digging if I can.
Basically, the issue is here, somehow in
ends up being an UnmodifiableIdentityHashMap.java and this.nodeValues
its underlying IdentityHashMap
. So, when the code calls this.nodeValues.clear()
it also clears the contents of in
. One way to fix this is to change UnmodifiableIdentityHashMap.wrap(...)
to make a copy if the map being wrapped isn't already immutable. I wonder if that will simply erase the advantages of that optimization, but the only other option is to impose the contract that, once an IdentityHashMap
has been wrapped through an immutable reference, the original map can't be used, and this seems hard to enforce in a reliable manner.
Thanks for digging, @lazaroclapp. That change to introduce UnmodifiableIdentityHashMap
was an optimization, but I didn't realize there is a way for the underlying IdentityHashMap
to still be modified (all the Checker Framework tests passed). I'll dig into this more when I get some time.
Do the NullAway regression tests fail with this change? Or just @ZacSweers's example? Edit: the NullAway tests also fail. I should have really run them before landing that change on Checker Framework...
This is now fixed upstream in Checker Framework. Once the next Checker Framework release comes out (early August most likely), the problem should be fixed. To try to avoid getting surprised like this in the future I'll try to set up a daily CI cron job that tests NullAway against the latest Checker Framework main branch.
FYI CF 3.24.0 is out now and this issue should not appear when updating to that version
When updating checker-framework (checker-qual) to 3.23.0, we see this NPE come from nullaway
where the source for that failure is the penultimate line in this source