Skip to content

Commit

Permalink
Auto merge of #27134 - fhartwig:derive, r=huonw
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Aug 3, 2015
2 parents 1fe32ca + 93e5a74 commit d877e65
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/libsyntax/ext/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ pub use self::SubstructureFields::*;
use self::StructType::*;

use std::cell::RefCell;
use std::collections::HashSet;
use std::vec;

use abi::Abi;
Expand Down Expand Up @@ -549,10 +550,20 @@ impl<'a> TraitDef<'a> {
.map(|ty_param| ty_param.ident.name)
.collect();

let mut processed_field_types = HashSet::new();
for field_ty in field_tys {
let tys = find_type_parameters(&*field_ty, &ty_param_names);

for ty in tys {
// if we have already handled this type, skip it
if let ast::TyPath(_, ref p) = ty.node {
if p.segments.len() == 1
&& ty_param_names.contains(&p.segments[0].identifier.name)
|| processed_field_types.contains(&p.segments) {
continue;
};
processed_field_types.insert(p.segments.clone());
}
let mut bounds: Vec<_> = self.additional_bounds.iter().map(|p| {
cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
}).collect();
Expand Down

0 comments on commit d877e65

Please sign in to comment.