about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/metadata/common.rs6
-rw-r--r--src/librustc/metadata/csearch.rs8
-rw-r--r--src/librustc/metadata/decoder.rs19
-rw-r--r--src/librustc/metadata/encoder.rs26
-rw-r--r--src/librustc/middle/ty.rs4
-rw-r--r--src/librustc/middle/typeck/check/_match.rs2
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs62
8 files changed, 98 insertions, 31 deletions
diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs
index 216a575f2fb..a42880b2d36 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -227,3 +227,9 @@ pub static tag_region_param_def_index: uint = 0x94;
 pub static tag_unboxed_closures: uint = 0x95;
 pub static tag_unboxed_closure: uint = 0x96;
 pub static tag_unboxed_closure_type: uint = 0x97;
+
+pub static tag_struct_fields: uint = 0x98;
+pub static tag_struct_field: uint = 0x99;
+pub static tag_struct_field_id: uint = 0x9a;
+
+pub static tag_attribute_is_sugared_doc: uint = 0x9b;
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 0adc8e915c6..b1b366ec030 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -29,6 +29,8 @@ use syntax::attr;
 use syntax::diagnostic::expect;
 use syntax::parse::token;
 
+use std::collections::hashmap::HashMap;
+
 pub struct StaticMethodInfo {
     pub ident: ast::Ident,
     pub def_id: ast::DefId,
@@ -192,6 +194,12 @@ pub fn get_struct_fields(cstore: &cstore::CStore,
     decoder::get_struct_fields(cstore.intr.clone(), &*cdata, def.node)
 }
 
+pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: ast::DefId) -> HashMap<ast::NodeId,
+        Vec<ast::Attribute>> {
+    let cdata = cstore.get_crate_data(def.krate);
+    decoder::get_struct_field_attrs(&*cdata)
+}
+
 pub fn get_type(tcx: &ty::ctxt,
                 def: ast::DefId)
              -> ty::Polytype {
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 094e83d2a47..f7576ffb481 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -34,6 +34,7 @@ use std::hash::Hash;
 use std::hash;
 use std::io::extensions::u64_from_be_bytes;
 use std::io;
+use std::collections::hashmap::HashMap;
 use std::rc::Rc;
 use std::u64;
 use serialize::ebml::reader;
@@ -963,6 +964,19 @@ pub fn get_item_attrs(cdata: Cmd,
     f(get_attributes(item));
 }
 
+pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<ast::Attribute>> {
+    let data = ebml::Doc::new(cdata.data());
+    let fields = reader::get_doc(data, tag_struct_fields);
+    let mut map = HashMap::new();
+    reader::tagged_docs(fields, tag_struct_field, |field| {
+        let id = reader::doc_as_u32(reader::get_doc(field, tag_struct_field_id));
+        let attrs = get_attributes(field);
+        map.insert(id, attrs);
+        true
+    });
+    map
+}
+
 fn struct_field_family_to_visibility(family: Family) -> ast::Visibility {
     match family {
       PublicField => ast::Public,
@@ -1042,6 +1056,9 @@ fn get_attributes(md: ebml::Doc) -> Vec<ast::Attribute> {
     match reader::maybe_get_doc(md, tag_attributes) {
       Some(attrs_d) => {
         reader::tagged_docs(attrs_d, tag_attribute, |attr_doc| {
+            let is_sugared_doc = reader::doc_as_u8(
+                reader::get_doc(attr_doc, tag_attribute_is_sugared_doc)
+            ) == 1;
             let meta_items = get_meta_items(attr_doc);
             // Currently it's only possible to have a single meta item on
             // an attribute
@@ -1053,7 +1070,7 @@ fn get_attributes(md: ebml::Doc) -> Vec<ast::Attribute> {
                         id: attr::mk_attr_id(),
                         style: ast::AttrOuter,
                         value: meta_item,
-                        is_sugared_doc: false,
+                        is_sugared_doc: is_sugared_doc,
                     },
                     span: codemap::DUMMY_SP
                 });
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 7997af1ee5e..6665e913e19 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1490,6 +1490,7 @@ fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
     ebml_w.start_tag(tag_attributes);
     for attr in attrs.iter() {
         ebml_w.start_tag(tag_attribute);
+        ebml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8);
         encode_meta_item(ebml_w, attr.node.value);
         ebml_w.end_tag();
     }
@@ -1644,6 +1645,29 @@ fn encode_unboxed_closures<'a>(
     ebml_w.end_tag();
 }
 
+fn encode_struct_field_attrs(ebml_w: &mut Encoder, krate: &Crate) {
+    struct StructFieldVisitor<'a, 'b> {
+        ebml_w: &'a mut Encoder<'b>,
+    }
+
+    impl<'a, 'b> Visitor<()> for StructFieldVisitor<'a, 'b> {
+        fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
+            self.ebml_w.start_tag(tag_struct_field);
+            self.ebml_w.wr_tagged_u32(tag_struct_field_id, field.node.id);
+            encode_attributes(self.ebml_w, field.node.attrs.as_slice());
+            self.ebml_w.end_tag();
+        }
+    }
+
+    ebml_w.start_tag(tag_struct_fields);
+    visit::walk_crate(&mut StructFieldVisitor {
+        ebml_w: ebml_w
+    }, krate, ());
+    ebml_w.end_tag();
+}
+
+
+
 struct ImplVisitor<'a,'b,'c> {
     ecx: &'a EncodeContext<'b>,
     ebml_w: &'a mut Encoder<'c>,
@@ -1928,6 +1952,8 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
     stats.index_bytes = ebml_w.writer.tell().unwrap() - i;
     ebml_w.end_tag();
 
+    encode_struct_field_attrs(&mut ebml_w, krate);
+
     stats.total_bytes = ebml_w.writer.tell().unwrap();
 
     if tcx.sess.meta_stats() {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 8f60fe340e4..0f5af4421a5 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -4071,7 +4071,7 @@ pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
 
         let len = results.as_slice().iter().map(|x| x.len()).sum();
         let mut result: Vec<field_ty> = Vec::with_capacity(len);
-        result.extend(results.as_slice().iter().flat_map(|rs| rs.iter().map(|&f| f)));
+        result.extend(results.as_slice().iter().flat_map(|rs| rs.iter().map(|f| f.clone())));
         assert!(result.len() == len);
         result
     } else {
@@ -4085,7 +4085,7 @@ pub fn lookup_struct_field(cx: &ctxt,
                         -> field_ty {
     let r = lookup_struct_fields(cx, parent);
     match r.iter().find(|f| f.id.node == field_id.node) {
-        Some(t) => *t,
+        Some(t) => t.clone(),
         None => cx.sess.bug("struct ID not found in parent's fields")
     }
 }
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index a238c207696..531dced550a 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -322,7 +322,7 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
             }
             Some(&(index, ref mut used)) => {
                 *used = true;
-                let class_field = *class_fields.get(index);
+                let class_field = class_fields.get(index).clone();
                 let field_type = ty::lookup_field_type(tcx,
                                                        class_id,
                                                        class_field.id,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 2f7d766c28f..3c942d0791e 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -209,7 +209,7 @@ fn build_struct(tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct {
             _ => doctree::Plain,
         },
         generics: (&t.generics, subst::TypeSpace).clean(),
-        fields: fields.iter().map(|f| f.clean()).collect(),
+        fields: fields.clean(),
         fields_stripped: false,
     }
 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 953b736f38b..002f8878347 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -347,18 +347,18 @@ impl Clean<Item> for doctree::Module {
             }
         }
         let items: Vec<Vec<Item> > = vec!(
-            self.structs.clean().move_iter().collect(),
-            self.enums.clean().move_iter().collect(),
-            self.fns.clean().move_iter().collect(),
+            self.structs.clean(),
+            self.enums.clean(),
+            self.fns.clean(),
             foreigns,
-            self.mods.clean().move_iter().collect(),
-            self.typedefs.clean().move_iter().collect(),
-            self.statics.clean().move_iter().collect(),
-            self.traits.clean().move_iter().collect(),
-            self.impls.clean().move_iter().collect(),
+            self.mods.clean(),
+            self.typedefs.clean(),
+            self.statics.clean(),
+            self.traits.clean(),
+            self.impls.clean(),
             self.view_items.clean().move_iter()
                            .flat_map(|s| s.move_iter()).collect(),
-            self.macros.clean().move_iter().collect()
+            self.macros.clean(),
         );
 
         // determine if we should display the inner contents or
@@ -406,7 +406,7 @@ impl Clean<Attribute> for ast::MetaItem {
         match self.node {
             ast::MetaWord(ref s) => Word(s.get().to_string()),
             ast::MetaList(ref s, ref l) => {
-                List(s.get().to_string(), l.clean().move_iter().collect())
+                List(s.get().to_string(), l.clean())
             }
             ast::MetaNameValue(ref s, ref v) => {
                 NameValue(s.get().to_string(), lit_to_string(v))
@@ -460,7 +460,7 @@ impl Clean<TyParam> for ast::TyParam {
         TyParam {
             name: self.ident.clean(),
             did: ast::DefId { krate: ast::LOCAL_CRATE, node: self.id },
-            bounds: self.bounds.clean().move_iter().collect(),
+            bounds: self.bounds.clean(),
             default: self.default.clean()
         }
     }
@@ -688,7 +688,7 @@ impl Clean<Item> for ast::Method {
         };
         Item {
             name: Some(self.pe_ident().clean()),
-            attrs: self.attrs.clean().move_iter().collect(),
+            attrs: self.attrs.clean(),
             source: self.span.clean(),
             def_id: ast_util::local_def(self.id),
             visibility: self.pe_vis().clean(),
@@ -727,7 +727,7 @@ impl Clean<Item> for ast::TypeMethod {
         };
         Item {
             name: Some(self.ident.clean()),
-            attrs: self.attrs.clean().move_iter().collect(),
+            attrs: self.attrs.clean(),
             source: self.span.clean(),
             def_id: ast_util::local_def(self.id),
             visibility: None,
@@ -805,7 +805,7 @@ impl Clean<ClosureDecl> for ast::ClosureTy {
             onceness: self.onceness,
             fn_style: self.fn_style,
             bounds: match self.bounds {
-                Some(ref x) => x.clean().move_iter().collect(),
+                Some(ref x) => x.clean(),
                 None        => Vec::new()
             },
         }
@@ -1178,7 +1178,7 @@ impl Clean<Type> for ast::Ty {
             TyTup(ref tys) => Tuple(tys.iter().map(|x| x.clean()).collect()),
             TyPath(ref p, ref tpbs, id) => {
                 resolve_type(p.clean(),
-                             tpbs.clean().map(|x| x.move_iter().collect()),
+                             tpbs.clean().map(|x| x),
                              id)
             }
             TyClosure(ref c, region) => Closure(box c.clean(), region.clean()),
@@ -1307,7 +1307,7 @@ impl Clean<Item> for ast::StructField {
         };
         Item {
             name: name.clean(),
-            attrs: self.node.attrs.clean().move_iter().collect(),
+            attrs: self.node.attrs.clean(),
             source: self.span.clean(),
             visibility: Some(vis),
             stability: get_stability(ast_util::local_def(self.node.id)),
@@ -1320,16 +1320,26 @@ impl Clean<Item> for ast::StructField {
 impl Clean<Item> for ty::field_ty {
     fn clean(&self) -> Item {
         use syntax::parse::token::special_idents::unnamed_field;
+        use rustc::metadata::csearch;
+
+        let cx = get_cx();
+        let attrs;
+
+        let attr_map = csearch::get_struct_field_attrs(&cx.tcx().sess.cstore, self.id);
+
         let name = if self.name == unnamed_field.name {
+            attrs = None;
             None
         } else {
+            attrs = Some(attr_map.find(&self.id.node).unwrap());
             Some(self.name)
         };
-        let cx = get_cx();
+
         let ty = ty::lookup_item_type(cx.tcx(), self.id);
+
         Item {
             name: name.clean(),
-            attrs: inline::load_attrs(cx.tcx(), self.id),
+            attrs: attrs.unwrap_or(&Vec::new()).clean(),
             source: Span::empty(),
             visibility: Some(self.vis),
             stability: get_stability(self.id),
@@ -1388,7 +1398,7 @@ impl Clean<VariantStruct> for syntax::ast::StructDef {
     fn clean(&self) -> VariantStruct {
         VariantStruct {
             struct_type: doctree::struct_type_from_def(self),
-            fields: self.fields.clean().move_iter().collect(),
+            fields: self.fields.clean(),
             fields_stripped: false,
         }
     }
@@ -1556,7 +1566,7 @@ impl Clean<Path> for ast::Path {
     fn clean(&self) -> Path {
         Path {
             global: self.global,
-            segments: self.segments.clean().move_iter().collect(),
+            segments: self.segments.clean(),
         }
     }
 }
@@ -1572,8 +1582,8 @@ impl Clean<PathSegment> for ast::PathSegment {
     fn clean(&self) -> PathSegment {
         PathSegment {
             name: self.identifier.clean(),
-            lifetimes: self.lifetimes.clean().move_iter().collect(),
-            types: self.types.clean().move_iter().collect()
+            lifetimes: self.lifetimes.clean(),
+            types: self.types.clean(),
         }
     }
 }
@@ -1640,7 +1650,7 @@ impl Clean<BareFunctionDecl> for ast::BareFnTy {
         BareFunctionDecl {
             fn_style: self.fn_style,
             generics: Generics {
-                lifetimes: self.lifetimes.clean().move_iter().collect(),
+                lifetimes: self.lifetimes.clean(),
                 type_params: Vec::new(),
             },
             decl: self.decl.clean(),
@@ -1745,7 +1755,7 @@ impl Clean<Vec<Item>> for ast::ViewItem {
         let convert = |node: &ast::ViewItem_| {
             Item {
                 name: None,
-                attrs: self.attrs.clean().move_iter().collect(),
+                attrs: self.attrs.clean(),
                 source: self.span.clean(),
                 def_id: ast_util::local_def(0),
                 visibility: self.vis.clean(),
@@ -1840,7 +1850,7 @@ impl Clean<ViewPath> for ast::ViewPath {
                 GlobImport(resolve_use_source(p.clean(), id)),
             ast::ViewPathList(ref p, ref pl, id) => {
                 ImportList(resolve_use_source(p.clean(), id),
-                           pl.clean().move_iter().collect())
+                           pl.clean())
             }
         }
     }
@@ -1893,7 +1903,7 @@ impl Clean<Item> for ast::ForeignItem {
         };
         Item {
             name: Some(self.ident.clean()),
-            attrs: self.attrs.clean().move_iter().collect(),
+            attrs: self.attrs.clean(),
             source: self.span.clean(),
             def_id: ast_util::local_def(self.id),
             visibility: self.vis.clean(),