Skip to content

Box<[T]> should have an IntoIter implementation. #59878

Closed

Description

@emilio

Right now the only way to move out of a Box<[T]> is using into_vec, which is a bit inconvenient. Is there any reason Box<[T]> shouldn't implement IntoIter?

Activity

  1. SimonSapin commented on Apr 11, 2019

    @SimonSapin
    Contributor

    Unfortunately this has the same issue as #25725: boxed_slice.into_iter() works today through auto-deref (then auto-ref?) to <&[T] as IntoIterator>::into_iter, so adding this impl would change the meaning of (some) existing code.

    Whatever we end up deciding should probably apply to both.

    CC @rust-lang/libs

  2. SimonSapin commented on Apr 11, 2019

    @SimonSapin
    Contributor

    Unlike with arrays though, this case has a work-around in converting though Vec<T>.

  3. scottmcm commented on Apr 16, 2019

    @scottmcm
    Member

    So we could add the implementation today, using Vec::from(self).into_iter() to make a vec::IntoIter? Seems like there wouldn't even be a need to make a new iterator type...

  4. cuviper commented on Apr 16, 2019

    @cuviper
    Member

    The user could work around this by going through Vec, and the nice thing is that this has no real cost -- it's just a bit awkward.

    But if std did this, we would run into the same problems as arrays, where calling into_iter() today on a Box<[T]> gets you a slice::Iter. So it's a breaking change to add IntoIterator -- technically minor and allowable, but needs caution.

  5. SimonSapin commented on Apr 16, 2019

    @SimonSapin
    Contributor

    @scottmcm Yes, the implementation is easy and does not require a new type. The concern is only in the change being breaking.

  6. LukasKalbertodt commented on Dec 29, 2019

    @LukasKalbertodt
    Contributor

    @SimonSapin Do you think it would be a good idea to add a future-incompatibility lint for this, like we did for the array.into_iter() problem (#66145)? In particular, because you said "Whatever we end up deciding should probably apply to both." This was suggested here.

  7. cuviper commented on Mar 28, 2021

    @cuviper
    Member

    FWIW, I just tried adding Box<[T]> and Box<[T; N]> to see what would break, and they fail immediately:

    // library/alloc/src/boxed.rs
    
    #[stable(feature = "boxed_slice_into_iter", since = "1.53.0")]
    impl<T, A> IntoIterator for Box<[T], A> {
        type Item = T;
        type IntoIter = crate::vec::IntoIter<T, A>;
    
        #[inline]
        fn into_iter(self) -> Self::IntoIter {
            todo!()
        }
    }
    
    #[stable(feature = "boxed_array_into_iter", since = "1.53.0")]
    impl<T, A, const N: usize> IntoIterator for Box<[T; N], A> {
        type Item = T;
        type IntoIter = crate::vec::IntoIter<T, A>;
    
        #[inline]
        fn into_iter(self) -> Self::IntoIter {
            todo!()
        }
    }
    error[E0119]: conflicting implementations of trait `core::iter::IntoIterator` for type `boxed::Box<[_], _>`:
        --> library/alloc/src/boxed.rs:1578:1
         |
    1578 | impl<T, A> IntoIterator for Box<[T], A> {
         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = note: conflicting implementation in crate `core`:
                 - impl<I> IntoIterator for I
                   where I: Iterator;
         = note: upstream crates may add a new impl of trait `core::iter::Iterator` for type `[_]` in future versions
    
    error[E0119]: conflicting implementations of trait `core::iter::IntoIterator` for type `boxed::Box<[_; _], _>`:
        --> library/alloc/src/boxed.rs:1589:1
         |
    1589 | impl<T, A, const N: usize> IntoIterator for Box<[T; N], A> {
         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = note: conflicting implementation in crate `core`:
                 - impl<I> IntoIterator for I
                   where I: Iterator;
         = note: upstream crates may add a new impl of trait `core::iter::Iterator` for type `[_; _]` in future versions
    

    This has to do with impl<I: Iterator + ?Sized, A> Iterator for Box<I, A> to complete the conflict, although we know that we would never add direct Iterator for [T] or [T; N]. I don't know if we could hack around that with a lang item or something.

  8. joshtriplett commented on May 19, 2021

    @joshtriplett
    Member

    We discussed this in the @rust-lang/libs meeting today.

    Our consensus was that we'd be happy to see this impl, as long as doing so was possible and wouldn't break backwards compatibility. It's possible that the machinery proposed for supporting [].into_iter() might help here; if that's the case, and this would potentially benefit from the edition transition, we'd love to see an implementation making use of that.

    The coherence issue @cuviper reported seems orthogonal to that, though.

  9. m-ou-se commented on Jun 10, 2021

    @m-ou-se
    Member

    @yaahc This might be another good use case for your negative trait implementation feature. E.g. impl !Iterator for [_; _]; to promise we will never add the trait implementation that rustc is worried about.

  10. btzy commented on Jul 5, 2021

    @btzy

    Are there any updates on this? It does seem like a waste of the edition update if this isn't going into Rust 2021. There're a number of places in our codebase where we're doing Vec::from(boxed_slice).into_iter() currently, which would benefit from this.

    I wouldn't mind spending some time to get this working, if we're just waiting for someone to get around to writing the implementation. (But I've never contributed to Rust before, so I might need some guidance.)

  11. yaahc commented on Aug 6, 2021

    @yaahc
    Member

    Are there any updates on this? It does seem like a waste of the edition update if this isn't going into Rust 2021. There're a number of places in our codebase where we're doing Vec::from(boxed_slice).into_iter() currently, which would benefit from this.

    I wouldn't mind spending some time to get this working, if we're just waiting for someone to get around to writing the implementation. (But I've never contributed to Rust before, so I might need some guidance.)

    I believe the edition cutoff has already passed quite a few months ago, so I doubt it's possible for this to make it into the 2021 edition but there may be some ways we can make it work backwards compatibly as @joshtriplett mentioned. AFAIK this is just waiting on someone to get around to writing the implementation so if this is something you're interested in please take a crack at it @btzy!

  12. moved this from Idea to Needs help: Impl in Lang Edition 2024on Jan 10, 2024
  13. added a commit that references this issue on May 21, 2024
  14. traviscross commented on Jun 18, 2024

    @traviscross
    Contributor

    This has now happened in:

    ...and is expected to stabilize with Rust 1.80.

    So we can close this issue.

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

    A-iteratorsArea: IteratorsC-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-libs-api[DEPRECATED; DO NOT USE]maybe-future-editionSomething we may consider for a future edition.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions