Fix bug parsing #[derive] macro invocations.

This commit is contained in:
Jeffrey Seyfried 2017-04-03 22:23:32 +00:00
parent 5309a3e31d
commit 6a9448b523
4 changed files with 46 additions and 3 deletions

View file

@ -222,8 +222,10 @@ impl<'a> base::Resolver for Resolver<'a> {
let name = unwrap_or!(attrs[i].name(), continue);
if name == "derive" {
let result = attrs[i].parse_list(&self.session.parse_sess,
|parser| parser.parse_path(PathStyle::Mod));
let result = attrs[i].parse_list(&self.session.parse_sess, |parser| {
parser.parse_path_allowing_meta(PathStyle::Mod)
});
let mut traits = match result {
Ok(traits) => traits,
Err(mut e) => {

View file

@ -26,7 +26,8 @@ pub fn collect_derives(cx: &mut ExtCtxt, attrs: &mut Vec<ast::Attribute>) -> Vec
return true;
}
match attr.parse_list(cx.parse_sess, |parser| parser.parse_path(PathStyle::Mod)) {
match attr.parse_list(cx.parse_sess,
|parser| parser.parse_path_allowing_meta(PathStyle::Mod)) {
Ok(ref traits) if traits.is_empty() => {
cx.span_warn(attr.span, "empty trait list in `derive`");
false

View file

@ -1754,6 +1754,26 @@ impl<'a> Parser<'a> {
})
}
/// Like `parse_path`, but also supports parsing `Word` meta items into paths for back-compat.
/// This is used when parsing derive macro paths in `#[derive]` attributes.
pub fn parse_path_allowing_meta(&mut self, mode: PathStyle) -> PResult<'a, ast::Path> {
let meta_ident = match self.token {
token::Interpolated(ref nt) => match **nt {
token::NtMeta(ref meta) => match meta.node {
ast::MetaItemKind::Word => Some(ast::Ident::with_empty_ctxt(meta.name)),
_ => None,
},
_ => None,
},
_ => None,
};
if let Some(ident) = meta_ident {
self.bump();
return Ok(ast::Path::from_ident(self.prev_span, ident));
}
self.parse_path(mode)
}
/// Examples:
/// - `a::b<T,U>::c<V,W>`
/// - `a::b<T,U>::c(V) -> W`

View file

@ -0,0 +1,20 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
macro_rules! m {
($i:meta) => {
#[derive($i)]
struct S;
}
}
m!(Clone);
fn main() {}