Skip to content

Conversation

@satler-git
Copy link
Member

@satler-git satler-git commented Oct 17, 2025

Summary by CodeRabbit

  • Refactor

    • Removed explicit lifetime parameters from public APIs (traits, wrappers, sources, UI, launcher, batcher, filters, sorters, actions, generators), simplifying generics, bounds and PhantomData usage for easier ergonomics and 'static-friendly usage.
  • Bug Fixes

    • Fixed naming/consistency issues and control-flow bugs (typos and run flow), aligned defaults and behaviors across batching and launcher paths.

@coderabbitai
Copy link

coderabbitai bot commented Oct 17, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This PR removes explicit lifetime parameters from core public traits and types (Action, Filter, Sorter, UI, Source, Launcher, Batcher), replaces per-lifetime bounds with Send/Sync/'static constraints, simplifies PhantomData usage, fixes naming typos (e.g., cusioncushion), and updates all related impls, wrappers, and tests accordingly.

Changes

Cohort / File(s) Summary
Core traits & type aliases
src/action.rs, src/filter.rs, src/sorter.rs, src/ui.rs, src/source.rs
Dropped lifetime params from public traits/type aliases (e.g., Action<'a>Action, Filter<'a>Filter, Source<'a,T>Source<T>). Removed associated-type lifetime bounds and adjusted trait signatures to use Send/Sync/'static constraints.
Closure implementations
src/action.rs, src/filter.rs, src/sorter.rs
Converted Closure*<'a, Context, F>Closure*<Context, F> and replaced PhantomData<&'a Context> with PhantomData<Context>. Removed 'a from where-clauses and normalized Send/Sync bounds for F and Context.
Wrapper types
src/action.rs, src/filter.rs, src/sorter.rs
Refactored *Wrapper<'a,...>*Wrapper<...>; updated PhantomData fields and impls to be lifetime-free; tightened transformer and inner-type bounds (Sync/Send and often 'static at public API boundaries).
Launcher & public API surfaces
src/launcher.rs
Removed lifetime from Launcher and migrated public methods to 'static where appropriate. Aligned associated types for sources/filters/sorters/actions/generators, fixed typos (cusion_to_uicushion_to_ui, compute_cusioncompute_cushion), and standardized parameter names (e.g., cushion).
Batcher internals
src/launcher/batcher.rs
Made Batcher lifetime-free (Batcher<Cushion, UIContext>), simplified type aliases and bounds, renamed fields/methods (cusion_*cushion_*, compute_cusioncompute_cushion), updated add_raw_* signatures to static-typed trait bounds, and adjusted tests.
Source utilities
src/source.rs
Source type alias made lifetime-free; from_iter/transform_source signatures updated to static bounds; mapping now uses stream .map(f) and iterator/generator bounds tightened to 'static.
UI & dummy UI tests
src/ui.rs, tests/dummyui.rs
UI<'a>UI, associated Context lifetime removed, run generics simplified to Send, DummyUI updated to remove lifetimes and adjust PhantomData and Batcher usage.
Misc & renames
multiple files under src/
Removed 'a from many impl blocks and trait objects, standardized trait object usage (e.g., Box<dyn Action<Context = ...>> without lifetimes), and corrected various naming inconsistencies.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐇 I nibbled through lifetimes, light and spry,
PhantomData shed a borrowed sigh,
Cusion turned to cushion, tidy and neat,
Traits let go of &'a — a lighter feat!
Hop, hop — the API now feels fleet.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "refactor: remove lifetime 'a and replace with 'static" is directly related to the main changes across all modified files. The changeset consistently removes the 'a lifetime parameter from trait definitions (Action, Filter, Sorter, UI), struct definitions (ClosureAction, ClosureFilter, ClosureSorter, ActionWrapper, FilterWrapper, SorterWrapper, Launcher, Batcher, and DummyUI), and their associated implementations. The title accurately reflects the core refactoring objective, though it should be noted that the "replace with 'static" aspect applies specifically to function bounds and public API signatures rather than uniformly across all lifetime removals. The title is concise, clear, and provides sufficient context for developers scanning the commit history to understand the nature of this significant API refactoring.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch push-lkxktnkxuoty

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e84e075 and 322341d.

📒 Files selected for processing (1)
  • src/launcher.rs (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/launcher.rs (4)
src/launcher/batcher.rs (4)
  • add_raw_source (380-382)
  • add_raw_filter (384-389)
  • add_raw_sorter (391-396)
  • add_raw_generator (398-403)
src/source.rs (1)
  • transform_source (14-25)
tests/dummyui.rs (2)
  • new (24-29)
  • run (39-65)
src/ui.rs (1)
  • run (6-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: review (ubuntu-latest)
  • GitHub Check: bench (ubuntu-latest)
  • GitHub Check: lint (ubuntu-latest)
  • GitHub Check: test (ubuntu-latest)
🔇 Additional comments (5)
src/launcher.rs (5)

13-23: LGTM: Lifetime removal from struct definition is clean.

The struct definition correctly removes the lifetime parameter and updates all field types accordingly. The Send and Sync bounds on Cushion and UIContext are appropriate for a launcher that needs to work across async boundaries.


126-133: Nice catch on the typo fix!

The method correctly updates bounds to 'static, and line 131 fixes the typo from cusion_to_ui to cushion_to_ui, which aligns with the correct field name.


152-166: LGTM: Consistent variable naming and clean implementation.

The run method now uses consistent cushion naming throughout (lines 153, 159, 161), and the explicit Ok(()) return on line 165 makes the control flow clearer.


58-124: LGTM: Consistent 'static bounds across all add methods.

All add_* and add_raw_* methods correctly apply 'static bounds to their type parameters. The pattern is consistent:

  • Transformers require Send + 'static for closures that may move across threads
  • Context types require Sync + Send + 'static when they need to be stored and shared
  • Raw types require 'static to ensure they can be stored in the internal vectors

This is appropriate for a launcher that needs to own and manage these components throughout its lifetime.


13-197: The review comment accurately characterizes the breaking API change, but sandbox limitations prevent verification of compilation/tests.

The git history confirms this PR removes the generic lifetime parameter 'a across Launcher, trait bounds (Filter, Action, Sorter, Generator), and wrapper types, replacing it with 'static bounds. This is a necessary constraint for async code using tokio.

Verification findings:

  • Code change is consistent across all related files (launcher.rs, batcher.rs, action.rs, filter.rs, sorter.rs, source.rs, ui.rs)
  • All visible test code uses i32 (which is 'static), making tests compatible with the new bounds
  • The architectural change is sound for async concurrent workloads
  • Cannot run cargo build/test due to sandbox environment constraints (/proc not mounted)

Since this is a breaking change for external users, manually verify that the full test suite passes with cargo test --all before merging.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @satler-git, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the codebase by eliminating the explicit lifetime parameter 'a from various core traits (Action, Filter, Sorter, UI) and their implementations. This change simplifies the type system, making the code more ergonomic and less verbose, particularly in the context of asynchronous operations and trait objects. By leveraging implicit 'static bounds where appropriate and adjusting PhantomData usage, the PR aims to improve the overall maintainability and flexibility of the component architecture.

Highlights

  • Lifetime Simplification: The explicit lifetime parameter 'a has been removed from the Action, Filter, Sorter, and UI traits, as well as their associated Closure and Wrapper structs. This simplifies type signatures and reduces boilerplate.
  • 'static Bounds Introduction: Where necessary, especially for closures and types stored within structs that need to live for the entire program duration, the 'static lifetime bound has been introduced. This ensures that the types can be safely held without a shorter lifetime constraint.
  • PhantomData Updates: PhantomData<&'a Context> has been changed to PhantomData<Context> in ClosureAction, ClosureFilter, ClosureSorter, ActionWrapper, FilterWrapper, SorterWrapper, and DummyUI, reflecting the removal of the explicit lifetime parameter.
  • Cushion Naming Consistency: In src/launcher/batcher.rs, the field cusion_to_ui was renamed to cushion_to_ui, and several variable names and method calls using cusion were corrected to cushion for consistency.
  • Ordering Clarity: In src/launcher/batcher.rs, the create_sorter function now explicitly uses std::cmp::Ordering::Equal instead of just Equal, improving clarity.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant refactoring that removes the generic lifetime 'a and replaces it with 'static bounds. This simplifies the overall API and has been applied consistently across multiple files. I appreciate the additional fixes for the 'cusion' -> 'cushion' typo, which improves code clarity. The changes look good, but I've found a couple of minor issues in src/sorter.rs where leftover code from the refactoring has resulted in an unnecessary trait bound and a syntax error.

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 17, 2025

CodSpeed Performance Report

Merging #28 will not alter performance

Comparing push-lkxktnkxuoty (322341d) with main (c81033b)

Summary

✅ 4 untouched

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/launcher/batcher.rs (1)

188-209: Fix borrow-across-await in prepare(): clone input before awaiting.

You capture &self.state.input inside async blocks, holding a borrow of self across .await. This is a common compile-time error. Also, Relaxed load suffices after join_all.

         let gen_len = self.generators.len();
         if self.state.gen_index < gen_len && batch_count > 0 {
             use std::sync::atomic::{AtomicUsize, Ordering};
 
             let len = AtomicUsize::new(0);
+            // Avoid borrowing `self` across `.await`
+            let input = self.state.input.clone();
+            let len_ref = &len;
 
             let gen_count_to_run = batch_count.min(gen_len - self.state.gen_index);
 
             // Iterator<Item = impl Future<Output = Vec<Cushion>>>
             // でjoin_allでFutureを解決して
-            let cushions_from_gen = self.generators
+            let cushions_from_gen = self.generators
                 [self.state.gen_index..(self.state.gen_index + gen_count_to_run)]
                 .iter()
-                .map(|r#gen| async {
-                    let cushions = r#gen.generate(&self.state.input).await.into_iter();
-                    // 最終結果で計算が終わったあとの長さにしか興味がないからRelaxedで問題ない
-                    len.fetch_add(cushions.len(), Ordering::Relaxed);
-                    cushions
-                });
+                .map(|gen| {
+                    let input = input.clone();
+                    async move {
+                        let cushions = gen.generate(&input).await.into_iter();
+                        // Only final value matters -> Relaxed is fine
+                        len_ref.fetch_add(cushions.len(), Ordering::Relaxed);
+                        cushions
+                    }
+                });
 
             let cushions_from_gen = futures::future::join_all(cushions_from_gen)
                 .await
                 .into_iter()
                 .flatten();
 
-            v.reserve(len.load(Ordering::SeqCst));
+            v.reserve(len.load(Ordering::Relaxed));
             for c in cushions_from_gen {

Also applies to: 213-215

src/launcher.rs (1)

168-171: Doc default vs. implementation: filter_and.

Docs state default=false, but Batcher default is currently true. If you adopt the Batcher fix (set false), this doc is correct; otherwise update the doc.

Do you want me to update the doc comment if you decide to keep default=true?

🧹 Nitpick comments (11)
src/ui.rs (1)

3-9: Add explicit Context bounds to encode invariants.

Batcher<_, Self::Context> and downstream wrappers expect thread-safety. Recommend bounding Context at the trait to avoid scattered bounds on impls.

-pub trait UI {
-    type Context;
+pub trait UI {
+    type Context: Sync + Send + 'static;
tests/dummyui.rs (1)

16-17: Prefer non‑owning PhantomData to avoid misleading drop/auto‑trait semantics.

PhantomData<T> models ownership of T. If DummyUI does not logically own T, use a non‑owning marker to keep covariance and avoid unintended Send/Drop implications.

-    _marker: PhantomData<T>,
+    _marker: PhantomData<fn() -> T>,
src/source.rs (2)

3-3: Make 'static explicit on the trait object to match the new API stance.

Given call sites now enforce 'static on inputs/closures, make the alias explicit for clarity.

-pub type Source<T> = Pin<Box<dyn tokio_stream::Stream<Item = T> + Send>>;
+pub type Source<T> = Pin<Box<dyn tokio_stream::Stream<Item = T> + Send + 'static>>;

14-21: Use FnMut to match StreamExt::map’s bound.

map requires FnMut. Requiring Fn is stricter than needed and blocks common mutable‑closure use cases.

-pub fn transform_source<Cushion, SourceContext, F>(
+pub fn transform_source<Cushion, SourceContext, F>(
     source: Source<SourceContext>,
     f: F,
 ) -> Source<Cushion>
 where
-    SourceContext: 'static,
-    F: Fn(SourceContext) -> Cushion + Send + 'static,
+    SourceContext: 'static,
+    F: FnMut(SourceContext) -> Cushion + Send + 'static,
 {
     use tokio_stream::StreamExt as _;
 
     Box::pin(source.map(f))
 }
src/sorter.rs (1)

36-46: Align bounds between struct and impl.

Struct requires SorterContext: Sync, impl requires SorterContext: Sync + Send. Align these to reduce surprise; also consider non‑owning PhantomData.

 pub struct SorterWrapper<SorterContext, SorterT, F, Cushion>
 where
-    F: Fn(&Cushion) -> SorterContext + Send,
-    SorterT: Sorter<Context = SorterContext>,
-    SorterContext: Sync,
+    F: Fn(&Cushion) -> SorterContext + Send,
+    SorterT: Sorter<Context = SorterContext>,
+    SorterContext: Sync + Send,
 {
@@
-    _marker: PhantomData<(SorterContext, Cushion)>,
+    _marker: PhantomData<(fn() -> SorterContext, Cushion)>,
src/filter.rs (3)

5-7: Encode Context invariants on the trait.

Most wrappers require Context: Sync + Send. Add it here to centralize constraints.

-pub trait Filter: Send {
-    type Context;
+pub trait Filter: Send {
+    type Context: Sync + Send + 'static;

36-45: Align struct bounds with impl and prefer non‑owning PhantomData.

Struct has FilterContext: Sync while the impl needs Sync + Send. Align and switch PhantomData form.

 pub struct FilterWrapper<FilterContext, FilterT, F, Cushion>
 where
-    F: Fn(&Cushion) -> FilterContext + Send,
-    FilterT: Filter<Context = FilterContext>,
+    F: Fn(&Cushion) -> FilterContext + Send,
+    FilterT: Filter<Context = FilterContext>,
@@
-    _marker: PhantomData<(FilterContext, Cushion)>,
+    _marker: PhantomData<(fn() -> FilterContext, Cushion)>,

62-69: Match struct bounds with impl usage.

Make the constructor’s bounds consistent with the impl (FilterContext: Sync + Send).

 impl<FilterContext, FilterT, F, Cushion> FilterWrapper<FilterContext, FilterT, F, Cushion>
 where
-    F: Fn(&Cushion) -> FilterContext + Send,
-    FilterT: Filter<Context = FilterContext>,
-    FilterContext: Sync,
-    Cushion: Send,
+    F: Fn(&Cushion) -> FilterContext + Send,
+    FilterT: Filter<Context = FilterContext>,
+    FilterContext: Sync + Send,
+    Cushion: Send,
 {
src/launcher/batcher.rs (1)

379-403: Minor: avoid alias/generic name shadowing in add_raw_ for readability.*

FilterT/SorterT are both a type alias and a generic parameter name here. Rename the generics to Flt/Srt/Gn to reduce confusion. No behavior change.

-    pub(super) fn add_raw_filter<FilterT>(&mut self, filter: FilterT)
+    pub(super) fn add_raw_filter<Flt>(&mut self, filter: Flt)
     where
-        FilterT: Filter<Context = Cushion> + 'static,
+        Flt: Filter<Context = Cushion> + 'static,
 { ... }
 
-    pub(super) fn add_raw_sorter<SorterT>(&mut self, sorter: SorterT)
+    pub(super) fn add_raw_sorter<Srt>(&mut self, sorter: Srt)
     where
-        SorterT: Sorter<Context = Cushion> + 'static,
+        Srt: Sorter<Context = Cushion> + 'static,
 { ... }
 
-    pub(super) fn add_raw_generator<GenT>(&mut self, generator: GenT)
+    pub(super) fn add_raw_generator<Gn>(&mut self, generator: Gn)
     where
-        GenT: Generator<Item = Cushion> + Sync + Send + 'static,
+        Gn: Generator<Item = Cushion> + Sync + Send + 'static,
 { ... }
src/action.rs (1)

37-47: Use PhantomData<fn(&Cushion)> to reflect reference-only dependency.

Current PhantomData models ownership; fn(&Cushion) models a borrow and improves variance semantics. Same idea applies to ClosureAction’s PhantomData.

-    _marker: PhantomData<Cushion>,
+    _marker: PhantomData<fn(&Cushion)>,

Optionally:

-pub struct ClosureAction<Context, F>(F, PhantomData<Context>)
+pub struct ClosureAction<Context, F>(F, PhantomData<fn(&Context)>)
src/launcher.rs (1)

126-133: Align set_ui bound with stored type.

set_ui requires Fn + Send + Sync + 'static, but Batcher’s CushionToUIF previously stored only +Send. After applying the Batcher alias update (+Sync+'static), these are consistent. If you choose not to change Batcher, drop +Sync here.

No code diff here if you applied the Batcher alias change. Otherwise:

-        F: Fn(&Cushion) -> UIContext + Send + Sync + 'static,
+        F: Fn(&Cushion) -> UIContext + Send + 'static,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c81033b and 5e10869.

📒 Files selected for processing (8)
  • src/action.rs (3 hunks)
  • src/filter.rs (3 hunks)
  • src/launcher.rs (3 hunks)
  • src/launcher/batcher.rs (15 hunks)
  • src/sorter.rs (3 hunks)
  • src/source.rs (1 hunks)
  • src/ui.rs (1 hunks)
  • tests/dummyui.rs (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
src/ui.rs (2)
src/launcher.rs (1)
  • run (152-166)
tests/dummyui.rs (1)
  • run (39-65)
tests/dummyui.rs (2)
src/launcher.rs (1)
  • run (152-166)
src/ui.rs (1)
  • run (6-9)
src/sorter.rs (4)
src/action.rs (2)
  • new (20-22)
  • new (69-76)
src/filter.rs (2)
  • new (19-21)
  • new (69-76)
tests/dummyui.rs (1)
  • new (24-29)
src/generator.rs (2)
  • new (24-26)
  • new (79-85)
src/action.rs (4)
src/filter.rs (2)
  • new (19-21)
  • new (69-76)
src/sorter.rs (2)
  • new (19-21)
  • new (70-76)
tests/dummyui.rs (1)
  • new (24-29)
src/generator.rs (2)
  • new (24-26)
  • new (79-85)
src/filter.rs (4)
src/action.rs (2)
  • new (20-22)
  • new (69-76)
src/sorter.rs (2)
  • new (19-21)
  • new (70-76)
tests/dummyui.rs (1)
  • new (24-29)
src/generator.rs (2)
  • new (24-26)
  • new (79-85)
src/launcher/batcher.rs (1)
src/launcher.rs (5)
  • add_raw_source (66-69)
  • add_raw_filter (80-86)
  • add_raw_sorter (97-103)
  • add_raw_generator (144-150)
  • default (31-37)
src/launcher.rs (4)
src/launcher/batcher.rs (4)
  • add_raw_source (380-382)
  • add_raw_filter (384-389)
  • add_raw_sorter (391-396)
  • add_raw_generator (398-403)
src/source.rs (1)
  • transform_source (14-25)
tests/dummyui.rs (2)
  • new (24-29)
  • run (39-65)
src/ui.rs (1)
  • run (6-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: bench (ubuntu-latest)
  • GitHub Check: review (ubuntu-latest)
🔇 Additional comments (5)
src/ui.rs (1)

6-9: No issues found—UI trait is used only generically.

The verification confirms the original review comment's concern is accurate but not problematic. The UI trait uses RPITIT, which does make it non-object-safe, but ripgrep found zero instances of dyn UI or Box<dyn UI> in the codebase. Instead, UI is used exclusively as a generic type parameter (e.g., Launcher<Cushion, UIT, UIContext> where UIT: UI<Context = UIContext>), which is fully compatible with RPITIT. The code is correct as-is.

tests/dummyui.rs (1)

32-43: LGTM on lifetime removal and compute_cushion fix verified.

Verification confirms:

  • Misspelling compute_cusion successfully removed from codebase
  • Correct spelling compute_cushion in use (tests/dummyui.rs:61, src/launcher/batcher.rs:126)
  • Bounds T: Sync + Send, F: Fn(&T) + Sync correctly ensure async run returns impl Future + Send satisfying trait requirements
src/source.rs (1)

5-12: The review comment is incorrect—no breaking changes identified.

The verification found that all current call sites to from_iter pass iterators that are already 'static (ranges like 0..COUNT, owned Vec, etc.). The 'static bound is semantically necessary for the return type Source<T> when it's a Box<Pin<...>> without an explicit lifetime parameter—by default, trait objects in boxes implicitly require 'static bounds unless the type carries a lifetime. Since there are no call sites passing non-'static iterators, removing the bound would only be beneficial if the API were redesigned to carry a lifetime (e.g., Source<'a, T>), which is not the case here. The stated concern about breaking existing code does not apply to the current codebase.

Likely an incorrect or invalid review comment.

src/action.rs (1)

4-8: Lifetimes removal looks solid; bounds are sensible.

Action is Send; ClosureAction enforces F: Send and Context: Sync; impl requires Context: Sync+Send. Good.

If desired, I can add From for ClosureAction to ease construction.

Also applies to: 10-23, 25-35

src/launcher.rs (1)

58-69: API surface is coherent post-lifetime removal.

add_* wrappers and raw variants have consistent 'static bounds and match the new non-lifetime traits. Good cleanup.

Consider adding small examples in docs showing typical transformer closures now that lifetimes are gone.

Also applies to: 80-87, 88-96, 97-103, 105-115, 117-124, 135-143, 144-151

@satler-git satler-git merged commit a3bed5b into main Oct 17, 2025
6 checks passed
@satler-git satler-git deleted the push-lkxktnkxuoty branch October 17, 2025 17:06
@coderabbitai coderabbitai bot mentioned this pull request Oct 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants