diff options
| author | bors <bors@rust-lang.org> | 2015-08-03 20:29:21 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-08-03 20:29:21 +0000 |
| commit | d877e6540431d99b0945a3d27eeb466b0d693902 (patch) | |
| tree | 6cae8df9b2700d9ada25a34b42e1a832ae7e8242 /src/libsyntax/ext | |
| parent | 1fe32ca12c51afcd761d9962f51a74ff0d07a591 (diff) | |
| parent | 93e5a74c87a5278d76050708bd59731c7f8fb5bb (diff) | |
| download | rust-d877e6540431d99b0945a3d27eeb466b0d693902.tar.gz rust-d877e6540431d99b0945a3d27eeb466b0d693902.zip | |
Auto merge of #27134 - fhartwig:derive, r=huonw
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.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index e7d242ab703..8f9e0279b29 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -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; @@ -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(); |
