about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2013-07-19 21:51:37 +1000
committerHuon Wilson <dbau.pp+github@gmail.com>2013-07-20 01:06:16 +1000
commitcc760a647ac0094814f592d08813ebae0b3bec47 (patch)
tree75ccb57c1c05b195ed8992a66cdd4a14441fca34 /src/libsyntax/parse
parent32586faa6adb890bc25caa8b5cb692e8c37e4a89 (diff)
downloadrust-cc760a647ac0094814f592d08813ebae0b3bec47.tar.gz
rust-cc760a647ac0094814f592d08813ebae0b3bec47.zip
syntax: modernise attribute handling in syntax::attr.
This does a number of things, but especially dramatically reduce the
number of allocations performed for operations involving attributes/
meta items:

- Converts ast::meta_item & ast::attribute and other associated enums
  to CamelCase.
- Converts several standalone functions in syntax::attr into methods,
  defined on two traits AttrMetaMethods & AttributeMethods. The former
  is common to both MetaItem and Attribute since the latter is a thin
  wrapper around the former.
- Deletes functions that are unnecessary due to iterators.
- Converts other standalone functions to use iterators and the generic
  AttrMetaMethods rather than allocating a lot of new vectors (e.g. the
  old code would have to allocate a new vector to use functions that
  operated on &[meta_item] on &[attribute].)
- Moves the core algorithm of the #[cfg] matching to syntax::attr,
  similar to find_inline_attr and find_linkage_metas.

This doesn't have much of an effect on the speed of #[cfg] stripping,
despite hugely reducing the number of allocations performed; presumably
most of the time is spent in the ast folder rather than doing attribute
checks.

Also fixes the Eq instance of MetaItem_ to correctly ignore spaces, so
that `rustc --cfg 'foo(bar)'` now works.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/attr.rs56
-rw-r--r--src/libsyntax/parse/comments.rs6
-rw-r--r--src/libsyntax/parse/mod.rs6
-rw-r--r--src/libsyntax/parse/obsolete.rs6
-rw-r--r--src/libsyntax/parse/parser.rs75
5 files changed, 70 insertions, 79 deletions
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 85c7d5de064..8cce5f15e67 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -17,32 +17,32 @@ use parse::parser::Parser;
 
 // a parser that can parse attributes.
 pub trait parser_attr {
-    fn parse_outer_attributes(&self) -> ~[ast::attribute];
-    fn parse_attribute(&self, style: ast::attr_style) -> ast::attribute;
+    fn parse_outer_attributes(&self) -> ~[ast::Attribute];
+    fn parse_attribute(&self, style: ast::AttrStyle) -> ast::Attribute;
     fn parse_attribute_naked(
         &self,
-        style: ast::attr_style,
+        style: ast::AttrStyle,
         lo: BytePos
-    ) -> ast::attribute;
+    ) -> ast::Attribute;
     fn parse_inner_attrs_and_next(&self) ->
-        (~[ast::attribute], ~[ast::attribute]);
-    fn parse_meta_item(&self) -> @ast::meta_item;
-    fn parse_meta_seq(&self) -> ~[@ast::meta_item];
-    fn parse_optional_meta(&self) -> ~[@ast::meta_item];
+        (~[ast::Attribute], ~[ast::Attribute]);
+    fn parse_meta_item(&self) -> @ast::MetaItem;
+    fn parse_meta_seq(&self) -> ~[@ast::MetaItem];
+    fn parse_optional_meta(&self) -> ~[@ast::MetaItem];
 }
 
 impl parser_attr for Parser {
 
     // Parse attributes that appear before an item
-    fn parse_outer_attributes(&self) -> ~[ast::attribute] {
-        let mut attrs: ~[ast::attribute] = ~[];
+    fn parse_outer_attributes(&self) -> ~[ast::Attribute] {
+        let mut attrs: ~[ast::Attribute] = ~[];
         loop {
             match *self.token {
               token::POUND => {
                 if self.look_ahead(1, |t| *t != token::LBRACKET) {
                     break;
                 }
-                attrs.push(self.parse_attribute(ast::attr_outer));
+                attrs.push(self.parse_attribute(ast::AttrOuter));
               }
               token::DOC_COMMENT(s) => {
                 let attr = ::attr::mk_sugared_doc_attr(
@@ -50,7 +50,7 @@ impl parser_attr for Parser {
                     self.span.lo,
                     self.span.hi
                 );
-                if attr.node.style != ast::attr_outer {
+                if attr.node.style != ast::AttrOuter {
                   self.fatal("expected outer comment");
                 }
                 attrs.push(attr);
@@ -63,20 +63,20 @@ impl parser_attr for Parser {
     }
 
     // matches attribute = # attribute_naked
-    fn parse_attribute(&self, style: ast::attr_style) -> ast::attribute {
+    fn parse_attribute(&self, style: ast::AttrStyle) -> ast::Attribute {
         let lo = self.span.lo;
         self.expect(&token::POUND);
         return self.parse_attribute_naked(style, lo);
     }
 
     // matches attribute_naked = [ meta_item ]
-    fn parse_attribute_naked(&self, style: ast::attr_style, lo: BytePos) ->
-        ast::attribute {
+    fn parse_attribute_naked(&self, style: ast::AttrStyle, lo: BytePos) ->
+        ast::Attribute {
         self.expect(&token::LBRACKET);
         let meta_item = self.parse_meta_item();
         self.expect(&token::RBRACKET);
         let hi = self.span.hi;
-        return spanned(lo, hi, ast::attribute_ { style: style,
+        return spanned(lo, hi, ast::Attribute_ { style: style,
                                                  value: meta_item, is_sugared_doc: false }); }
 
     // Parse attributes that appear after the opening of an item, each
@@ -90,9 +90,9 @@ impl parser_attr for Parser {
     // you can make the 'next' field an Option, but the result is going to be
     // more useful as a vector.
     fn parse_inner_attrs_and_next(&self) ->
-        (~[ast::attribute], ~[ast::attribute]) {
-        let mut inner_attrs: ~[ast::attribute] = ~[];
-        let mut next_outer_attrs: ~[ast::attribute] = ~[];
+        (~[ast::Attribute], ~[ast::Attribute]) {
+        let mut inner_attrs: ~[ast::Attribute] = ~[];
+        let mut next_outer_attrs: ~[ast::Attribute] = ~[];
         loop {
             match *self.token {
               token::POUND => {
@@ -100,7 +100,7 @@ impl parser_attr for Parser {
                     // This is an extension
                     break;
                 }
-                let attr = self.parse_attribute(ast::attr_inner);
+                let attr = self.parse_attribute(ast::AttrInner);
                 if *self.token == token::SEMI {
                     self.bump();
                     inner_attrs.push(attr);
@@ -108,7 +108,7 @@ impl parser_attr for Parser {
                     // It's not really an inner attribute
                     let outer_attr =
                         spanned(attr.span.lo, attr.span.hi,
-                            ast::attribute_ { style: ast::attr_outer,
+                            ast::Attribute_ { style: ast::AttrOuter,
                                               value: attr.node.value,
                                               is_sugared_doc: false });
                     next_outer_attrs.push(outer_attr);
@@ -122,7 +122,7 @@ impl parser_attr for Parser {
                     self.span.hi
                 );
                 self.bump();
-                if attr.node.style == ast::attr_inner {
+                if attr.node.style == ast::AttrInner {
                   inner_attrs.push(attr);
                 } else {
                   next_outer_attrs.push(attr);
@@ -138,7 +138,7 @@ impl parser_attr for Parser {
     // matches meta_item = IDENT
     // | IDENT = lit
     // | IDENT meta_seq
-    fn parse_meta_item(&self) -> @ast::meta_item {
+    fn parse_meta_item(&self) -> @ast::MetaItem {
         let lo = self.span.lo;
         let name = self.id_to_str(self.parse_ident());
         match *self.token {
@@ -146,29 +146,29 @@ impl parser_attr for Parser {
                 self.bump();
                 let lit = self.parse_lit();
                 let hi = self.span.hi;
-                @spanned(lo, hi, ast::meta_name_value(name, lit))
+                @spanned(lo, hi, ast::MetaNameValue(name, lit))
             }
             token::LPAREN => {
                 let inner_items = self.parse_meta_seq();
                 let hi = self.span.hi;
-                @spanned(lo, hi, ast::meta_list(name, inner_items))
+                @spanned(lo, hi, ast::MetaList(name, inner_items))
             }
             _ => {
                 let hi = self.last_span.hi;
-                @spanned(lo, hi, ast::meta_word(name))
+                @spanned(lo, hi, ast::MetaWord(name))
             }
         }
     }
 
     // matches meta_seq = ( COMMASEP(meta_item) )
-    fn parse_meta_seq(&self) -> ~[@ast::meta_item] {
+    fn parse_meta_seq(&self) -> ~[@ast::MetaItem] {
         self.parse_seq(&token::LPAREN,
                        &token::RPAREN,
                        seq_sep_trailing_disallowed(token::COMMA),
                        |p| p.parse_meta_item()).node
     }
 
-    fn parse_optional_meta(&self) -> ~[@ast::meta_item] {
+    fn parse_optional_meta(&self) -> ~[@ast::MetaItem] {
         match *self.token {
             token::LPAREN => self.parse_meta_seq(),
             _ => ~[]
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 83af5bade3a..6daeb1b3e1e 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -44,12 +44,12 @@ pub fn is_doc_comment(s: &str) -> bool {
     s.starts_with("/*!")
 }
 
-pub fn doc_comment_style(comment: &str) -> ast::attr_style {
+pub fn doc_comment_style(comment: &str) -> ast::AttrStyle {
     assert!(is_doc_comment(comment));
     if comment.starts_with("//!") || comment.starts_with("/*!") {
-        ast::attr_inner
+        ast::AttrInner
     } else {
-        ast::attr_outer
+        ast::AttrOuter
     }
 }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 410849b4482..c7a65c80de1 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -115,7 +115,7 @@ pub fn parse_item_from_source_str(
     name: @str,
     source: @str,
     cfg: ast::crate_cfg,
-    attrs: ~[ast::attribute],
+    attrs: ~[ast::Attribute],
     sess: @mut ParseSess
 ) -> Option<@ast::item> {
     let p = new_parser_from_source_str(
@@ -132,7 +132,7 @@ pub fn parse_meta_from_source_str(
     source: @str,
     cfg: ast::crate_cfg,
     sess: @mut ParseSess
-) -> @ast::meta_item {
+) -> @ast::MetaItem {
     let p = new_parser_from_source_str(
         sess,
         cfg,
@@ -146,7 +146,7 @@ pub fn parse_stmt_from_source_str(
     name: @str,
     source: @str,
     cfg: ast::crate_cfg,
-    attrs: ~[ast::attribute],
+    attrs: ~[ast::Attribute],
     sess: @mut ParseSess
 ) -> @ast::stmt {
     let p = new_parser_from_source_str(
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index b014c5668b6..6d7fd3390fa 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -17,7 +17,7 @@ Obsolete syntax that becomes too hard to parse can be
 removed.
 */
 
-use ast::{expr, expr_lit, lit_nil, attribute};
+use ast::{expr, expr_lit, lit_nil, Attribute};
 use ast;
 use codemap::{span, respan};
 use parse::parser::Parser;
@@ -88,7 +88,7 @@ pub trait ParserObsoleteMethods {
     fn eat_obsolete_ident(&self, ident: &str) -> bool;
     fn try_parse_obsolete_struct_ctor(&self) -> bool;
     fn try_parse_obsolete_with(&self) -> bool;
-    fn try_parse_obsolete_priv_section(&self, attrs: &[attribute]) -> bool;
+    fn try_parse_obsolete_priv_section(&self, attrs: &[Attribute]) -> bool;
 }
 
 impl ParserObsoleteMethods for Parser {
@@ -322,7 +322,7 @@ impl ParserObsoleteMethods for Parser {
         }
     }
 
-    pub fn try_parse_obsolete_priv_section(&self, attrs: &[attribute])
+    pub fn try_parse_obsolete_priv_section(&self, attrs: &[Attribute])
                                            -> bool {
         if self.is_keyword(keywords::Priv) &&
                 self.look_ahead(1, |t| *t == token::LBRACE) {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fb5d3b5262c..7e1d5bff4df 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -15,7 +15,7 @@ use ast::{CallSugar, NoSugar, DoSugar, ForSugar};
 use ast::{TyBareFn, TyClosure};
 use ast::{RegionTyParamBound, TraitTyParamBound};
 use ast::{provided, public, purity};
-use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer};
+use ast::{_mod, add, arg, arm, Attribute, bind_by_ref, bind_infer};
 use ast::{bitand, bitor, bitxor, blk};
 use ast::{blk_check_mode, box};
 use ast::{crate, crate_cfg, decl, decl_item};
@@ -109,12 +109,12 @@ enum restriction {
 }
 
 type arg_or_capture_item = Either<arg, ()>;
-type item_info = (ident, item_, Option<~[attribute]>);
+type item_info = (ident, item_, Option<~[Attribute]>);
 
 pub enum item_or_view_item {
     // Indicates a failure to parse any kind of item. The attributes are
     // returned.
-    iovi_none(~[attribute]),
+    iovi_none(~[Attribute]),
     iovi_item(@item),
     iovi_foreign_item(@foreign_item),
     iovi_view_item(view_item)
@@ -242,8 +242,8 @@ macro_rules! maybe_whole (
 )
 
 
-fn maybe_append(lhs: ~[attribute], rhs: Option<~[attribute]>)
-             -> ~[attribute] {
+fn maybe_append(lhs: ~[Attribute], rhs: Option<~[Attribute]>)
+             -> ~[Attribute] {
     match rhs {
         None => lhs,
         Some(ref attrs) => vec::append(lhs, (*attrs))
@@ -252,7 +252,7 @@ fn maybe_append(lhs: ~[attribute], rhs: Option<~[attribute]>)
 
 
 struct ParsedItemsAndViewItems {
-    attrs_remaining: ~[attribute],
+    attrs_remaining: ~[Attribute],
     view_items: ~[view_item],
     items: ~[@item],
     foreign_items: ~[@foreign_item]
@@ -2959,7 +2959,7 @@ impl Parser {
     // parse a structure field
     fn parse_name_and_ty(&self,
                          pr: visibility,
-                         attrs: ~[attribute]) -> @struct_field {
+                         attrs: ~[Attribute]) -> @struct_field {
         let lo = self.span.lo;
         if !is_plain_ident(&*self.token) {
             self.fatal("expected ident");
@@ -2977,7 +2977,7 @@ impl Parser {
 
     // parse a statement. may include decl.
     // precondition: any attributes are parsed already
-    pub fn parse_stmt(&self, item_attrs: ~[attribute]) -> @stmt {
+    pub fn parse_stmt(&self, item_attrs: ~[Attribute]) -> @stmt {
         maybe_whole!(self, nt_stmt);
 
         fn check_expected_item(p: &Parser, found_attrs: bool) {
@@ -3091,7 +3091,7 @@ impl Parser {
 
     // parse a block. Inner attrs are allowed.
     fn parse_inner_attrs_and_block(&self)
-        -> (~[attribute], blk) {
+        -> (~[Attribute], blk) {
 
         maybe_whole!(pair_empty self, nt_block);
 
@@ -3115,7 +3115,7 @@ impl Parser {
 
     // parse the rest of a block expression or function body
     fn parse_block_tail_(&self, lo: BytePos, s: blk_check_mode,
-                         first_item_attrs: ~[attribute]) -> blk {
+                         first_item_attrs: ~[Attribute]) -> blk {
         let mut stmts = ~[];
         let mut expr = None;
 
@@ -3594,7 +3594,7 @@ impl Parser {
 
     fn mk_item(&self, lo: BytePos, hi: BytePos, ident: ident,
                node: item_, vis: visibility,
-               attrs: ~[attribute]) -> @item {
+               attrs: ~[Attribute]) -> @item {
         @ast::item { ident: ident,
                      attrs: attrs,
                      id: self.get_id(),
@@ -3825,7 +3825,7 @@ impl Parser {
     // parse a structure field declaration
     pub fn parse_single_struct_field(&self,
                                      vis: visibility,
-                                     attrs: ~[attribute])
+                                     attrs: ~[Attribute])
                                      -> @struct_field {
         if self.eat_obsolete_ident("let") {
             self.obsolete(*self.last_span, ObsoleteLet);
@@ -3894,7 +3894,7 @@ impl Parser {
     // attributes (of length 0 or 1), parse all of the items in a module
     fn parse_mod_items(&self,
                        term: token::Token,
-                       first_item_attrs: ~[attribute])
+                       first_item_attrs: ~[Attribute])
                        -> _mod {
         // parse all of the items up to closing or an attribute.
         // view items are legal here.
@@ -3953,7 +3953,7 @@ impl Parser {
     }
 
     // parse a `mod <foo> { ... }` or `mod <foo>;` item
-    fn parse_item_mod(&self, outer_attrs: &[ast::attribute]) -> item_info {
+    fn parse_item_mod(&self, outer_attrs: &[Attribute]) -> item_info {
         let id_span = *self.span;
         let id = self.parse_ident();
         if *self.token == token::SEMI {
@@ -3972,11 +3972,10 @@ impl Parser {
         }
     }
 
-    fn push_mod_path(&self, id: ident, attrs: &[ast::attribute]) {
+    fn push_mod_path(&self, id: ident, attrs: &[Attribute]) {
         let default_path = token::interner_get(id.name);
-        let file_path = match ::attr::first_attr_value_str_by_name(
-            attrs, "path") {
-
+        let file_path = match ::attr::first_attr_value_str_by_name(attrs,
+                                                                   "path") {
             Some(d) => d,
             None => default_path
         };
@@ -3990,14 +3989,13 @@ impl Parser {
     // read a module from a source file.
     fn eval_src_mod(&self,
                     id: ast::ident,
-                    outer_attrs: &[ast::attribute],
+                    outer_attrs: &[ast::Attribute],
                     id_sp: span)
-                    -> (ast::item_, ~[ast::attribute]) {
+                    -> (ast::item_, ~[ast::Attribute]) {
         let prefix = Path(self.sess.cm.span_to_filename(*self.span));
         let prefix = prefix.dir_path();
         let mod_path_stack = &*self.mod_path_stack;
         let mod_path = Path(".").push_many(*mod_path_stack);
-        let default_path = token::interner_get(id.name).to_owned() + ".rs";
         let file_path = match ::attr::first_attr_value_str_by_name(
                 outer_attrs, "path") {
             Some(d) => {
@@ -4008,7 +4006,7 @@ impl Parser {
                     path
                 }
             }
-            None => mod_path.push(default_path)
+            None => mod_path.push(token::interner_get(id.name) + ".rs") // default
         };
 
         self.eval_src_mod_from_path(prefix,
@@ -4020,8 +4018,8 @@ impl Parser {
     fn eval_src_mod_from_path(&self,
                               prefix: Path,
                               path: Path,
-                              outer_attrs: ~[ast::attribute],
-                              id_sp: span) -> (ast::item_, ~[ast::attribute]) {
+                              outer_attrs: ~[ast::Attribute],
+                              id_sp: span) -> (ast::item_, ~[ast::Attribute]) {
 
         let full_path = if path.is_absolute {
             path
@@ -4057,17 +4055,10 @@ impl Parser {
         let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
         self.sess.included_mod_stack.pop();
         return (ast::item_mod(m0), mod_attrs);
-
-        fn cdir_path_opt(default: @str, attrs: ~[ast::attribute]) -> @str {
-            match ::attr::first_attr_value_str_by_name(attrs, "path") {
-                Some(d) => d,
-                None => default
-            }
-        }
     }
 
     // parse a function declaration from a foreign module
-    fn parse_item_foreign_fn(&self,  attrs: ~[attribute]) -> @foreign_item {
+    fn parse_item_foreign_fn(&self,  attrs: ~[Attribute]) -> @foreign_item {
         let lo = self.span.lo;
         let vis = self.parse_visibility();
         let purity = self.parse_fn_purity();
@@ -4085,7 +4076,7 @@ impl Parser {
 
     // parse a const definition from a foreign module
     fn parse_item_foreign_const(&self, vis: ast::visibility,
-                                attrs: ~[attribute]) -> @foreign_item {
+                                attrs: ~[Attribute]) -> @foreign_item {
         let lo = self.span.lo;
 
         // XXX: Obsolete; remove after snap.
@@ -4130,7 +4121,7 @@ impl Parser {
     fn parse_foreign_mod_items(&self,
                                sort: ast::foreign_mod_sort,
                                abis: AbiSet,
-                               first_item_attrs: ~[attribute])
+                               first_item_attrs: ~[Attribute])
                                -> foreign_mod {
         let ParsedItemsAndViewItems {
             attrs_remaining: attrs_remaining,
@@ -4156,7 +4147,7 @@ impl Parser {
                               lo: BytePos,
                               opt_abis: Option<AbiSet>,
                               visibility: visibility,
-                              attrs: ~[attribute],
+                              attrs: ~[Attribute],
                               items_allowed: bool)
                               -> item_or_view_item {
         let mut must_be_named_mod = false;
@@ -4430,7 +4421,7 @@ impl Parser {
     // NB: this function no longer parses the items inside an
     // extern mod.
     fn parse_item_or_view_item(&self,
-                               attrs: ~[attribute],
+                               attrs: ~[Attribute],
                                macros_allowed: bool)
                                -> item_or_view_item {
         maybe_whole!(iovi self, nt_item);
@@ -4562,7 +4553,7 @@ impl Parser {
 
     // parse a foreign item; on failure, return iovi_none.
     fn parse_foreign_item(&self,
-                          attrs: ~[attribute],
+                          attrs: ~[Attribute],
                           macros_allowed: bool)
                           -> item_or_view_item {
         maybe_whole!(iovi self, nt_item);
@@ -4587,7 +4578,7 @@ impl Parser {
     // this is the fall-through for parsing items.
     fn parse_macro_use_or_failure(
         &self,
-        attrs: ~[attribute],
+        attrs: ~[Attribute],
         macros_allowed: bool,
         lo : BytePos,
         visibility : visibility
@@ -4649,7 +4640,7 @@ impl Parser {
         return iovi_none(attrs);
     }
 
-    pub fn parse_item(&self, attrs: ~[attribute]) -> Option<@ast::item> {
+    pub fn parse_item(&self, attrs: ~[Attribute]) -> Option<@ast::item> {
         match self.parse_item_or_view_item(attrs, true) {
             iovi_none(_) =>
                 None,
@@ -4786,7 +4777,7 @@ impl Parser {
     // parse a view item.
     fn parse_view_item(
         &self,
-        attrs: ~[attribute],
+        attrs: ~[Attribute],
         vis: visibility
     ) -> view_item {
         let lo = self.span.lo;
@@ -4812,7 +4803,7 @@ impl Parser {
     // - mod_items uses extern_mod_allowed = true
     // - block_tail_ uses extern_mod_allowed = false
     fn parse_items_and_view_items(&self,
-                                  first_item_attrs: ~[attribute],
+                                  first_item_attrs: ~[Attribute],
                                   mut extern_mod_allowed: bool,
                                   macros_allowed: bool)
                                   -> ParsedItemsAndViewItems {
@@ -4894,7 +4885,7 @@ impl Parser {
 
     // Parses a sequence of foreign items. Stops when it finds program
     // text that can't be parsed as an item
-    fn parse_foreign_items(&self, first_item_attrs: ~[attribute],
+    fn parse_foreign_items(&self, first_item_attrs: ~[Attribute],
                            macros_allowed: bool)
         -> ParsedItemsAndViewItems {
         let mut attrs = vec::append(first_item_attrs,