@@ -884,82 +884,109 @@ impl AttributesExt for Vec<Attribute> {
884884 }
885885}
886886
887+ pub trait HasAttrs : Sized {
888+ fn attrs ( & self ) -> & [ ast:: Attribute ] ;
889+ fn map_attrs < F : FnOnce ( Vec < ast:: Attribute > ) -> Vec < ast:: Attribute > > ( self , f : F ) -> Self ;
890+ }
891+
887892/// A cheap way to add Attributes to an AST node.
888893pub trait WithAttrs {
889894 // FIXME: Could be extended to anything IntoIter<Item=Attribute>
890895 fn with_attrs ( self , attrs : ThinAttributes ) -> Self ;
891896}
892897
893- impl WithAttrs for P < Expr > {
898+ impl < T : HasAttrs > WithAttrs for T {
894899 fn with_attrs ( self , attrs : ThinAttributes ) -> Self {
895- self . map ( |mut e | {
896- e . attrs . update ( |a| a . append ( attrs ) ) ;
897- e
900+ self . map_attrs ( |mut orig_attrs | {
901+ orig_attrs . extend ( attrs. into_attr_vec ( ) ) ;
902+ orig_attrs
898903 } )
899904 }
900905}
901906
902- impl WithAttrs for P < Item > {
903- fn with_attrs ( self , attrs : ThinAttributes ) -> Self {
904- self . map ( |Item { ident, attrs : mut ats, id, node, vis, span } | {
905- ats. extend ( attrs. into_attr_vec ( ) ) ;
906- Item {
907- ident : ident,
908- attrs : ats,
909- id : id,
910- node : node,
911- vis : vis,
912- span : span,
913- }
914- } )
907+ impl HasAttrs for Vec < Attribute > {
908+ fn attrs ( & self ) -> & [ Attribute ] {
909+ & self
910+ }
911+ fn map_attrs < F : FnOnce ( Vec < Attribute > ) -> Vec < Attribute > > ( self , f : F ) -> Self {
912+ f ( self )
915913 }
916914}
917915
918- impl WithAttrs for P < Local > {
919- fn with_attrs ( self , attrs : ThinAttributes ) -> Self {
920- self . map ( |Local { pat, ty, init, id, span, attrs : mut ats } | {
921- ats. update ( |a| a. append ( attrs) ) ;
922- Local {
923- pat : pat,
924- ty : ty,
925- init : init,
926- id : id,
927- span : span,
928- attrs : ats,
929- }
930- } )
916+ impl HasAttrs for ThinAttributes {
917+ fn attrs ( & self ) -> & [ Attribute ] {
918+ self . as_attr_slice ( )
919+ }
920+ fn map_attrs < F : FnOnce ( Vec < Attribute > ) -> Vec < Attribute > > ( self , f : F ) -> Self {
921+ self . map_thin_attrs ( f)
931922 }
932923}
933924
934- impl WithAttrs for P < Decl > {
935- fn with_attrs ( self , attrs : ThinAttributes ) -> Self {
936- self . map ( |Spanned { span, node } | {
937- Spanned {
938- span : span,
939- node : match node {
940- DeclKind :: Local ( local) => DeclKind :: Local ( local. with_attrs ( attrs) ) ,
941- DeclKind :: Item ( item) => DeclKind :: Item ( item. with_attrs ( attrs) ) ,
942- }
943- }
944- } )
925+ impl < T : HasAttrs + ' static > HasAttrs for P < T > {
926+ fn attrs ( & self ) -> & [ Attribute ] {
927+ ( * * self ) . attrs ( )
928+ }
929+ fn map_attrs < F : FnOnce ( Vec < Attribute > ) -> Vec < Attribute > > ( self , f : F ) -> Self {
930+ self . map ( |t| t. map_attrs ( f) )
945931 }
946932}
947933
948- impl WithAttrs for P < Stmt > {
949- fn with_attrs ( self , attrs : ThinAttributes ) -> Self {
950- self . map ( |Spanned { span, node } | {
951- Spanned {
952- span : span,
953- node : match node {
954- StmtKind :: Decl ( decl, id) => StmtKind :: Decl ( decl. with_attrs ( attrs) , id) ,
955- StmtKind :: Expr ( expr, id) => StmtKind :: Expr ( expr. with_attrs ( attrs) , id) ,
956- StmtKind :: Semi ( expr, id) => StmtKind :: Semi ( expr. with_attrs ( attrs) , id) ,
957- StmtKind :: Mac ( mac, style, mut ats) => {
958- ats. update ( |a| a. append ( attrs) ) ;
959- StmtKind :: Mac ( mac, style, ats)
960- }
961- } ,
962- }
963- } )
934+ impl HasAttrs for DeclKind {
935+ fn attrs ( & self ) -> & [ Attribute ] {
936+ match * self {
937+ DeclKind :: Local ( ref local) => local. attrs ( ) ,
938+ DeclKind :: Item ( ref item) => item. attrs ( ) ,
939+ }
940+ }
941+
942+ fn map_attrs < F : FnOnce ( Vec < Attribute > ) -> Vec < Attribute > > ( self , f : F ) -> Self {
943+ match self {
944+ DeclKind :: Local ( local) => DeclKind :: Local ( local. map_attrs ( f) ) ,
945+ DeclKind :: Item ( item) => DeclKind :: Item ( item. map_attrs ( f) ) ,
946+ }
964947 }
965948}
949+
950+ impl HasAttrs for StmtKind {
951+ fn attrs ( & self ) -> & [ Attribute ] {
952+ match * self {
953+ StmtKind :: Decl ( ref decl, _) => decl. attrs ( ) ,
954+ StmtKind :: Expr ( ref expr, _) | StmtKind :: Semi ( ref expr, _) => expr. attrs ( ) ,
955+ StmtKind :: Mac ( _, _, ref attrs) => attrs. attrs ( ) ,
956+ }
957+ }
958+
959+ fn map_attrs < F : FnOnce ( Vec < Attribute > ) -> Vec < Attribute > > ( self , f : F ) -> Self {
960+ match self {
961+ StmtKind :: Decl ( decl, id) => StmtKind :: Decl ( decl. map_attrs ( f) , id) ,
962+ StmtKind :: Expr ( expr, id) => StmtKind :: Expr ( expr. map_attrs ( f) , id) ,
963+ StmtKind :: Semi ( expr, id) => StmtKind :: Semi ( expr. map_attrs ( f) , id) ,
964+ StmtKind :: Mac ( mac, style, attrs) =>
965+ StmtKind :: Mac ( mac, style, attrs. map_attrs ( f) ) ,
966+ }
967+ }
968+ }
969+
970+ macro_rules! derive_has_attrs_from_field {
971+ ( $( $ty: path) ,* ) => { derive_has_attrs_from_field!( $( $ty: . attrs) ,* ) ; } ;
972+ ( $( $ty: path : $( . $field: ident) * ) ,* ) => { $(
973+ impl HasAttrs for $ty {
974+ fn attrs( & self ) -> & [ Attribute ] {
975+ self $( . $field) * . attrs( )
976+ }
977+
978+ fn map_attrs<F >( mut self , f: F ) -> Self
979+ where F : FnOnce ( Vec <Attribute >) -> Vec <Attribute >,
980+ {
981+ self $( . $field) * = self $( . $field) * . map_attrs( f) ;
982+ self
983+ }
984+ }
985+ ) * }
986+ }
987+
988+ derive_has_attrs_from_field ! {
989+ Item , Expr , Local , ast:: ForeignItem , ast:: StructField , ast:: ImplItem , ast:: TraitItem , ast:: Arm
990+ }
991+
992+ derive_has_attrs_from_field ! { Decl : . node, Stmt : . node, ast:: Variant : . node. attrs }
0 commit comments