@@ -212,15 +212,15 @@ pub struct TraitDef<'a> {
212
212
/// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
213
213
pub generics : Bounds ,
214
214
215
+ pub methods : Vec < MethodDef < ' a > > ,
216
+
217
+ pub associated_types : Vec < ( Ident , Ty ) > ,
218
+
215
219
/// Is it an `unsafe` trait?
216
220
pub is_unsafe : bool ,
217
221
218
222
/// Can this trait be derived for unions?
219
223
pub supports_unions : bool ,
220
-
221
- pub methods : Vec < MethodDef < ' a > > ,
222
-
223
- pub associated_types : Vec < ( Ident , Ty ) > ,
224
224
}
225
225
226
226
pub struct MethodDef < ' a > {
@@ -237,18 +237,18 @@ pub struct MethodDef<'a> {
237
237
/// Arguments other than the self argument
238
238
pub args : Vec < ( Ty , Symbol ) > ,
239
239
240
- /// Returns type
240
+ /// Return type
241
241
pub ret_ty : Ty ,
242
242
243
243
pub attributes : Vec < ast:: Attribute > ,
244
244
245
- // Is it an `unsafe fn`?
246
- pub is_unsafe : bool ,
247
-
248
245
/// Can we combine fieldless variants for enums into a single match arm?
249
246
pub unify_fieldless_variants : bool ,
250
247
251
248
pub combine_substructure : RefCell < CombineSubstructureFunc < ' a > > ,
249
+
250
+ /// Is it an `unsafe fn`?
251
+ pub is_unsafe : bool ,
252
252
}
253
253
254
254
/// All the data about the data structure/method being derived upon.
@@ -451,23 +451,27 @@ impl<'a> TraitDef<'a> {
451
451
} ;
452
452
// Keep the lint attributes of the previous item to control how the
453
453
// 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 ( ) ;
471
475
push ( Annotatable :: Item ( P ( ast:: Item { attrs, ..( * newitem) . clone ( ) } ) ) )
472
476
}
473
477
_ => unreachable ! ( ) ,
@@ -542,7 +546,7 @@ impl<'a> TraitDef<'a> {
542
546
543
547
// Create the generic parameters
544
548
params. extend ( generics. params . iter ( ) . map ( |param| match param. kind {
545
- GenericParamKind :: Lifetime { .. } => param. clone ( ) ,
549
+ GenericParamKind :: Lifetime { .. } | GenericParamKind :: Const { .. } => param. clone ( ) ,
546
550
GenericParamKind :: Type { .. } => {
547
551
// I don't think this can be moved out of the loop, since
548
552
// a GenericBound requires an ast id
@@ -561,7 +565,6 @@ impl<'a> TraitDef<'a> {
561
565
562
566
cx. typaram ( self . span , param. ident , vec ! [ ] , bounds, None )
563
567
}
564
- GenericParamKind :: Const { .. } => param. clone ( ) ,
565
568
} ) ) ;
566
569
567
570
// and similarly for where clauses
@@ -605,38 +608,37 @@ impl<'a> TraitDef<'a> {
605
608
let ty_param_names: Vec < Symbol > =
606
609
ty_params. map ( |ty_param| ty_param. ident . name ) . collect ( ) ;
607
610
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| {
609
619
let tys = find_type_parameters ( & field_ty, & ty_param_names, cx) ;
610
-
611
- for ty in tys {
620
+ tys. into_iter ( ) . filter_map ( |ty| {
612
621
// if we have already handled this type, skip it
613
622
if let ast:: TyKind :: Path ( _, ref p) = ty. kind {
614
623
if p. segments . len ( ) == 1
615
624
&& ty_param_names. contains ( & p. segments [ 0 ] . ident . name )
616
625
{
617
- continue ;
618
- } ;
626
+ return None ;
627
+ }
619
628
}
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 ( ) ) ) ;
628
629
629
630
let predicate = ast:: WhereBoundPredicate {
630
631
span : self . span ,
631
632
bound_generic_params : Vec :: new ( ) ,
632
633
bounded_ty : ty,
633
- bounds,
634
+ bounds : bounds . clone ( ) ,
634
635
} ;
635
636
636
637
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) ;
640
642
}
641
643
}
642
644
@@ -678,11 +680,14 @@ impl<'a> TraitDef<'a> {
678
680
cx. attribute ( list)
679
681
} ;
680
682
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 ( ) ;
683
687
684
688
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) ;
686
691
cx. item (
687
692
self . span ,
688
693
Ident :: invalid ( ) ,
@@ -695,7 +700,7 @@ impl<'a> TraitDef<'a> {
695
700
generics : trait_generics,
696
701
of_trait : opt_trait_ref,
697
702
self_ty : self_type,
698
- items : methods . into_iter ( ) . chain ( associated_types ) . collect ( ) ,
703
+ items,
699
704
} ,
700
705
)
701
706
}
@@ -709,9 +714,6 @@ impl<'a> TraitDef<'a> {
709
714
from_scratch : bool ,
710
715
use_temporaries : bool ,
711
716
) -> P < ast:: Item > {
712
- let field_tys: Vec < P < ast:: Ty > > =
713
- struct_def. fields ( ) . iter ( ) . map ( |field| field. ty . clone ( ) ) . collect ( ) ;
714
-
715
717
let methods = self
716
718
. methods
717
719
. iter ( )
@@ -744,6 +746,8 @@ impl<'a> TraitDef<'a> {
744
746
} )
745
747
. collect ( ) ;
746
748
749
+ let field_tys: Vec < P < ast:: Ty > > =
750
+ struct_def. fields ( ) . iter ( ) . map ( |field| field. ty . clone ( ) ) . collect ( ) ;
747
751
self . create_derived_impl ( cx, type_ident, generics, field_tys, methods)
748
752
}
749
753
@@ -755,11 +759,11 @@ impl<'a> TraitDef<'a> {
755
759
generics : & Generics ,
756
760
from_scratch : bool ,
757
761
) -> 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 ( ) ;
763
767
764
768
let methods = self
765
769
. methods
@@ -980,22 +984,22 @@ impl<'a> MethodDef<'a> {
980
984
nonself_args : & [ P < Expr > ] ,
981
985
use_temporaries : bool ,
982
986
) -> 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 ( ) ;
999
1003
1000
1004
// transpose raw_fields
1001
1005
let fields = if !raw_fields. is_empty ( ) {
@@ -1555,18 +1559,21 @@ impl<'a> TraitDef<'a> {
1555
1559
mutbl : ast:: Mutability ,
1556
1560
use_temporaries : bool ,
1557
1561
) -> ( 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 ( ) ;
1570
1577
1571
1578
let subpats = self . create_subpatterns ( cx, paths, mutbl, use_temporaries) ;
1572
1579
let pattern = match * struct_def {
@@ -1575,11 +1582,13 @@ impl<'a> TraitDef<'a> {
1575
1582
. into_iter ( )
1576
1583
. zip ( & ident_exprs)
1577
1584
. 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
+ } ;
1581
1590
ast:: FieldPat {
1582
- ident : ident. unwrap ( ) ,
1591
+ ident : ident,
1583
1592
is_shorthand : false ,
1584
1593
attrs : ast:: AttrVec :: new ( ) ,
1585
1594
id : ast:: DUMMY_NODE_ID ,
0 commit comments