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

rustdoc shows duplicate bounds for derived implementations #25022

Closed
solson opened this issue May 1, 2015 · 2 comments
Closed

rustdoc shows duplicate bounds for derived implementations #25022

solson opened this issue May 1, 2015 · 2 comments
Labels
T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Comments

@solson
Copy link
Member

solson commented May 1, 2015

See the derived implementations at the bottom of http://doc.rust-lang.org/1.0.0-beta.3/std/num/struct.Wrapping.html for example.

impl<T> Clone for Wrapping<T> where T: Clone + Clone
@alexcrichton alexcrichton added the T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. label May 1, 2015
@solson
Copy link
Member Author

solson commented May 6, 2015

Interestingly, impl<Idx> Clone for Range<Idx> where Idx: Clone + Clone + Clone has Clone three times. My theory is that there's an extra bound for each use of the type parameter inside the struct, since Wrapping<T> has one T field and Range<Idx> has two Idx fields.

@tomjakubowski
Copy link
Contributor

I think this is a bug in #[derive(Clone)], actually.

// bar.rs
#[derive(Clone)]
struct Foo<T>(pub T);

fn main() {
}

The results of --pretty=expanded:

#![feature(no_std)]
#![no_std]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std as std;
struct Foo<T>(pub T);
#[automatically_derived]
impl <T: ::std::clone::Clone> ::std::clone::Clone for Foo<T> where
 T: ::std::clone::Clone {
    #[inline]
    fn clone(&self) -> Foo<T> {
        match *self {
            Foo(ref __self_0_0) =>
            Foo(::std::clone::Clone::clone(&(*__self_0_0))),
        }
    }
}

fn main() { }

Note the extra bound on T. The only weird thing rustdoc is doing is writing that as a where clause, which I'd expect because that's all it can do for bounds on an inlined doc item such as std::num::Wrapping (for now).

bors added a commit that referenced this issue Aug 3, 2015
Fixes #25022

This adapts the deriving mechanism to not repeat bounds for the same type parameter. To give an example: for the following code:

```rust
#[derive(Clone)]
pub struct FlatMap<I, U: IntoIterator, F> {
    iter: I,
    f: F,
    frontiter: Option<U::IntoIter>,
    backiter: Option<U::IntoIter>,
}
```
the latest nightly generates the following impl signature:

```rust
impl <I: ::std::clone::Clone,
      U: ::std::clone::Clone + IntoIterator,
      F: ::std::clone::Clone>
::std::clone::Clone for FlatMap<I, U, F> where
    I: ::std::clone::Clone,
    F: ::std::clone::Clone,
    U::IntoIter: ::std::clone::Clone,
    U::IntoIter: ::std::clone::Clone
```

With these changes, the signature changes to this:
```rust
impl <I, U: IntoIterator, F> ::std::clone::Clone for FlatMap<I, U, F> where
    I: ::std::clone::Clone,
    F: ::std::clone::Clone,
    U::IntoIter: ::std::clone::Clone
```
(Nothing in the body of the impl changes)
Note that the second impl is more permissive, as it doesn't have a `Clone` bound on `U` at all. There was a compile-fail test that failed due to this. I don't understand why we would want the old behaviour (and nobody on IRC could tell me either), so please tell me if there is a good reason that I missed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants