Conversation
|
This change is part of the following stack: Change managed by git-spice. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1813 +/- ##
============================================
+ Coverage 87.67% 87.92% +0.25%
- Complexity 3499 3581 +82
============================================
Files 110 111 +1
Lines 11641 12034 +393
Branches 2403 2468 +65
============================================
+ Hits 10206 10581 +375
- Misses 657 666 +9
- Partials 778 787 +9 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
c7b6872 to
107b239
Compare
a63ed66 to
1f52bb7
Compare
2811af1 to
ae70300
Compare
5d13c7e to
100dbd1
Compare
|
The inference engine in this PR is more general than its API. A PolyNull group is a synthetic type variable bounded by // Optional<T>
<S extends @Nullable T> S orElseGet(Supplier<? extends S> supplier)
// Map<K, V>
<S extends @Nullable V> S computeIfAbsent(K key, Function<? super K, ? extends S> mappingFunction)Plain Java cannot declare these, because a real Could If you agree with this reading, the javadoc could describe a location as a position of a nullness-only method type variable, rather than as PolyNull. That would leave room for the following, none of which needs to be in this PR:
In both cases, the new source would feed the existing |
To be clear, the ask is both for a group id and that each group is handled with a separate constraint variable during solving, is that correct? I'm a bit unclear on the motivation. Do you have a concrete example?
Yeah, that is weird. Probably the safe thing to do here is assert fail if more then one handler tries to add polynull locations for the same method. Alternately, maybe this doesn't belong in handlers, and instead we should "hard code" the fact that only library models provide polynull locations; but that might be messier.
In terms of priorities, the reason I am working on PolyNull for library models is that without it, we get a very big number of false positives with JDK library models enabled for calls to methods like I'm also open to unchecked (trusted)
👍 |
|
Thanks, that clears up the priorities. On group ids: yes, I meant a separate solver variable per group, but I withdraw the request. I looked for a method that needs two independent groups and found none. The Checker Framework manual defines every occurrence of a polymorphic qualifier in a method as the same qualifier, so CF-annotated code cannot have two groups: all 171 That search turned up a different gap: the receiver. @PolyNull @PolySigned Object[] toArray(List<@PolyNull @PolySigned E> this);and the same pattern appears in more than 30 On merging: the same union also happens one level down. |
👍
Absolutely, we should fix this. Thanks for finding this issue!! I'll at least try to fix the API in this PR, though perhaps will add full support in a follow-up.
This is a good point. I think we should probably assert in both places for now. One could hypothetically imagine user-provided |
|
Note to self: we should probably also model |
100dbd1 to
aefee7d
Compare
Retain the upstream fallback to the capture upper bound when javac omits the formal type variable on an unbounded wildcard. Assisted-by: Codex (gpt-6)
aefee7d to
b7a2ecd
Compare
Fixes #1616.
Add JSpecify-mode library model support for polymorphic nullness in method signatures. Library model providers can identify top-level or nested parameter and return locations whose nullness must resolve together at each invocation.
Represent the linked nullness with a fresh, nullable-bounded synthetic inference variable for each call. Generate constraints from named arguments, lambdas, method references, and available result target types, and solve these constraints alongside ordinary generic method type-variable inference. Apply the resolved
@Nullableor@NonNullqualifier back to every modeled location in the call-site method type. Report a dedicated inference diagnostic when the linked locations impose incompatible constraints.Initially model
Optional.orElseGetandMap.computeIfAbsent, including calls through overriding methods. Extend nested type-path updates to replace types during inference and to preserve wildcard and captured-type structure when applying the resolved qualifier.Add tests covering named functional-interface arguments, lambdas, method references,
varresults, assignment targets, inherited models, explicit and inferred generic type arguments, and custom library model providers.Assisted-by: Codex (GPT-5)