]> git.lizzy.rs Git - rust.git/commitdiff
Add AttrId to Attribute_
authorSteven Fackler <sfackler@gmail.com>
Tue, 20 May 2014 07:07:24 +0000 (00:07 -0700)
committerSteven Fackler <sfackler@gmail.com>
Sat, 24 May 2014 23:08:36 +0000 (16:08 -0700)
23 files changed:
src/librustc/back/svh.rs
src/librustc/front/std_inject.rs
src/librustc/front/test.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/trans/base.rs
src/libsyntax/ast.rs
src/libsyntax/attr.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/clone.rs
src/libsyntax/ext/deriving/cmp/eq.rs
src/libsyntax/ext/deriving/cmp/ord.rs
src/libsyntax/ext/deriving/cmp/totaleq.rs
src/libsyntax/ext/deriving/cmp/totalord.rs
src/libsyntax/ext/deriving/default.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/hash.rs
src/libsyntax/ext/deriving/primitive.rs
src/libsyntax/ext/deriving/zero.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/format.rs
src/libsyntax/fold.rs
src/libsyntax/parse/attr.rs

index 489722aa13fb473bf24abcf75e49f1276223f9e4..9ad653498ba06f91b902677902d05e237f605b37 100644 (file)
@@ -91,7 +91,12 @@ pub fn calculate(krate: &ast::Crate) -> Svh {
         // types and then use hash_content.  But, since all crate
         // attributes should appear near beginning of the file, it is
         // not such a big deal to be sensitive to their spans for now.
-        krate.attrs.hash(&mut state);
+        //
+        // We hash only the MetaItems instead of the entire Attribute
+        // to avoid hashing the AttrId
+        for attr in krate.attrs.iter() {
+            attr.node.value.hash(&mut state);
+        }
 
         let hash = state.result();
         return Svh {
index efaeeaa557510074e3f07315815f43f43852651f..e380af7a4f01b98827c0d1b609238fe97a5b17a5 100644 (file)
@@ -78,7 +78,7 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
                                          with_version("std"),
                                          ast::DUMMY_NODE_ID),
             attrs: vec!(
-                attr::mk_attr_outer(attr::mk_list_item(
+                attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
                         InternedString::new("phase"),
                         vec!(
                             attr::mk_word_item(InternedString::new("syntax")),
@@ -110,7 +110,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         // Add it during the prelude injection instead.
 
         // Add #![feature(phase)] here, because we use #[phase] on extern crate std.
-        let feat_phase_attr = attr::mk_attr_inner(attr::mk_list_item(
+        let feat_phase_attr = attr::mk_attr_inner(attr::mk_attr_id(),
+                                                  attr::mk_list_item(
                                   InternedString::new("feature"),
                                   vec![attr::mk_word_item(InternedString::new("phase"))],
                               ));
@@ -138,7 +139,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         // This must happen here and not in StandardLibraryInjector because this
         // fold happens second.
 
-        let no_std_attr = attr::mk_attr_inner(attr::mk_word_item(InternedString::new("no_std")));
+        let no_std_attr = attr::mk_attr_inner(attr::mk_attr_id(),
+                                              attr::mk_word_item(InternedString::new("no_std")));
         krate.attrs.push(no_std_attr);
 
         if !no_prelude(krate.attrs.as_slice()) {
@@ -146,7 +148,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
             // `#![no_implicit_prelude]` at the crate level.
 
             // fold_mod() will insert glob path.
-            let globs_attr = attr::mk_attr_inner(attr::mk_list_item(
+            let globs_attr = attr::mk_attr_inner(attr::mk_attr_id(),
+                                                 attr::mk_list_item(
                 InternedString::new("feature"),
                 vec!(
                     attr::mk_word_item(InternedString::new("globs")),
index e7a5aeb9ef5aa00a25ed63fe6c59bd2efae7c6a3..d5e9192cd7496b73e6251a50890b0f941e835434 100644 (file)
@@ -341,7 +341,8 @@ pub fn main() {
     // This attribute tells resolve to let us call unexported functions
     let resolve_unexported_str = InternedString::new("!resolve_unexported");
     let resolve_unexported_attr =
-        attr::mk_attr_inner(attr::mk_word_item(resolve_unexported_str));
+        attr::mk_attr_inner(attr::mk_attr_id(),
+                            attr::mk_word_item(resolve_unexported_str));
 
     let item = ast::Item {
         ident: token::str_to_ident("__test"),
index b3ef888c0b466da89068758bfc97c8e165f46244..77c3d43bc095ae7b49346cbc3fc169421bcbff55 100644 (file)
@@ -1056,6 +1056,7 @@ fn get_attributes(md: ebml::Doc) -> Vec<ast::Attribute> {
             attrs.push(
                 codemap::Spanned {
                     node: ast::Attribute_ {
+                        id: attr::mk_attr_id(),
                         style: ast::AttrOuter,
                         value: meta_item,
                         is_sugared_doc: false,
index a0742669cc07e9a38be051ada15aa4d1865df2b0..a06c6e59ea1dea5645e0d2a8bc2f85364db8d4d8 100644 (file)
@@ -1436,7 +1436,7 @@ fn synthesize_crate_attrs(ecx: &EncodeContext,
     fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
         assert!(!ecx.link_meta.crateid.name.is_empty());
 
-        attr::mk_attr_inner(
+        attr::mk_attr_inner(attr::mk_attr_id(),
             attr::mk_name_value_item_str(
                 InternedString::new("crate_id"),
                 token::intern_and_get_ident(ecx.link_meta
index 43f3442ec472ec79b29bcd379eb481c2777431e7..4b769a5fdaef70fbcb5f6c0c32c0419f68dc295b 100644 (file)
@@ -228,8 +228,9 @@ fn get_extern_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str, did: ast::De
     let f = decl_rust_fn(ccx, fn_ty, name);
 
     csearch::get_item_attrs(&ccx.sess().cstore, did, |meta_items| {
-        set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr_outer(x))
-                                    .collect::<Vec<_>>().as_slice(), f)
+        set_llvm_fn_attrs(meta_items.iter().map(|&x| {
+            attr::mk_attr_outer(attr::mk_attr_id(), x)
+        }).collect::<Vec<_>>().as_slice(), f)
     });
 
     ccx.externs.borrow_mut().insert(name.to_strbuf(), f);
index d4c01746098ea2faa19b26bae2e88676e3ffa80c..e77d1faf05d89a0790e9908d3ef3b2bfb549aad6 100644 (file)
@@ -1024,9 +1024,13 @@ pub enum AttrStyle {
     AttrInner,
 }
 
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
+pub struct AttrId(pub uint);
+
 // doc-comments are promoted to attributes that have is_sugared_doc = true
 #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Attribute_ {
+    pub id: AttrId,
     pub style: AttrStyle,
     pub value: @MetaItem,
     pub is_sugared_doc: bool,
index 77c335b8936100b19486bc2e9061de0e3d3ff268..83ac2c08efb5e4b56595c7350397a003f5317856 100644 (file)
@@ -11,7 +11,7 @@
 // Functions dealing with attributes and meta items
 
 use ast;
-use ast::{Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList};
+use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList};
 use codemap::{Span, Spanned, spanned, dummy_spanned};
 use codemap::BytePos;
 use diagnostic::SpanHandler;
 
 use collections::HashSet;
 
+local_data_key!(used_attrs: HashSet<AttrId>)
+
+pub fn mark_used(attr: &Attribute) {
+    let mut used = used_attrs.replace(None).unwrap_or_else(|| HashSet::new());
+    used.insert(attr.node.id);
+    used_attrs.replace(Some(used));
+}
+
+pub fn is_used(attr: &Attribute) -> bool {
+    used_attrs.get().map_or(false, |used| used.contains(&attr.node.id))
+}
+
 pub trait AttrMetaMethods {
     // This could be changed to `fn check_name(&self, name: InternedString) ->
     // bool` which would facilitate a side table recording which
@@ -127,9 +139,9 @@ fn desugar_doc(&self) -> Attribute {
                 token::intern_and_get_ident(strip_doc_comment_decoration(
                         comment.get()).as_slice()));
             if self.node.style == ast::AttrOuter {
-                mk_attr_outer(meta)
+                mk_attr_outer(self.node.id, meta)
             } else {
-                mk_attr_inner(meta)
+                mk_attr_inner(self.node.id, meta)
             }
         } else {
             *self
@@ -158,9 +170,18 @@ pub fn mk_word_item(name: InternedString) -> @MetaItem {
     @dummy_spanned(MetaWord(name))
 }
 
+local_data_key!(next_attr_id: uint)
+
+pub fn mk_attr_id() -> AttrId {
+    let id = next_attr_id.replace(None).unwrap_or(0);
+    next_attr_id.replace(Some(id + 1));
+    AttrId(id)
+}
+
 /// Returns an inner attribute with the given value.
-pub fn mk_attr_inner(item: @MetaItem) -> Attribute {
+pub fn mk_attr_inner(id: AttrId, item: @MetaItem) -> Attribute {
     dummy_spanned(Attribute_ {
+        id: id,
         style: ast::AttrInner,
         value: item,
         is_sugared_doc: false,
@@ -168,19 +189,22 @@ pub fn mk_attr_inner(item: @MetaItem) -> Attribute {
 }
 
 /// Returns an outer attribute with the given value.
-pub fn mk_attr_outer(item: @MetaItem) -> Attribute {
+pub fn mk_attr_outer(id: AttrId, item: @MetaItem) -> Attribute {
     dummy_spanned(Attribute_ {
+        id: id,
         style: ast::AttrOuter,
         value: item,
         is_sugared_doc: false,
     })
 }
 
-pub fn mk_sugared_doc_attr(text: InternedString, lo: BytePos, hi: BytePos)
+pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
+                           hi: BytePos)
                            -> Attribute {
     let style = doc_comment_style(text.get());
     let lit = spanned(lo, hi, ast::LitStr(text, ast::CookedStr));
     let attr = Attribute_ {
+        id: id,
         style: style,
         value: @spanned(lo, hi, MetaNameValue(InternedString::new("doc"),
                                               lit)),
index 3c7415ae0e9b9fe0a81bf116ed173ba26aae260b..44c177d19ca2fbc234c00b473122f1eb73be5c92 100644 (file)
@@ -231,7 +231,7 @@ fn item_ty_poly(&self,
                     generics: Generics) -> @ast::Item;
     fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item;
 
-    fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute;
+    fn attribute(&self, id: AttrId, sp: Span, mi: @ast::MetaItem) -> ast::Attribute;
 
     fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem;
     fn meta_list(&self,
@@ -925,8 +925,10 @@ fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item {
         self.item_ty_poly(span, name, ty, ast_util::empty_generics())
     }
 
-    fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute {
+    fn attribute(&self, id: ast::AttrId, sp: Span, mi: @ast::MetaItem)
+                 -> ast::Attribute {
         respan(sp, ast::Attribute_ {
+            id: id,
             style: ast::AttrOuter,
             value: mi,
             is_sugared_doc: false,
index 89c94891b3380875057fb3c6b575eb4397671cc3..73bfe9c27b62fc86ece69b0da3a6476509259ba3 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use attr;
 use ast::{MetaItem, Item, Expr};
 use codemap::Span;
 use ext::base::ExtCtxt;
@@ -21,7 +22,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                              item: @Item,
                              push: |@Item|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
-    let attrs = vec!(cx.attribute(span, inline));
+    let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
index 92b3788c247443c53791a8eecbb6e8480ac52d09..31d6fcb9d6f7b2ecafbfb011873909a213d3a426 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use ast::{MetaItem, Item, Expr};
+use attr;
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -34,7 +35,7 @@ fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
     macro_rules! md (
         ($name:expr, $f:ident) => { {
             let inline = cx.meta_word(span, InternedString::new("inline"));
-            let attrs = vec!(cx.attribute(span, inline));
+            let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
             MethodDef {
                 name: $name,
                 generics: LifetimeBounds::empty(),
index dd2f90cfa5fae9ac21880ad8a78513c6567d063d..3d79de4feb1da47a846be515e323238852ec057c 100644 (file)
@@ -10,6 +10,7 @@
 
 use ast;
 use ast::{MetaItem, Item, Expr};
+use attr;
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -24,7 +25,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
     macro_rules! md (
         ($name:expr, $op:expr, $equal:expr) => { {
             let inline = cx.meta_word(span, InternedString::new("inline"));
-            let attrs = vec!(cx.attribute(span, inline));
+            let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
             MethodDef {
                 name: $name,
                 generics: LifetimeBounds::empty(),
index b76caccffecc6095b168fcd4474987124f94bc51..42bbf8e415af9d27c02f893b350060d91692edd4 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use ast::{MetaItem, Item, Expr};
+use attr;
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -37,8 +38,8 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @E
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let hidden = cx.meta_word(span, InternedString::new("hidden"));
     let doc = cx.meta_list(span, InternedString::new("doc"), vec!(hidden));
-    let attrs = vec!(cx.attribute(span, inline),
-                     cx.attribute(span, doc));
+    let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline),
+                     cx.attribute(attr::mk_attr_id(), span, doc));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
index 3ca4f9e28626380da776cee61b04e8c3a0d70cf3..6413bdab3447660610dac4e1eca140ed30a69cdb 100644 (file)
@@ -10,6 +10,7 @@
 
 use ast;
 use ast::{MetaItem, Item, Expr};
+use attr;
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -24,7 +25,7 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
                                 item: @Item,
                                 push: |@Item|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
-    let attrs = vec!(cx.attribute(span, inline));
+    let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
index c225906ed2babafcf00398b5b991b8423cd1fcfc..a0499a2cc1ef2e7998f758a6268aea408f603586 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use ast::{MetaItem, Item, Expr};
+use attr;
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -21,7 +22,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
                             item: @Item,
                             push: |@Item|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
-    let attrs = vec!(cx.attribute(span, inline));
+    let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
index 0875daddc0f9fb3e0855bc475de3c75811272816..28595fecd89e914340e5d322f0d855097d573126 100644 (file)
@@ -182,6 +182,7 @@ fn eq(&self, other: &int) -> bool {
 use ast;
 use ast::{P, EnumDef, Expr, Ident, Generics, StructDef};
 use ast_util;
+use attr;
 use attr::AttrMetaMethods;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -427,6 +428,7 @@ fn create_derived_impl(&self,
                         self_ty_params.into_vec()), None);
 
         let attr = cx.attribute(
+            attr::mk_attr_id(),
             self.span,
             cx.meta_word(self.span,
                          InternedString::new("automatically_derived")));
index 3e6b8d522d4f9a6b425b55e275b0331f65973254..8b368968f49018ec3ffbfbcd07b6da6cf9666890 100644 (file)
@@ -10,6 +10,7 @@
 
 use ast;
 use ast::{MetaItem, Item, Expr, MutMutable};
+use attr;
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -37,7 +38,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
          Path::new(vec!("std", "hash", "sip", "SipState")))
     };
     let inline = cx.meta_word(span, InternedString::new("inline"));
-    let attrs = vec!(cx.attribute(span, inline));
+    let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
     let hash_trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
index 5066a395b415f073e0eba0478a918174d0b448a9..e3621b51c4d6ff2a4a4b781062dc24147f2a96ae 100644 (file)
@@ -10,6 +10,7 @@
 
 use ast::{MetaItem, Item, Expr};
 use ast;
+use attr;
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -22,7 +23,7 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                       item: @Item,
                                       push: |@Item|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
-    let attrs = vec!(cx.attribute(span, inline));
+    let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
index 449851dd3ea5913aecc03654a5d5f5f55958c801..c60cdab90993ba4313a69ac27c7abd72e30ceaf5 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use ast::{MetaItem, Item, Expr};
+use attr;
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -21,7 +22,7 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                             item: @Item,
                             push: |@Item|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
-    let attrs = vec!(cx.attribute(span, inline));
+    let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
index 989d0a463c387a653ac884152bd2890062e0f8d7..83118df5e65cbbc076d1f72c7e1bd9034daec0a7 100644 (file)
@@ -972,6 +972,7 @@ mod test {
     use super::*;
     use ast;
     use ast::{Attribute_, AttrOuter, MetaWord};
+    use attr;
     use codemap;
     use codemap::Spanned;
     use ext::base::{CrateLoader, MacroCrate};
@@ -1103,6 +1104,7 @@ fn make_dummy_attr(s: &str) -> ast::Attribute {
         Spanned {
             span:codemap::DUMMY_SP,
             node: Attribute_ {
+                id: attr::mk_attr_id(),
                 style: AttrOuter,
                 value: @Spanned {
                     node: MetaWord(token::intern_and_get_ident(s)),
index ad4b798cfe5b85c66d505a16b2a8500131d09054..c3b3c4eed572ca95cbd7eefad171c71ac679af1e 100644 (file)
@@ -10,6 +10,7 @@
 
 use ast;
 use ast::P;
+use attr;
 use codemap::{Span, respan};
 use ext::base::*;
 use ext::base;
@@ -382,7 +383,8 @@ fn static_attrs(&self) -> Vec<ast::Attribute> {
                           .meta_word(self.fmtsp,
                                      InternedString::new(
                                          "address_insignificant"));
-        let unnamed = self.ecx.attribute(self.fmtsp, unnamed);
+        let unnamed = self.ecx.attribute(attr::mk_attr_id(), self.fmtsp,
+                                         unnamed);
 
         // Do not warn format string as dead code
         let dead_code = self.ecx.meta_word(self.fmtsp,
@@ -390,7 +392,8 @@ fn static_attrs(&self) -> Vec<ast::Attribute> {
         let allow_dead_code = self.ecx.meta_list(self.fmtsp,
                                                  InternedString::new("allow"),
                                                  vec!(dead_code));
-        let allow_dead_code = self.ecx.attribute(self.fmtsp, allow_dead_code);
+        let allow_dead_code = self.ecx.attribute(attr::mk_attr_id(), self.fmtsp,
+                                                 allow_dead_code);
         return vec!(unnamed, allow_dead_code);
     }
 
index 9813e12de01ca4ae4f7eb76987400536d6a35ac9..ae5cf550bb9bc0bd00e5de08ddd1a2767be17cf8 100644 (file)
@@ -360,6 +360,7 @@ fn fold_attribute_<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
     Spanned {
         span: fld.new_span(at.span),
         node: ast::Attribute_ {
+            id: at.node.id,
             style: at.node.style,
             value: fold_meta_item_(at.node.value, fld),
             is_sugared_doc: at.node.is_sugared_doc
index 89d1b8f9342dd8b14e7e9948f86f6c662bac60d3..e86dcb3d3114697113e74d9620be06614e7325e2 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use attr;
 use ast;
 use codemap::{spanned, Spanned, mk_sp, Span};
 use parse::common::*; //resolve bug?
@@ -39,6 +40,7 @@ fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
               }
               token::DOC_COMMENT(s) => {
                 let attr = ::attr::mk_sugared_doc_attr(
+                    attr::mk_attr_id(),
                     self.id_to_interned_str(s),
                     self.span.lo,
                     self.span.hi
@@ -101,6 +103,7 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
         return Spanned {
             span: span,
             node: ast::Attribute_ {
+                id: attr::mk_attr_id(),
                 style: style,
                 value: value,
                 is_sugared_doc: false
@@ -132,7 +135,10 @@ fn parse_inner_attrs_and_next(&mut self)
                     // we need to get the position of this token before we bump.
                     let Span { lo, hi, .. } = self.span;
                     self.bump();
-                    ::attr::mk_sugared_doc_attr(self.id_to_interned_str(s), lo, hi)
+                    ::attr::mk_sugared_doc_attr(attr::mk_attr_id(),
+                                                self.id_to_interned_str(s),
+                                                lo,
+                                                hi)
                 }
                 _ => {
                     break;