about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2017-03-08 23:13:35 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2017-03-14 04:39:21 +0000
commit839c2860ccb7cd3d381abf2838dfba566f52618e (patch)
treede9b57f15703328322a174cb820ba1e97bd29bba /src/libsyntax/parse
parent68c1cc68b44bb987ec57251bc457a55292515d1d (diff)
downloadrust-839c2860ccb7cd3d381abf2838dfba566f52618e.tar.gz
rust-839c2860ccb7cd3d381abf2838dfba566f52618e.zip
Liberalize attributes.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/attr.rs32
-rw-r--r--src/libsyntax/parse/parser.rs11
2 files changed, 36 insertions, 7 deletions
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 272cff7ad34..53106214fa3 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -14,8 +14,9 @@ use syntax_pos::{mk_sp, Span};
 use codemap::spanned;
 use parse::common::SeqSep;
 use parse::PResult;
-use parse::token;
-use parse::parser::{Parser, TokenType};
+use parse::token::{self, Nonterminal};
+use parse::parser::{Parser, TokenType, PathStyle};
+use tokenstream::TokenStream;
 
 #[derive(PartialEq, Eq, Debug)]
 enum InnerAttributeParsePolicy<'a> {
@@ -91,7 +92,7 @@ impl<'a> Parser<'a> {
         debug!("parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}",
                inner_parse_policy,
                self.token);
-        let (span, value, mut style) = match self.token {
+        let (span, path, tokens, mut style) = match self.token {
             token::Pound => {
                 let lo = self.span.lo;
                 self.bump();
@@ -119,11 +120,11 @@ impl<'a> Parser<'a> {
                 };
 
                 self.expect(&token::OpenDelim(token::Bracket))?;
-                let meta_item = self.parse_meta_item()?;
+                let (path, tokens) = self.parse_path_and_tokens()?;
                 self.expect(&token::CloseDelim(token::Bracket))?;
                 let hi = self.prev_span.hi;
 
-                (mk_sp(lo, hi), meta_item, style)
+                (mk_sp(lo, hi), path, tokens, style)
             }
             _ => {
                 let token_str = self.this_token_to_string();
@@ -143,13 +144,30 @@ impl<'a> Parser<'a> {
         Ok(ast::Attribute {
             id: attr::mk_attr_id(),
             style: style,
-            path: ast::Path::from_ident(value.span, ast::Ident::with_empty_ctxt(value.name)),
-            tokens: value.node.tokens(value.span),
+            path: path,
+            tokens: tokens,
             is_sugared_doc: false,
             span: span,
         })
     }
 
+    pub fn parse_path_and_tokens(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
+        let meta = match self.token {
+            token::Interpolated(ref nt) => match **nt {
+                Nonterminal::NtMeta(ref meta) => Some(meta.clone()),
+                _ => None,
+            },
+            _ => None,
+        };
+        Ok(if let Some(meta) = meta {
+            self.bump();
+            (ast::Path::from_ident(meta.span, ast::Ident::with_empty_ctxt(meta.name)),
+             meta.node.tokens(meta.span))
+        } else {
+            (self.parse_path(PathStyle::Mod)?, self.parse_tokens())
+        })
+    }
+
     /// Parse attributes that appear after the opening of an item. These should
     /// be preceded by an exclamation mark, but we accept and warn about one
     /// terminated by a semicolon.
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ed512b89987..308876fed56 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2644,6 +2644,17 @@ impl<'a> Parser<'a> {
         Ok(tts)
     }
 
+    pub fn parse_tokens(&mut self) -> TokenStream {
+        let mut result = Vec::new();
+        loop {
+            match self.token {
+                token::Eof | token::CloseDelim(..) => break,
+                _ => result.push(self.parse_token_tree().into()),
+            }
+        }
+        TokenStream::concat(result)
+    }
+
     /// Parse a prefix-unary-operator expr
     pub fn parse_prefix_expr(&mut self,
                              already_parsed_attrs: Option<ThinVec<Attribute>>)