about summary refs log tree commit diff
path: root/src/libsyntax_ext
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-03-16 20:48:40 +0000
committerbors <bors@rust-lang.org>2019-03-16 20:48:40 +0000
commit7cf074a1e655ac07d04d045667278fa1a9970b93 (patch)
treed2509e198c34af3e41cce2dbde186635384a418a /src/libsyntax_ext
parent2c8bbf50db0ef90a33f986ba8fc2e1fe129197ff (diff)
parent2fd4cbb3f283b903f55444bb585d38a2539f4e8d (diff)
downloadrust-7cf074a1e655ac07d04d045667278fa1a9970b93.tar.gz
rust-7cf074a1e655ac07d04d045667278fa1a9970b93.zip
Auto merge of #58899 - petrochenkov:derval2, r=estebank
Do not accidentally treat multi-segment meta-items as single-segment

Fixes https://github.com/rust-lang/rust/issues/55168 and many other regressions from https://github.com/rust-lang/rust/pull/50030

Basically, attributes like `#[any::prefix::foo]` were commonly interpreted as `#[foo]` due to `name()` successfully returning the last segment (this applies to nested things as well `#[attr(any::prefix::foo)]`).
Diffstat (limited to 'src/libsyntax_ext')
-rw-r--r--src/libsyntax_ext/deriving/custom.rs8
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs9
-rw-r--r--src/libsyntax_ext/proc_macro_decls.rs67
-rw-r--r--src/libsyntax_ext/proc_macro_server.rs8
-rw-r--r--src/libsyntax_ext/test.rs2
5 files changed, 52 insertions, 42 deletions
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs
index cfc3c931598..e73110717e9 100644
--- a/src/libsyntax_ext/deriving/custom.rs
+++ b/src/libsyntax_ext/deriving/custom.rs
@@ -17,9 +17,11 @@ struct MarkAttrs<'a>(&'a [ast::Name]);
 
 impl<'a> Visitor<'a> for MarkAttrs<'a> {
     fn visit_attribute(&mut self, attr: &Attribute) {
-        if self.0.contains(&attr.name()) {
-            mark_used(attr);
-            mark_known(attr);
+        if let Some(ident) = attr.ident() {
+            if self.0.contains(&ident.name) {
+                mark_used(attr);
+                mark_known(attr);
+            }
         }
     }
 
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index b8f96c5bc0e..2bb98c1bf62 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -463,12 +463,9 @@ impl<'a> TraitDef<'a> {
                 let mut attrs = newitem.attrs.clone();
                 attrs.extend(item.attrs
                     .iter()
-                    .filter(|a| {
-                        match &*a.name().as_str() {
-                            "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
-                            _ => false,
-                        }
-                    })
+                    .filter(|a| a.ident_str().map_or(false, |name| {
+                        ["allow", "warn", "deny", "forbid", "stable", "unstable"].contains(&name)
+                    }))
                     .cloned());
                 push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() })))
             }
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index d8f8decef39..d5f37aff222 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -109,52 +109,67 @@ impl<'a> CollectProcMacros<'a> {
             None => return,
         };
         if list.len() != 1 && list.len() != 2 {
-            self.handler.span_err(attr.span(),
+            self.handler.span_err(attr.span,
                                   "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) {
-            self.handler.span_err(trait_attr.span(),
-                                  "cannot override a built-in #[derive] mode");
+        if !trait_ident.can_be_raw() {
+            self.handler.span_err(trait_attr.span,
+                                  &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.can_be_raw() {
+                    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,
             });
@@ -247,8 +262,8 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
                                 to the same function", attr.path, prev_attr.path)
                     };
 
-                    self.handler.struct_span_err(attr.span(), &msg)
-                        .span_note(prev_attr.span(), "Previous attribute here")
+                    self.handler.struct_span_err(attr.span, &msg)
+                        .span_note(prev_attr.span, "Previous attribute here")
                         .emit();
 
                     return;
@@ -273,7 +288,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
             let msg = format!("the `#[{}]` attribute may only be used on bare functions",
                               attr.path);
 
-            self.handler.span_err(attr.span(), &msg);
+            self.handler.span_err(attr.span, &msg);
             return;
         }
 
@@ -285,7 +300,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
             let msg = format!("the `#[{}]` attribute is only usable with crates of the \
                               `proc-macro` crate type", attr.path);
 
-            self.handler.span_err(attr.span(), &msg);
+            self.handler.span_err(attr.span, &msg);
             return;
         }
 
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index a7ac95ba9ef..c0a9dfe6189 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -340,12 +340,8 @@ impl Ident {
         if !Self::is_valid(string) {
             panic!("`{:?}` is not a valid identifier", string)
         }
-        if is_raw {
-            let normalized_sym = Symbol::intern(string);
-            if normalized_sym == keywords::Underscore.name() ||
-               ast::Ident::with_empty_ctxt(normalized_sym).is_path_segment_keyword() {
-                panic!("`{:?}` is not a valid raw identifier", string)
-            }
+        if is_raw && !ast::Ident::from_str(string).can_be_raw() {
+            panic!("`{}` cannot be a raw identifier", string);
         }
         Ident { sym, is_raw, span }
     }
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index f4b625f8ea2..0dbcb7ce0b7 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -227,7 +227,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
                         .and_then(|mi| mi.value_str());
                     if list.len() != 1 || msg.is_none() {
                         sd.struct_span_warn(
-                            attr.span(),
+                            attr.span,
                             "argument must be of the form: \
                              `expected = \"error message\"`"
                         ).note("Errors in this attribute were erroneously \