diff options
| author | bors <bors@rust-lang.org> | 2019-03-16 20:48:40 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-03-16 20:48:40 +0000 |
| commit | 7cf074a1e655ac07d04d045667278fa1a9970b93 (patch) | |
| tree | d2509e198c34af3e41cce2dbde186635384a418a /src/libsyntax_ext | |
| parent | 2c8bbf50db0ef90a33f986ba8fc2e1fe129197ff (diff) | |
| parent | 2fd4cbb3f283b903f55444bb585d38a2539f4e8d (diff) | |
| download | rust-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.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/generic/mod.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax_ext/proc_macro_decls.rs | 67 | ||||
| -rw-r--r-- | src/libsyntax_ext/proc_macro_server.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax_ext/test.rs | 2 |
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 \ |
