pjfanning opened a new pull request, #3719:
URL: https://github.com/apache/pekko/pull/3719

   ### Motivation
   Java generics are invariant, so javadsl operators that take a `Graph` reject 
graphs of a narrower or wider element type even when the call is type safe: 
concatenating a `Source<Integer>` onto a `Source<Number>` needs 
`Source.upcast`, and a pre-typed `Sink<Object, ...>` or `Flow<Object, ...>` 
cannot be attached to a `Source<String>`. Functions returning `Optional`, 
`Iterable` or `Pair` are also still invariant in their element types after 
#3717 widened the function parameters themselves. These are items 1 and 2 from 
the follow-up comment on #3712.
   
   ### Modification
   - Widen `Graph` parameters across the stream javadsl, including graphs 
inside function results, `Iterable`s and `CompletionStage`s:
     - `Graph[SourceShape[T], M]` → `Graph[? <: SourceShape[? <: T], M]` 
(`concat`, `merge`, `zip*`, `interleave*`, `orElse`, `prepend*`, 
`flatMapConcat`, `recoverWith`, …)
     - `Graph[SinkShape[T], M]` → `Graph[? <: SinkShape[? >: T], M]` (`to`, 
`toMat`, `runWith`, `alsoTo*`, `wireTap*`, `divertTo*`, …)
     - `Graph[FlowShape[I, O], M]` → `Graph[? <: FlowShape[? >: I, O], M]` 
(`via`, `viaMat`, `join`, …)
     - The outer `? <:` is required: `Graph` itself is invariant in Java, so 
without it a `Graph<SourceShape<Integer>, M>` would not match even an exact 
`SourceShape<? extends Integer>`.
   - Widen `Optional[T]`, `java.lang.Iterable[T]` and `Pair[A, B]` where they 
are the result of a function parameter (`mapOption`, `mapConcat`, 
`statefulMap`, `unfold*`, `RetryFlow`, …).
   - Internals:
     - `sourceGraph`/`sinkGraph`/`flowGraph` helpers narrow the widened graphs 
before delegating to scaladsl. Scala 3.3 does not treat e.g. `SourceShape[? <: 
T]` as conforming to `SourceShape[T]` even though the shapes are variant; 
erasure is identical, so the casts are safe.
     - `optionalToScala`/`iterableToScala` helpers, because Scala 2 cannot 
apply the converters to the nested existential types; a cast in `unfold` where 
the internal stage takes an invariant function.
   - `RunnableGraphSpec`: give the javadsl round trip a concrete element type. 
Scala 2 cannot infer `Sink.ignore()` against `Graph[? <: SinkShape[? >: 
Nothing], ?]`; with any concrete element type, Scala callers using generic 
factories (`Sink.ignore()`, `Sink.seq`, `Source.empty()`, `Flow.create()`) 
still infer on 2.13 and 3.3.
   - Add MiMa excludes (`IncompatibleSignatureProblem` only) for the generic 
signature changes.
   
   ### Result
   Java callers can combine sources of a subtype and attach flows and sinks of 
a supertype without `upcast` or casts, and functions may return an 
`Optional`/`Iterable`/`Pair` of a subtype. Erasure is unchanged, so the change 
is binary compatible.
   
   ### Tests
   - `sbt "stream/compile" "++3.3.8 stream/compile"` - passed
   - `sbt "stream-tests/Test/compile"` (existing Java and Scala callers plus 
new tests) - passed
   - `sbt "stream/mimaReportBinaryIssues"` - passed with the added excludes
   - New directional tests (`mustAcceptGraphsOfNarrowerAndWiderElementTypes`, 
`mustAcceptFunctionsReturningOptionalsAndIterablesOfSubtypes` in `SourceTest`) 
not run locally - left to CI, along with the other modules' test compilation
   
   ### References
   Refs #3712, #3717


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to