rewrite-static-analysis icon indicating copy to clipboard operation
rewrite-static-analysis copied to clipboard

RemoveRedundantTypeCast should not remove required downcast

Open protocol7 opened this issue 8 months ago • 1 comments

Adds a failing test case for where RemoveRedundantTypeCast should not remove a downcast that is necessary for chained calls to get matching types.

protocol7 avatar Apr 06 '25 11:04 protocol7

Thanks for the runnable example!

timtebeek avatar Apr 06 '25 14:04 timtebeek

This PR is stale because it has been open for 90 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Jul 07 '25 04:07 github-actions[bot]

Summary

I successfully fixed the dontRemoveNecessaryDowncast test in RemoveRedundantTypeCastTest. The issue was that the recipe was incorrectly removing a type cast in a generic method call chain:

Optional.of((Bar) getBarImpl()).orElse(getBar())

The cast (Bar) is necessary here because:

  1. Without the cast, Optional.of(getBarImpl()) returns Optional<BarImpl>
  2. With the cast, Optional.of((Bar) getBarImpl()) returns Optional<Bar>
  3. The orElse(getBar()) method requires Optional<Bar> since getBar() returns Bar

The fix adds a special case check in the RemoveRedundantTypeCast recipe that preserves type casts when:

  1. The cast is inside a method invocation
  2. The cast is widening a type (e.g., from BarImpl to Bar)
  3. The method returns a parameterized (generic) type

This ensures that casts that affect generic type inference are preserved, preventing type compatibility issues in method chains.

timtebeek avatar Jul 21 '25 19:07 timtebeek

Nice work!

protocol7 avatar Jul 21 '25 20:07 protocol7