mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
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.
This commit is contained in:
commit
d877e65404
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user