Skip to content

Tracking Issue for Iterator::map_windows (feature iter_map_windows)Β #87155

Open

Description

@LukasKalbertodt

Feature gate: #![feature(iter_map_windows)]

This is a tracking issue for Iterator::map_windows:

Calls the given function f for each contiguous window of size N over self and returns an iterator over the outputs of f.

In the following example, the closure is called three times with the arguments &['a', 'b'], &['b', 'c'] and &['c', 'd'] respectively.

#![feature(iter_map_windows)]

let strings = "abcd".chars()
    .map_windows(|[x, y]| format!("{}+{}", x, y))
    .collect::<Vec<String>>();

assert_eq!(strings, vec!["a+b", "b+c", "c+d"]);

Public API

impl Iterator {
    fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
    where
        Self: Sized,
        F: FnMut(&[Self::Item; N]) -> R;
}

struct MapWindows<I: Iterator, F, const N: usize> { ... }

impl<I, F, R, const N: usize> Iterator for MapWindows<I, F, N>
where
    I: Iterator,
    F: FnMut(&[I::Item; N]) -> R;

impl<I: Iterator + fmt::Debug, F, const N: usize> fmt::Debug for MapWindows<I, F, N>;

Steps / History

  • Implementation: Add Iterator::map_windowsΒ #82413
  • Implementation: Add Iterator::map_windowsΒ #94667
  • Optimize with buffer of size 2 * N
  • Any other iterator-related traits?
    • DoubleEndedIterator
    • FusedIterator
    • TrustedLen
  • Compile fail on N=0, rather than panic. Blocked on a solution for compile errors in callers that are generic over N and would want a fallback for N=0.
  • Final comment period (FCP)
  • Stabilization PR

Unresolved Questions

Activity

  1. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    T-libs-api[DEPRECATED; DO NOT USE]
    on Jul 15, 2021
  2. dtolnay commented on Feb 28, 2023

    @dtolnay
    Member

    Copied from #94667 (comment):

    Taking GAT for consideration, should the mapper function be FnMut(&[I::Item; N]) -> R or something like FnMut(ArrayView<'_, I::Item, N>) -> R? Where ArrayView is mentioned in rust-lang/generic-associated-types-initiative#2.

    • It can save memory, only the same size as the array window is needed,
    • It is more efficient, which requires less data copies,
    • It is possibly compatible with the GATified version of LendingIterator::windows.
    • But it prevents the array pattern matching like iter.map_windows(|_arr: [_; N]| ()), unless we extend the array pattern to allow matching the ArrayView.
  3. added a commit that references this issue on May 18, 2023
  4. added a commit that references this issue on May 19, 2023
  5. added a commit that references this issue on May 19, 2023
  6. added a commit that references this issue on Aug 13, 2023
  7. Nydauron commented on Dec 11, 2023

    @Nydauron

    I have been working on implementing the compile-time check on N (Nydauron@31ffa40). Currently, the change works on all doc tests using ./x test library/core --doc -- Iterator::map_windows, but fails compilation when trying to run all tests ./x test library/core -- Iterator::map_windows with the following error:

    error[E0080]: evaluation of `std::iter::MapWindows::<std::iter::Repeat<i32>, {closure@library/core/tests/iter/adapters/map_windows.rs:173:46: 173:58}, 0>::N_NOT_ZERO` failed
        --> /home/<USER>/Git/rust/library/core/src/panic.rs:106:9
         |
    79   | / pub macro panic_2021 {
    80   | |     () => ({
    81   | |         // Create a function so that the argument for `track_caller`
    82   | |         // can be moved inside if possible.
    ...    |
    106  | |         $crate::panicking::panic_fmt($crate::const_format_args!($($t)+...
         | |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'array in `Iterator::map_windows` must contain more than 0 elements', /home/<USER>/Git/rust/library/core/src/iter/adapters/map_windows.rs:60:9
    107  | |     }),
    108  | | }
         | |_- in this expansion of `$crate::panic::panic_2021!` (#2)
         |
        ::: /home/<USER>/Git/rust/library/core/src/iter/adapters/map_windows.rs:60:9
         |
    60   |   ...   assert!(N != 0, "array in `Iterator::map_windows` must contain more than 0 elements...
         |         -------------------------------------------------------------------------------------
         |         |
         |         in this macro invocation (#1)
         |         in this macro invocation (#2)
         |
        ::: /home/<USER>/Git/rust/library/core/src/macros/mod.rs:1538:5
         |
    1538 | /     macro_rules! assert {
    1539 | |         ($cond:expr $(,)?) => {{ /* compiler built-in */ }};
    1540 | |         ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in ...
    1541 | |     }
         | |_____- in this expansion of `assert!` (#1)
    
    note: the above error was encountered while instantiating `fn std::iter::MapWindows::<std::iter::Repeat<i32>, {closure@library/core/tests/iter/adapters/map_windows.rs:173:46: 173:58}, 0>::new`
        --> /home/<USER>/Git/rust/library/core/src/iter/traits/iterator.rs:1747:9
         |
    1747 |         MapWindows::new(self, f)
         |         ^^^^^^^^^^^^^^^^^^^^^^^^
    
    For more information about this error, try `rustc --explain E0080`.
    error: could not compile `core` (test "coretests") due to previous error
    

    Any idea why this is happening on ./x test library/core and not ./x test library/core --doc?

    EDIT: Fixed the issue. It ended up being the test that checked for panic with a zero-width array.

  8. Jules-Bertholet commented on Apr 10, 2024

    @Jules-Bertholet
    Contributor

    From the docs:

    The returned iterator implements FusedIterator, because once self returns None, even if it returns a Some(T) again in the next iterations, we cannot put it into a contigious array buffer, and thus the returned iterator should be fused.

    I'm not sure I understand the reasoning here. Couldn't/shouldn't the iterator return overlapping windows for each run of successive Somes yielded by the inner iterator? IOW, remove this line:

  9. GrayJack commented on Nov 26, 2024

    @GrayJack
    Contributor

    Taking GAT for consideration, should the mapper function be FnMut(&[I::Item; N]) -> R or something like FnMut(ArrayView<'_, I::Item, N>) -> R? Where ArrayView is mentioned in rust-lang/generic-associated-types-initiative#2.

    • It can save memory, only the same size as the array window is needed,
    • It is more efficient, which requires less data copies,
    • It is possibly compatible with the GATified version of LendingIterator::windows.
    • But it prevents the array pattern matching like iter.map_windows(|_arr: [_; N]| ()), unless we extend the array pattern to allow matching the ArrayView.

    I like the idea of using ArrayView and making array pattern match ArrayView as well

  10. jobafr commented on Apr 17, 2025

    @jobafr

    It seems slice::array_chunks is being stabilized despite the N=0 case remaining unhandled at compile time:
    #74985

    Is this still a blocker here for reasons that aren't applicable to slice::array_chunks?

  11. Jules-Bertholet commented on Apr 17, 2025

    @Jules-Bertholet
    Contributor

    I’m not actually convinced we should be rejecting N = 0 at all. Unlike with array_chunks, there is a single obvious behavior for it here. But making it work without breaking the ExactSizeIterator impl requires language features we do not have yet.

  12. scottmcm commented on Apr 19, 2025

    @scottmcm
    Member

    Given that I was strongly against the "just allow zero" options for as_chunks, I figured I'd comment that I agree that those reasons don't apply here. Getting n+1 zero-length windows from a n-length input is 100% consistent with the other sizes, and even common if you look at matching the Ξ΅ regex against strings.

    (Said in the abstract. I agree there may be complicating practical concerns, like the ESI issue mentioned.)

  13. added a commit that references this issue on Mar 29, 2026
  14. added 2 commits that reference this issue on Mar 29, 2026
  15. added a commit that references this issue on Mar 29, 2026
  16. added
    T-libsRelevant to the library team, which will review and decide on the PR/issue.
    and removed
    T-libs-api[DEPRECATED; DO NOT USE]
    on Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions