Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions checker/tests/nullness/Issue771.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;

public class Issue771 {
private @MonotonicNonNull String value = null;

@RequiresNonNull("value")
void print() {
System.out.println(value);
}

void func() {
if (value == null) {
return;
}

Runnable r = () -> print();
}

private final @Nullable String finalValue;

Issue771(@Nullable String finalValue) {
this.finalValue = finalValue;
}

void finalField() {
if (finalValue == null) {
return;
}

Runnable r = () -> finalValue.toString();
}

private @Nullable String nullableValue;

void nullableField() {
if (nullableValue == null) {
return;
}

Runnable r =
() -> {
// :: error: (dereference.of.nullable)
nullableValue.toString();
};
nullableValue = null;
r.run();
}
}
2 changes: 1 addition & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ median of four warm-daemon reps per side).

**Closed issues:**

eisop#433, eisop#792, eisop#863, eisop#1801.
eisop#433, eisop#771, eisop#792, eisop#863, eisop#1801.


Version 3.49.5-eisop1 (April 26, 2026)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,17 @@ public S initialStore(UnderlyingAST underlyingAST, List<LocalVariableNode> param
addFinalLocalValues(store, enclosingElement);
}

// We want the initialization stuff, but need to throw out any refinements.
// We want the initialization stuff, but need to throw out refinements that might not
// still hold when the lambda is invoked later.
// Update values in place; keys are unchanged.
store.fieldValues.replaceAll(
(fieldAccess, currentValue) -> {
V laterValue =
store.newFieldValueAfterMethodCall(
fieldAccess, analysis.atypeFactory, currentValue);
if (laterValue != null) {
return laterValue;
}
AnnotatedTypeMirror declaredType =
atypeFactory.getAnnotatedType(fieldAccess.getField());
return analysis.createAbstractValue(declaredType)
Expand Down
Loading