about summary refs log tree commit diff
path: root/src/libsyntax/attr
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-01-16 15:01:20 +0000
committerbors <bors@rust-lang.org>2019-01-16 15:01:20 +0000
commitceb2512144d1fc26330e85fb9d41c22ba1866259 (patch)
tree698f2e468d5964e3e7368af3c48e706d035df6da /src/libsyntax/attr
parentcccaf9a8c69219c8267e406f92fef895fbba80f2 (diff)
parentd3411d3ee8a350e2b8ec202a4a493e69c827245c (diff)
downloadrust-ceb2512144d1fc26330e85fb9d41c22ba1866259.tar.gz
rust-ceb2512144d1fc26330e85fb9d41c22ba1866259.zip
Auto merge of #57321 - petrochenkov:atokens, r=nikomatsakis
Implement basic input validation for built-in attributes

Correct top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is enforced for built-in attributes, built-in attributes must also fit into the "meta-item" syntax (aka the "classic attribute syntax").

For some subset of attributes (found by crater run), errors are lowered to deprecation warnings.

NOTE: This PR previously included https://github.com/rust-lang/rust/pull/57367 as well.
Diffstat (limited to 'src/libsyntax/attr')
-rw-r--r--src/libsyntax/attr/builtin.rs3
-rw-r--r--src/libsyntax/attr/mod.rs43
2 files changed, 24 insertions, 22 deletions
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 98585dc1e6f..15e480496f7 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -436,9 +436,6 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
                 }
                 _ => unreachable!()
             }
-        } else {
-            span_err!(diagnostic, attr.span(), E0548, "incorrect stability attribute type");
-            continue
         }
     }
 
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index d03563f8891..f83c1ec1455 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -481,28 +481,33 @@ impl MetaItem {
     {
         // FIXME: Share code with `parse_path`.
         let ident = match tokens.next() {
-            Some(TokenTree::Token(span, Token::Ident(ident, _))) => {
-                if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
-                    let mut segments = vec![PathSegment::from_ident(ident.with_span_pos(span))];
-                    tokens.next();
-                    loop {
-                        if let Some(TokenTree::Token(span,
-                                                     Token::Ident(ident, _))) = tokens.next() {
-                            segments.push(PathSegment::from_ident(ident.with_span_pos(span)));
-                        } else {
-                            return None;
-                        }
-                        if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
-                            tokens.next();
-                        } else {
-                            break;
-                        }
+            Some(TokenTree::Token(span, token @ Token::Ident(..))) |
+            Some(TokenTree::Token(span, token @ Token::ModSep)) => 'arm: {
+                let mut segments = if let Token::Ident(ident, _) = token {
+                    if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
+                        tokens.next();
+                        vec![PathSegment::from_ident(ident.with_span_pos(span))]
+                    } else {
+                        break 'arm Path::from_ident(ident.with_span_pos(span));
                     }
-                    let span = span.with_hi(segments.last().unwrap().ident.span.hi());
-                    Path { span, segments }
                 } else {
-                    Path::from_ident(ident.with_span_pos(span))
+                    vec![PathSegment::path_root(span)]
+                };
+                loop {
+                    if let Some(TokenTree::Token(span,
+                                                    Token::Ident(ident, _))) = tokens.next() {
+                        segments.push(PathSegment::from_ident(ident.with_span_pos(span)));
+                    } else {
+                        return None;
+                    }
+                    if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
+                        tokens.next();
+                    } else {
+                        break;
+                    }
                 }
+                let span = span.with_hi(segments.last().unwrap().ident.span.hi());
+                Path { span, segments }
             }
             Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 {
                 token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),