From 0381096d0c0c8623d970444577e3bc3a73dcf8ca Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Tue, 12 May 2026 09:52:22 +0200 Subject: [PATCH 1/2] Move ToStreamBuilder's container builder to method generic Generic-over-Item trait with method-level CB enables method-call syntax `(0..3).to_stream_with_builder::<_, CB>(scope)` instead of the UFCS form `ToStreamBuilder::::to_stream_with_builder(...)`. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 4 ++++ .../src/dataflow/operators/core/to_stream.rs | 20 +++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d11c74a6..bd9e333f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Breaking changes + +- `ToStreamBuilder` is now generic over the item type instead of the container builder; the container builder moves to a method-level generic. This enables method-call syntax: `(0..3).to_stream_with_builder::<_, CapacityContainerBuilder<_>>(scope)` instead of the UFCS form `ToStreamBuilder::>::to_stream_with_builder(0..3, scope)`. + ## [0.29.0](https://github.com/TimelyDataflow/timely-dataflow/compare/timely-v0.28.1...timely-v0.29.0) - 2026-04-13 The theme in this release is simplifying specialization by removing monomorphization sprawl. diff --git a/timely/src/dataflow/operators/core/to_stream.rs b/timely/src/dataflow/operators/core/to_stream.rs index ef7b7648a..3201337c4 100644 --- a/timely/src/dataflow/operators/core/to_stream.rs +++ b/timely/src/dataflow/operators/core/to_stream.rs @@ -7,7 +7,7 @@ use crate::dataflow::operators::generic::operator::source; use crate::dataflow::{Stream, Scope}; /// Converts to a timely [Stream], using a container builder. -pub trait ToStreamBuilder { +pub trait ToStreamBuilder { /// Converts to a timely [Stream], using the supplied container builder type. /// /// # Examples @@ -18,10 +18,10 @@ pub trait ToStreamBuilder { /// use timely::container::CapacityContainerBuilder; /// /// let (data1, data2) = timely::example(|scope| { - /// let data1 = ToStreamBuilder::>::to_stream_with_builder(0..3, scope) + /// let data1 = (0..3).to_stream_with_builder::<_, CapacityContainerBuilder<_>>(scope) /// .container::>() /// .capture(); - /// let data2 = ToStreamBuilder::>::to_stream_with_builder(vec![0,1,2], scope) + /// let data2 = vec![0,1,2].to_stream_with_builder::<_, CapacityContainerBuilder<_>>(scope) /// .container::>() /// .capture(); /// (data1, data2) @@ -29,12 +29,16 @@ pub trait ToStreamBuilder { /// /// assert_eq!(data1.extract(), data2.extract()); /// ``` - fn to_stream_with_builder<'scope, T: Timestamp>(self, scope: Scope<'scope, T>) -> Stream<'scope, T, CB::Container>; + fn to_stream_with_builder<'scope, T: Timestamp, CB: ContainerBuilder>(self, scope: Scope<'scope, T>) -> Stream<'scope, T, CB::Container> + where + CB: PushInto; } -impl ToStreamBuilder for I where CB: PushInto { - fn to_stream_with_builder<'scope, T: Timestamp>(self, scope: Scope<'scope, T>) -> Stream<'scope, T, CB::Container> { - +impl ToStreamBuilder for I { + fn to_stream_with_builder<'scope, T: Timestamp, CB: ContainerBuilder>(self, scope: Scope<'scope, T>) -> Stream<'scope, T, CB::Container> + where + CB: PushInto + { source::<_, CB, _, _>(scope, "ToStreamBuilder", |capability, info| { // Acquire an activator, so that the operator can rescheduled itself. @@ -84,6 +88,6 @@ pub trait ToStream { impl ToStream for I where C: PushInto { fn to_stream<'scope, T: Timestamp>(self, scope: Scope<'scope, T>) -> Stream<'scope, T, C> { - ToStreamBuilder::>::to_stream_with_builder(self, scope) + ToStreamBuilder::to_stream_with_builder::<_, CapacityContainerBuilder>(self, scope) } } From c29924dfb38adf54b1e8f781fe5095fe0e69d882 Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Thu, 28 May 2026 15:24:43 -0400 Subject: [PATCH 2/2] Use associated type for ToStreamBuilder item Per review feedback: each implementor of `ToStreamBuilder` has exactly one item type (`I::Item` for the blanket impl), so an associated type fits better than a trait-level generic. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 2 +- timely/src/dataflow/operators/core/to_stream.rs | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd9e333f2..8887ceccf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking changes -- `ToStreamBuilder` is now generic over the item type instead of the container builder; the container builder moves to a method-level generic. This enables method-call syntax: `(0..3).to_stream_with_builder::<_, CapacityContainerBuilder<_>>(scope)` instead of the UFCS form `ToStreamBuilder::>::to_stream_with_builder(0..3, scope)`. +- `ToStreamBuilder` exposes the item type via the `Item` associated type instead of a trait-level generic, and the container builder moves to a method-level generic. This enables method-call syntax: `(0..3).to_stream_with_builder::<_, CapacityContainerBuilder<_>>(scope)` instead of the UFCS form `ToStreamBuilder::>::to_stream_with_builder(0..3, scope)`. ## [0.29.0](https://github.com/TimelyDataflow/timely-dataflow/compare/timely-v0.28.1...timely-v0.29.0) - 2026-04-13 diff --git a/timely/src/dataflow/operators/core/to_stream.rs b/timely/src/dataflow/operators/core/to_stream.rs index 3201337c4..f2ca61eb8 100644 --- a/timely/src/dataflow/operators/core/to_stream.rs +++ b/timely/src/dataflow/operators/core/to_stream.rs @@ -7,7 +7,10 @@ use crate::dataflow::operators::generic::operator::source; use crate::dataflow::{Stream, Scope}; /// Converts to a timely [Stream], using a container builder. -pub trait ToStreamBuilder { +pub trait ToStreamBuilder { + /// The item type produced by this iterator-like source. + type Item; + /// Converts to a timely [Stream], using the supplied container builder type. /// /// # Examples @@ -31,10 +34,12 @@ pub trait ToStreamBuilder { /// ``` fn to_stream_with_builder<'scope, T: Timestamp, CB: ContainerBuilder>(self, scope: Scope<'scope, T>) -> Stream<'scope, T, CB::Container> where - CB: PushInto; + CB: PushInto; } -impl ToStreamBuilder for I { +impl ToStreamBuilder for I { + type Item = I::Item; + fn to_stream_with_builder<'scope, T: Timestamp, CB: ContainerBuilder>(self, scope: Scope<'scope, T>) -> Stream<'scope, T, CB::Container> where CB: PushInto