summary refs log tree commit diff
path: root/src/libsyntax_ext/proc_macro_decls.rs
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-02-28 08:51:35 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-03-17 17:35:25 +0300
commitcdd934ea1dabd72e09bcda7a9954905df3c9ee47 (patch)
treee3fbc4b73ceb94f6d9b9bfaf96815173c779f7f3 /src/libsyntax_ext/proc_macro_decls.rs
parent7473869a6d1348d22d053c85507c7ff5a6f30937 (diff)
downloadrust-cdd934ea1dabd72e09bcda7a9954905df3c9ee47.tar.gz
rust-cdd934ea1dabd72e09bcda7a9954905df3c9ee47.zip
Do not accidentally treat multi-segment meta-items as single-segment
Diffstat (limited to 'src/libsyntax_ext/proc_macro_decls.rs')
-rw-r--r--src/libsyntax_ext/proc_macro_decls.rs55
1 files changed, 35 insertions, 20 deletions
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index d8f8decef39..efa6ce56648 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -113,48 +113,63 @@ impl<'a> CollectProcMacros<'a> {
                                   "attribute must have either one or two arguments");
             return
         }
-        let trait_attr = &list[0];
-        let attributes_attr = list.get(1);
-        let trait_name = match trait_attr.name() {
-            Some(name) => name,
+        let trait_attr = match list[0].meta_item() {
+            Some(meta_item) => meta_item,
             _ => {
-                self.handler.span_err(trait_attr.span(), "not a meta item");
+                self.handler.span_err(list[0].span(), "not a meta item");
+                return
+            }
+        };
+        let trait_ident = match trait_attr.ident() {
+            Some(trait_ident) if trait_attr.is_word() => trait_ident,
+            _ => {
+                self.handler.span_err(trait_attr.span, "must only be one word");
                 return
             }
         };
-        if !trait_attr.is_word() {
-            self.handler.span_err(trait_attr.span(), "must only be one word");
-        }
 
-        if deriving::is_builtin_trait(trait_name) {
+        if trait_ident.is_path_segment_keyword() {
             self.handler.span_err(trait_attr.span(),
-                                  "cannot override a built-in #[derive] mode");
+                                  &format!("`{}` cannot be a name of derive macro", trait_ident));
+        }
+        if deriving::is_builtin_trait(trait_ident.name) {
+            self.handler.span_err(trait_attr.span,
+                                  "cannot override a built-in derive macro");
         }
 
+        let attributes_attr = list.get(1);
         let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
             if !attr.check_name("attributes") {
                 self.handler.span_err(attr.span(), "second argument must be `attributes`")
             }
             attr.meta_item_list().unwrap_or_else(|| {
                 self.handler.span_err(attr.span(),
-                                      "attribute must be of form: \
-                                       `attributes(foo, bar)`");
+                                      "attribute must be of form: `attributes(foo, bar)`");
                 &[]
             }).into_iter().filter_map(|attr| {
-                let name = match attr.name() {
-                    Some(name) => name,
+                let attr = match attr.meta_item() {
+                    Some(meta_item) => meta_item,
                     _ => {
                         self.handler.span_err(attr.span(), "not a meta item");
                         return None;
-                    },
+                    }
                 };
 
-                if !attr.is_word() {
-                    self.handler.span_err(attr.span(), "must only be one word");
-                    return None;
+                let ident = match attr.ident() {
+                    Some(ident) if attr.is_word() => ident,
+                    _ => {
+                        self.handler.span_err(attr.span, "must only be one word");
+                        return None;
+                    }
+                };
+                if ident.is_path_segment_keyword() {
+                    self.handler.span_err(
+                        attr.span(),
+                        &format!("`{}` cannot be a name of derive helper attribute", ident),
+                    );
                 }
 
-                Some(name)
+                Some(ident.name)
             }).collect()
         } else {
             Vec::new()
@@ -163,7 +178,7 @@ impl<'a> CollectProcMacros<'a> {
         if self.in_root && item.vis.node.is_pub() {
             self.derives.push(ProcMacroDerive {
                 span: item.span,
-                trait_name,
+                trait_name: trait_ident.name,
                 function_name: item.ident,
                 attrs: proc_attrs,
             });