Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

&Box<[T]> does not impl IntoIterator #83589

Open
lopopolo opened this issue Mar 27, 2021 · 4 comments
Open

&Box<[T]> does not impl IntoIterator #83589

lopopolo opened this issue Mar 27, 2021 · 4 comments
Labels
A-iterators Area: Iterators C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@lopopolo
Copy link
Contributor

I tried this code:

fn one() {
    let v = vec![1, 2, 3].into_boxed_slice();
    for elem in &v {
        println!("elem: {}", elem);
    }
}

fn two() {
    let v = vec![1, 2, 3].into_boxed_slice();
    for elem in &*v {
        println!("elem: {}", elem);
    }
}

I expected to see this happen: I expected both functions one and two to compile.

Instead, this happened: function one does not compile:

   Compiling playground v0.0.1 (/playground)
error[E0277]: `&Box<[{integer}]>` is not an iterator
 --> src/lib.rs:4:17
  |
4 |     for elem in &v {
  |                 ^^ `&Box<[{integer}]>` is not an iterator
  |
  = help: the trait `Iterator` is not implemented for `&Box<[{integer}]>`
  = note: required because of the requirements on the impl of `IntoIterator` for `&Box<[{integer}]>`
  = note: required by `into_iter`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=93a16fe1e2860bd5eb98b2d73f00fc50

Meta

rustc --version --verbose:

Stable channel
Build using the Stable version: 1.51.0
@lopopolo lopopolo added the C-bug Category: This is a bug. label Mar 27, 2021
@cuviper
Copy link
Member

cuviper commented Mar 28, 2021

You could say the same for &mut Box<[T]>, as well as &Rc<[T]> and &Arc<[T]>.

We might also want owned IntoIterator for Box<[T]> and Box<[T; N]>, but this has the same caveat as #65819, that calling .into_iter() currently does auto-deref to the same effect as calling .iter() to get references.
(edit: owned Box<[T]> already has issue #59878)

@cuviper
Copy link
Member

cuviper commented Mar 28, 2021

I experimented with this locally. Fully-generic &Box<[T], A> fails:

error[E0119]: conflicting implementations of trait `core::iter::IntoIterator` for type `&boxed::Box<[_], _>`:
    --> library/alloc/src/boxed.rs:1578:1
     |
1578 | impl<'a, T, A> IntoIterator for &'a Box<[T], A> {
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: conflicting implementation in crate `core`:
             - impl<I> IntoIterator for I
               where I: Iterator;
     = note: downstream crates may implement trait `core::iter::Iterator` for type `&boxed::Box<[_], _>`

I think downstream could only implement this if they have a local allocator type A, because [T] is always foreign. The compiler accepts it if I only implement for &Box<[T]> though, for the default global allocator. &Rc<[T]> and &Arc<[T]> are also fine, and I think they would still work even if they get a parameterized allocator, since they're not fundamental types like Box is.

I tried &mut Box<[T]> too, with or without A, but it conflicts upstream:

error[E0119]: conflicting implementations of trait `core::iter::IntoIterator` for type `&mut boxed::Box<[_], _>`:
    --> library/alloc/src/boxed.rs:1578:1
     |
1578 | impl<'a, T, A> IntoIterator for &'a mut 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

@lopopolo
Copy link
Contributor Author

The same happens for Cow of slice too:

use std::borrow::Cow;

fn one() {
    let v = vec![1, 2, 3];
    let c: Cow<'static, [u8]> = Cow::Owned(v);
    for elem in &c {
        println!("elem: {}", elem);
    }
}

fn two() {
    let v = vec![1, 2, 3];
    let c: Cow<'_, [u8]> = Cow::Borrowed(v.as_slice());
    for elem in &c {
        println!("elem: {}", elem);
    }
}

fn three() {
    let v = vec![1, 2, 3];
    let c: Cow<'static, [u8]> = Cow::Owned(v);
    for elem in &*c {
        println!("elem: {}", elem);
    }
}

fn four() {
    let v = vec![1, 2, 3];
    let c: Cow<'_, [u8]> = Cow::Borrowed(v.as_slice());
    for elem in &*c {
        println!("elem: {}", elem);
    }
}

one and two fail to compile, three and four succeed.

   Compiling playground v0.0.1 (/playground)
error[E0277]: `&Cow<'_, [u8]>` is not an iterator
 --> src/lib.rs:6:17
  |
6 |     for elem in &c {
  |                 ^^ `&Cow<'_, [u8]>` is not an iterator
  |
  = help: the trait `Iterator` is not implemented for `&Cow<'_, [u8]>`
  = note: required because of the requirements on the impl of `IntoIterator` for `&Cow<'_, [u8]>`
  = note: required by `into_iter`

error[E0277]: `&Cow<'_, [u8]>` is not an iterator
  --> src/lib.rs:14:17
   |
14 |     for elem in &c {
   |                 ^^ `&Cow<'_, [u8]>` is not an iterator
   |
   = help: the trait `Iterator` is not implemented for `&Cow<'_, [u8]>`
   = note: required because of the requirements on the impl of `IntoIterator` for `&Cow<'_, [u8]>`
   = note: required by `into_iter`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e4c86a0bd57ff629a4bd31beb9c9ceb2

@ChrisDenton ChrisDenton added the needs-triage-legacy Old issue that were never triaged. Remove this label once the issue has been sufficiently triaged. label Jul 16, 2023
@fmease fmease added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. C-feature-request Category: A feature request, i.e: not implemented / a PR. A-iterators Area: Iterators and removed C-bug Category: This is a bug. needs-triage-legacy Old issue that were never triaged. Remove this label once the issue has been sufficiently triaged. labels Jan 25, 2024
@GrigorenkoPV
Copy link
Contributor

GrigorenkoPV commented Sep 7, 2024

I believe the Box<[T]> case has been fixed by #123759

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-iterators Area: Iterators C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants