Skip to content

Allow Assertions.UNREACHABLE(...) in expressions#1998

Open
liblit wants to merge 1 commit into
wala:masterfrom
liblit:allow-Assertions.UNREACHABLE-in-expressions
Open

Allow Assertions.UNREACHABLE(...) in expressions#1998
liblit wants to merge 1 commit into
wala:masterfrom
liblit:allow-Assertions.UNREACHABLE-in-expressions

Conversation

@liblit

@liblit liblit commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Previously, the various overloads of Assertions.UNREACHABLE(...) returned void. Therefore, calls to these methods could be used as statements but not expressions. That restriction led to many code fragments like the following:

Assertions.UNREACHABLE();
return null;

An unfortunate side effect of that style was to make many methods appear to return nullable values even though the return null statement could never be reached.

Now the Asserions.UNREACHABLE(...) methods statically claim to return a value of any arbitrary type. In reality, they will never return at all; each such method always throws an exception. However, by pretending to return an arbitrarily typed value, we can now replace the above code pattern with:

return Assertions.UNREACHABLE();

This change should help us recognize that some methods can never return null, even though they contain unreachable code.

This change was inspired by several standard Kotlin features. The TODO(), TODO(String), and error(Any) functions all return type Nothing, which is a subtype of every other type. Kotlin's throw ... construct is also an expression (not a statement) with static type Nothing.

Also add JetBrains @Contract annotations to Asserions.UNREACHABLE(...) methods declaring that they always "fail" (i.e., throw exceptions) regardless of the arguments passed to them. Some static analysis tools may benefit from this information.

Previously, the various overloads of `Assertions.UNREACHABLE(...)`
returned `void`.  Therefore, calls to these methods could be used as
statements but not expressions.  That restriction led to many code
fragments like the following:

```java
Assertions.UNREACHABLE();
return null;
```

An unfortunate side effect of that style was to make many methods appear
to return nullable values even though the `return null` statement could
never be reached.

Now the `Asserions.UNREACHABLE(...)` methods statically claim to return
a value of any arbitrary type.  In reality, they will never return at
all; each such method always throws an exception.  However, by
_pretending_ to return an arbitrarily typed value, we can now replace
the above code pattern with:

```java
return Assertions.UNREACHABLE();
```

This change should help us recognize that some methods can never return
`null`, even though they contain unreachable code.

This change was inspired by several standard Kotlin features.  The
`TODO()`, `TODO(String)`, and `error(Any)` functions all return
type `Nothing`, which is a subtype of every other type.  Kotlin's
`throw ...` construct is also an expression (not a statement) with
static type `Nothing`.

Also add JetBrains `@Contract` annotations to
`Asserions.UNREACHABLE(...)` methods declaring that they always "fail"
(i.e., throw exceptions) regardless of the arguments passed to them.
Some static analysis tools may benefit from this information.
@liblit
liblit requested a review from msridhar July 15, 2026 20:52
@liblit liblit self-assigned this Jul 15, 2026
@liblit
liblit enabled auto-merge July 15, 2026 20:53
@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 1.54799% with 318 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.69%. Comparing base (df62e0f) to head (24d17f4).

Files with missing lines Patch % Lines
.../java/translator/jdt/FakeExceptionTypeBinding.java 0.00% 58 Missing ⚠️
...m/wala/cast/java/translator/jdt/JDT2CAstUtils.java 7.69% 18 Missing and 6 partials ⚠️
...st/java/translator/jdt/JDTJava2CAstTranslator.java 0.00% 16 Missing ⚠️
...in/java/com/ibm/wala/ipa/slicer/SDGSupergraph.java 0.00% 12 Missing ⚠️
.../main/java/com/ibm/wala/ipa/slicer/thin/CISDG.java 0.00% 11 Missing ⚠️
...java/com/ibm/wala/ipa/slicer/HeapReachingDefs.java 0.00% 10 Missing ⚠️
...java/com/ibm/wala/demandpa/util/ArrayContents.java 0.00% 8 Missing ⚠️
.../analysis/reflection/FactoryBypassInterpreter.java 0.00% 6 Missing ⚠️
.../callgraph/propagation/rta/TypeBasedHeapModel.java 0.00% 6 Missing ⚠️
...ore/src/main/java/com/ibm/wala/ipa/slicer/PDG.java 0.00% 6 Missing ⚠️
... and 95 more
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1998      +/-   ##
============================================
+ Coverage     50.51%   50.69%   +0.17%     
- Complexity    12695    12697       +2     
============================================
  Files          1368     1368              
  Lines         83799    83506     -293     
  Branches      14419    14419              
============================================
- Hits          42333    42331       -2     
+ Misses        36772    36478     -294     
- Partials       4694     4697       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown

Test Results

  918 files  ±0    918 suites  ±0   5h 36m 4s ⏱️ - 15m 57s
  834 tests ±0    815 ✅ ±0   19 💤 ±0  0 ❌ ±0 
5 722 runs  ±0  5 587 ✅ ±0  135 💤 ±0  0 ❌ ±0 

Results for commit 24d17f4. ± Comparison against base commit df62e0f.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant