Skip to content

Commit d877e65

Browse files
committed
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.
2 parents 1fe32ca + 93e5a74 commit d877e65

File tree

1 file changed

+11
-0
lines changed
  • src/libsyntax/ext/deriving/generic

1 file changed

+11
-0
lines changed

src/libsyntax/ext/deriving/generic/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ pub use self::SubstructureFields::*;
188188
use self::StructType::*;
189189

190190
use std::cell::RefCell;
191+
use std::collections::HashSet;
191192
use std::vec;
192193

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

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

555557
for ty in tys {
558+
// if we have already handled this type, skip it
559+
if let ast::TyPath(_, ref p) = ty.node {
560+
if p.segments.len() == 1
561+
&& ty_param_names.contains(&p.segments[0].identifier.name)
562+
|| processed_field_types.contains(&p.segments) {
563+
continue;
564+
};
565+
processed_field_types.insert(p.segments.clone());
566+
}
556567
let mut bounds: Vec<_> = self.additional_bounds.iter().map(|p| {
557568
cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
558569
}).collect();

0 commit comments

Comments
 (0)