@@ -212,15 +212,15 @@ pub struct TraitDef<'a> {
212212 /// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
213213 pub generics : Bounds ,
214214
215+ pub methods : Vec < MethodDef < ' a > > ,
216+
217+ pub associated_types : Vec < ( Ident , Ty ) > ,
218+
215219 /// Is it an `unsafe` trait?
216220 pub is_unsafe : bool ,
217221
218222 /// Can this trait be derived for unions?
219223 pub supports_unions : bool ,
220-
221- pub methods : Vec < MethodDef < ' a > > ,
222-
223- pub associated_types : Vec < ( Ident , Ty ) > ,
224224}
225225
226226pub struct MethodDef < ' a > {
@@ -237,18 +237,18 @@ pub struct MethodDef<'a> {
237237 /// Arguments other than the self argument
238238 pub args : Vec < ( Ty , Symbol ) > ,
239239
240- /// Returns type
240+ /// Return type
241241 pub ret_ty : Ty ,
242242
243243 pub attributes : Vec < ast:: Attribute > ,
244244
245- // Is it an `unsafe fn`?
246- pub is_unsafe : bool ,
247-
248245 /// Can we combine fieldless variants for enums into a single match arm?
249246 pub unify_fieldless_variants : bool ,
250247
251248 pub combine_substructure : RefCell < CombineSubstructureFunc < ' a > > ,
249+
250+ /// Is it an `unsafe fn`?
251+ pub is_unsafe : bool ,
252252}
253253
254254/// All the data about the data structure/method being derived upon.
@@ -451,23 +451,27 @@ impl<'a> TraitDef<'a> {
451451 } ;
452452 // Keep the lint attributes of the previous item to control how the
453453 // generated implementations are linted
454- let mut attrs = newitem. attrs . clone ( ) ;
455- attrs. extend (
456- item. attrs
457- . iter ( )
458- . filter ( |a| {
459- [
460- sym:: allow,
461- sym:: warn,
462- sym:: deny,
463- sym:: forbid,
464- sym:: stable,
465- sym:: unstable,
466- ]
467- . contains ( & a. name_or_empty ( ) )
468- } )
469- . cloned ( ) ,
470- ) ;
454+ let attrs = newitem
455+ . attrs
456+ . iter ( )
457+ . cloned ( )
458+ . chain (
459+ item. attrs
460+ . iter ( )
461+ . filter ( |a| {
462+ [
463+ sym:: allow,
464+ sym:: warn,
465+ sym:: deny,
466+ sym:: forbid,
467+ sym:: stable,
468+ sym:: unstable,
469+ ]
470+ . contains ( & a. name_or_empty ( ) )
471+ } )
472+ . cloned ( ) ,
473+ )
474+ . collect ( ) ;
471475 push ( Annotatable :: Item ( P ( ast:: Item { attrs, ..( * newitem) . clone ( ) } ) ) )
472476 }
473477 _ => unreachable ! ( ) ,
@@ -542,7 +546,7 @@ impl<'a> TraitDef<'a> {
542546
543547 // Create the generic parameters
544548 params. extend ( generics. params . iter ( ) . map ( |param| match param. kind {
545- GenericParamKind :: Lifetime { .. } => param. clone ( ) ,
549+ GenericParamKind :: Lifetime { .. } | GenericParamKind :: Const { .. } => param. clone ( ) ,
546550 GenericParamKind :: Type { .. } => {
547551 // I don't think this can be moved out of the loop, since
548552 // a GenericBound requires an ast id
@@ -561,7 +565,6 @@ impl<'a> TraitDef<'a> {
561565
562566 cx. typaram ( self . span , param. ident , vec ! [ ] , bounds, None )
563567 }
564- GenericParamKind :: Const { .. } => param. clone ( ) ,
565568 } ) ) ;
566569
567570 // and similarly for where clauses
@@ -605,38 +608,37 @@ impl<'a> TraitDef<'a> {
605608 let ty_param_names: Vec < Symbol > =
606609 ty_params. map ( |ty_param| ty_param. ident . name ) . collect ( ) ;
607610
608- for field_ty in field_tys {
611+ let bounds: Vec < _ > = self
612+ . additional_bounds
613+ . iter ( )
614+ . map ( |p| cx. trait_bound ( p. to_path ( cx, self . span , type_ident, generics) ) )
615+ // require the current trait
616+ . chain ( iter:: once ( cx. trait_bound ( trait_path. clone ( ) ) ) )
617+ . collect ( ) ;
618+ let preds = field_tys. iter ( ) . flat_map ( |field_ty| {
609619 let tys = find_type_parameters ( & field_ty, & ty_param_names, cx) ;
610-
611- for ty in tys {
620+ tys. into_iter ( ) . filter_map ( |ty| {
612621 // if we have already handled this type, skip it
613622 if let ast:: TyKind :: Path ( _, ref p) = ty. kind {
614623 if p. segments . len ( ) == 1
615624 && ty_param_names. contains ( & p. segments [ 0 ] . ident . name )
616625 {
617- continue ;
618- } ;
626+ return None ;
627+ }
619628 }
620- let mut bounds: Vec < _ > = self
621- . additional_bounds
622- . iter ( )
623- . map ( |p| cx. trait_bound ( p. to_path ( cx, self . span , type_ident, generics) ) )
624- . collect ( ) ;
625-
626- // require the current trait
627- bounds. push ( cx. trait_bound ( trait_path. clone ( ) ) ) ;
628629
629630 let predicate = ast:: WhereBoundPredicate {
630631 span : self . span ,
631632 bound_generic_params : Vec :: new ( ) ,
632633 bounded_ty : ty,
633- bounds,
634+ bounds : bounds . clone ( ) ,
634635 } ;
635636
636637 let predicate = ast:: WherePredicate :: BoundPredicate ( predicate) ;
637- where_clause. predicates . push ( predicate) ;
638- }
639- }
638+ Some ( predicate)
639+ } )
640+ } ) ;
641+ where_clause. predicates . extend ( preds) ;
640642 }
641643 }
642644
@@ -678,11 +680,14 @@ impl<'a> TraitDef<'a> {
678680 cx. attribute ( list)
679681 } ;
680682
681- let mut a = vec ! [ attr, unused_qual] ;
682- a. extend ( self . attributes . iter ( ) . cloned ( ) ) ;
683+ let a = iter:: once ( attr)
684+ . chain ( iter:: once ( unused_qual) )
685+ . chain ( self . attributes . iter ( ) . cloned ( ) )
686+ . collect ( ) ;
683687
684688 let unsafety = if self . is_unsafe { ast:: Unsafe :: Yes ( self . span ) } else { ast:: Unsafe :: No } ;
685-
689+ let mut items = methods;
690+ items. extend ( associated_types) ;
686691 cx. item (
687692 self . span ,
688693 Ident :: invalid ( ) ,
@@ -695,7 +700,7 @@ impl<'a> TraitDef<'a> {
695700 generics : trait_generics,
696701 of_trait : opt_trait_ref,
697702 self_ty : self_type,
698- items : methods . into_iter ( ) . chain ( associated_types ) . collect ( ) ,
703+ items,
699704 } ,
700705 )
701706 }
@@ -709,9 +714,6 @@ impl<'a> TraitDef<'a> {
709714 from_scratch : bool ,
710715 use_temporaries : bool ,
711716 ) -> P < ast:: Item > {
712- let field_tys: Vec < P < ast:: Ty > > =
713- struct_def. fields ( ) . iter ( ) . map ( |field| field. ty . clone ( ) ) . collect ( ) ;
714-
715717 let methods = self
716718 . methods
717719 . iter ( )
@@ -744,6 +746,8 @@ impl<'a> TraitDef<'a> {
744746 } )
745747 . collect ( ) ;
746748
749+ let field_tys: Vec < P < ast:: Ty > > =
750+ struct_def. fields ( ) . iter ( ) . map ( |field| field. ty . clone ( ) ) . collect ( ) ;
747751 self . create_derived_impl ( cx, type_ident, generics, field_tys, methods)
748752 }
749753
@@ -755,11 +759,11 @@ impl<'a> TraitDef<'a> {
755759 generics : & Generics ,
756760 from_scratch : bool ,
757761 ) -> P < ast:: Item > {
758- let mut field_tys = Vec :: new ( ) ;
759-
760- for variant in & enum_def . variants {
761- field_tys . extend ( variant. data . fields ( ) . iter ( ) . map ( |field| field. ty . clone ( ) ) ) ;
762- }
762+ let field_tys = enum_def
763+ . variants
764+ . iter ( )
765+ . flat_map ( | variant| variant . data . fields ( ) . iter ( ) . map ( |field| field. ty . clone ( ) ) )
766+ . collect ( ) ;
763767
764768 let methods = self
765769 . methods
@@ -980,22 +984,22 @@ impl<'a> MethodDef<'a> {
980984 nonself_args : & [ P < Expr > ] ,
981985 use_temporaries : bool ,
982986 ) -> P < Expr > {
983- let mut raw_fields = Vec :: new ( ) ; // Vec<[fields of self],
984- // [fields of next Self arg], [etc]>
985- let mut patterns = Vec :: new ( ) ;
986- for i in 0 ..self_args . len ( ) {
987- let struct_path = cx. path ( trait_. span , vec ! [ type_ident] ) ;
988- let ( pat, ident_expr) = trait_. create_struct_pattern (
989- cx,
990- struct_path,
991- struct_def,
992- & format ! ( "__self_{}" , i) ,
993- ast:: Mutability :: Not ,
994- use_temporaries,
995- ) ;
996- patterns . push ( pat) ;
997- raw_fields . push ( ident_expr ) ;
998- }
987+ // raw_fields: Vec<[fields of self],
988+ // patterns: [fields of next Self arg], [etc]>
989+ let ( patterns, raw_fields ) : ( Vec < _ > , Vec < _ > ) = ( 0 ..self_args . len ( ) )
990+ . map ( |i| {
991+ let struct_path = cx. path ( trait_. span , vec ! [ type_ident] ) ;
992+ let ( pat, ident_expr) = trait_. create_struct_pattern (
993+ cx,
994+ struct_path,
995+ struct_def,
996+ & format ! ( "__self_{}" , i) ,
997+ ast:: Mutability :: Not ,
998+ use_temporaries,
999+ ) ;
1000+ ( pat, ident_expr )
1001+ } )
1002+ . unzip ( ) ;
9991003
10001004 // transpose raw_fields
10011005 let fields = if !raw_fields. is_empty ( ) {
@@ -1555,18 +1559,21 @@ impl<'a> TraitDef<'a> {
15551559 mutbl : ast:: Mutability ,
15561560 use_temporaries : bool ,
15571561 ) -> ( P < ast:: Pat > , Vec < ( Span , Option < Ident > , P < Expr > , & ' a [ ast:: Attribute ] ) > ) {
1558- let mut paths = Vec :: new ( ) ;
1559- let mut ident_exprs = Vec :: new ( ) ;
1560- for ( i, struct_field) in struct_def. fields ( ) . iter ( ) . enumerate ( ) {
1561- let sp = struct_field. span . with_ctxt ( self . span . ctxt ( ) ) ;
1562- let ident = Ident :: from_str_and_span ( & format ! ( "{}_{}" , prefix, i) , self . span ) ;
1563- paths. push ( ident. with_span_pos ( sp) ) ;
1564- let val = cx. expr_path ( cx. path_ident ( sp, ident) ) ;
1565- let val = if use_temporaries { val } else { cx. expr_deref ( sp, val) } ;
1566- let val = cx. expr ( sp, ast:: ExprKind :: Paren ( val) ) ;
1567-
1568- ident_exprs. push ( ( sp, struct_field. ident , val, & struct_field. attrs [ ..] ) ) ;
1569- }
1562+ let ( paths, ident_exprs) : ( Vec < _ > , Vec < _ > ) = struct_def
1563+ . fields ( )
1564+ . iter ( )
1565+ . enumerate ( )
1566+ . map ( |( i, struct_field) | {
1567+ let sp = struct_field. span . with_ctxt ( self . span . ctxt ( ) ) ;
1568+ let ident = Ident :: from_str_and_span ( & format ! ( "{}_{}" , prefix, i) , self . span ) ;
1569+
1570+ let val = cx. expr_path ( cx. path_ident ( sp, ident) ) ;
1571+ let val = if use_temporaries { val } else { cx. expr_deref ( sp, val) } ;
1572+ let val = cx. expr ( sp, ast:: ExprKind :: Paren ( val) ) ;
1573+
1574+ ( ident. with_span_pos ( sp) , ( sp, struct_field. ident , val, & struct_field. attrs [ ..] ) )
1575+ } )
1576+ . unzip ( ) ;
15701577
15711578 let subpats = self . create_subpatterns ( cx, paths, mutbl, use_temporaries) ;
15721579 let pattern = match * struct_def {
@@ -1575,11 +1582,13 @@ impl<'a> TraitDef<'a> {
15751582 . into_iter ( )
15761583 . zip ( & ident_exprs)
15771584 . map ( |( pat, & ( sp, ident, ..) ) | {
1578- if ident. is_none ( ) {
1579- cx. span_bug ( sp, "a braced struct with unnamed fields in `derive`" ) ;
1580- }
1585+ let ident = if let Some ( ident) = ident {
1586+ ident
1587+ } else {
1588+ cx. span_bug ( sp, "a braced struct with unnamed fields in `derive`" )
1589+ } ;
15811590 ast:: FieldPat {
1582- ident : ident. unwrap ( ) ,
1591+ ident : ident,
15831592 is_shorthand : false ,
15841593 attrs : ast:: AttrVec :: new ( ) ,
15851594 id : ast:: DUMMY_NODE_ID ,
0 commit comments