about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-11-23 14:16:38 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-11-24 11:47:45 +0300
commit37bb0c7fa68700b7637c137c8b31cdc2e6b49b5e (patch)
treef136d47397110c38e059252995a11931dd748fe2
parente41ced3f8d8e2f3f377ef931458e612d5f3d1f3f (diff)
downloadrust-37bb0c7fa68700b7637c137c8b31cdc2e6b49b5e.tar.gz
rust-37bb0c7fa68700b7637c137c8b31cdc2e6b49b5e.zip
def_collector: Do not forget to save indices of fields with multiple attributes
-rw-r--r--src/librustc_resolve/def_collector.rs16
-rw-r--r--src/test/ui/attributes/unnamed-field-attributes-dup.rs11
2 files changed, 18 insertions, 9 deletions
diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs
index 414ea6e9aa1..dd6b1d2119e 100644
--- a/src/librustc_resolve/def_collector.rs
+++ b/src/librustc_resolve/def_collector.rs
@@ -80,15 +80,16 @@ impl<'a> DefCollector<'a> {
     }
 
     fn collect_field(&mut self, field: &'a StructField, index: Option<usize>) {
+        let index = |this: &Self| index.unwrap_or_else(|| {
+            let node_id = NodeId::placeholder_from_expn_id(this.expansion);
+            this.definitions.placeholder_field_index(node_id)
+        });
+
         if field.is_placeholder {
+            self.definitions.set_placeholder_field_index(field.id, index(self));
             self.visit_macro_invoc(field.id);
         } else {
-            let name = field.ident.map(|ident| ident.name)
-                .or_else(|| index.map(sym::integer))
-                .unwrap_or_else(|| {
-                    let node_id = NodeId::placeholder_from_expn_id(self.expansion);
-                    sym::integer(self.definitions.placeholder_field_index(node_id))
-                });
+            let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name);
             let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span);
             self.with_parent(def, |this| visit::walk_struct_field(this, field));
         }
@@ -190,9 +191,6 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
         // and every such attribute expands into a single field after it's resolved.
         for (index, field) in data.fields().iter().enumerate() {
             self.collect_field(field, Some(index));
-            if field.is_placeholder && field.ident.is_none() {
-                self.definitions.set_placeholder_field_index(field.id, index);
-            }
         }
     }
 
diff --git a/src/test/ui/attributes/unnamed-field-attributes-dup.rs b/src/test/ui/attributes/unnamed-field-attributes-dup.rs
new file mode 100644
index 00000000000..7edfd033794
--- /dev/null
+++ b/src/test/ui/attributes/unnamed-field-attributes-dup.rs
@@ -0,0 +1,11 @@
+// Duplicate non-builtin attributes can be used on unnamed fields.
+
+// check-pass
+
+struct S (
+    #[rustfmt::skip]
+    #[rustfmt::skip]
+    u8
+);
+
+fn main() {}