about summary refs log tree commit diff
path: root/src/libsyntax_expand
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-12-21 11:05:03 +0000
committerbors <bors@rust-lang.org>2019-12-21 11:05:03 +0000
commitc64eecf4d0907095928fb36fd3a1dd5fb2d9ff06 (patch)
tree073a8038727414aed13f54622fce43ca63990ca6 /src/libsyntax_expand
parent9ff30a7810c586819a78188c173a7b74adbb9730 (diff)
parent621661f8a63f2118f3add5c3d686d9a2b6f62e5e (diff)
downloadrust-c64eecf4d0907095928fb36fd3a1dd5fb2d9ff06.tar.gz
rust-c64eecf4d0907095928fb36fd3a1dd5fb2d9ff06.zip
Auto merge of #66994 - Centril:stmt-polish, r=estebank
refactor expr & stmt parsing + improve recovery

Summary of important changes (best read commit-by-commit, ignoring whitespace changes):

- `AttrVec` is introduces as an alias for `ThinVec<Attribute>`
- `parse_expr_bottom` and `parse_stmt` are thoroughly refactored.
- Extract diagnostics logic for `vec![...]` in a pattern context.
- Recovery is added for `do catch { ... }`
- Recovery is added for `'label: non_block_expr`
- Recovery is added for `var $local`, `auto $local`, and `mut $local`. Fixes #65257.
- Recovery is added for `e1 and e2` and `e1 or e2`.
- ~~`macro_legacy_warnings` is turned into an error (has been a warning for 3 years!)~~
- Fixes #63396 by forward-porting #64105 which now works thanks to added recovery.
- `ui-fulldeps/ast_stmt_expr_attr.rs` is turned into UI and pretty tests.
- Recovery is fixed for `#[attr] if expr {}`

r? @estebank
Diffstat (limited to 'src/libsyntax_expand')
-rw-r--r--src/libsyntax_expand/base.rs3
-rw-r--r--src/libsyntax_expand/build.rs15
-rw-r--r--src/libsyntax_expand/mbe/macro_rules.rs46
-rw-r--r--src/libsyntax_expand/placeholders.rs5
4 files changed, 35 insertions, 34 deletions
diff --git a/src/libsyntax_expand/base.rs b/src/libsyntax_expand/base.rs
index 75066a006bf..2ad327e872e 100644
--- a/src/libsyntax_expand/base.rs
+++ b/src/libsyntax_expand/base.rs
@@ -9,7 +9,6 @@ use syntax::mut_visit::{self, MutVisitor};
 use syntax::ptr::P;
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym, Ident, Symbol};
-use syntax::ThinVec;
 use syntax::token;
 use syntax::tokenstream::{self, TokenStream};
 use syntax::visit::Visitor;
@@ -552,7 +551,7 @@ impl DummyResult {
             id: ast::DUMMY_NODE_ID,
             kind: if is_error { ast::ExprKind::Err } else { ast::ExprKind::Tup(Vec::new()) },
             span: sp,
-            attrs: ThinVec::new(),
+            attrs: ast::AttrVec::new(),
         })
     }
 
diff --git a/src/libsyntax_expand/build.rs b/src/libsyntax_expand/build.rs
index 3d082101c41..4c539cad111 100644
--- a/src/libsyntax_expand/build.rs
+++ b/src/libsyntax_expand/build.rs
@@ -1,11 +1,10 @@
 use crate::base::ExtCtxt;
 
-use syntax::ast::{self, Ident, Expr, BlockCheckMode, UnOp, PatKind};
+use syntax::ast::{self, AttrVec, Ident, Expr, BlockCheckMode, UnOp, PatKind};
 use syntax::attr;
 use syntax::source_map::{respan, Spanned};
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
-use syntax::ThinVec;
 
 use syntax_pos::{Pos, Span};
 
@@ -81,7 +80,7 @@ impl<'a> ExtCtxt<'a> {
                 id: ast::DUMMY_NODE_ID,
                 kind,
                 span,
-                attrs: ThinVec::new(),
+                attrs: AttrVec::new(),
             })
         }
     }
@@ -190,7 +189,7 @@ impl<'a> ExtCtxt<'a> {
             init: Some(ex),
             id: ast::DUMMY_NODE_ID,
             span: sp,
-            attrs: ThinVec::new(),
+            attrs: AttrVec::new(),
         });
         ast::Stmt {
             id: ast::DUMMY_NODE_ID,
@@ -207,7 +206,7 @@ impl<'a> ExtCtxt<'a> {
             init: None,
             id: ast::DUMMY_NODE_ID,
             span,
-            attrs: ThinVec::new(),
+            attrs: AttrVec::new(),
         });
         ast::Stmt {
             id: ast::DUMMY_NODE_ID,
@@ -245,7 +244,7 @@ impl<'a> ExtCtxt<'a> {
             id: ast::DUMMY_NODE_ID,
             kind,
             span,
-            attrs: ThinVec::new(),
+            attrs: AttrVec::new(),
         })
     }
 
@@ -304,7 +303,7 @@ impl<'a> ExtCtxt<'a> {
             expr: e,
             span,
             is_shorthand: false,
-            attrs: ThinVec::new(),
+            attrs: AttrVec::new(),
             id: ast::DUMMY_NODE_ID,
             is_placeholder: false,
         }
@@ -549,7 +548,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn param(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Param {
         let arg_pat = self.pat_ident(span, ident);
         ast::Param {
-            attrs: ThinVec::default(),
+            attrs: AttrVec::default(),
             id: ast::DUMMY_NODE_ID,
             pat: arg_pat,
             span,
diff --git a/src/libsyntax_expand/mbe/macro_rules.rs b/src/libsyntax_expand/mbe/macro_rules.rs
index 2dd15872a9f..107fe388ed0 100644
--- a/src/libsyntax_expand/mbe/macro_rules.rs
+++ b/src/libsyntax_expand/mbe/macro_rules.rs
@@ -63,6 +63,30 @@ crate fn annotate_err_with_kind(
     };
 }
 
+/// Instead of e.g. `vec![a, b, c]` in a pattern context, suggest `[a, b, c]`.
+fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Parser<'_>) {
+    let mut suggestion = None;
+    if let Ok(code) = parser.sess.source_map().span_to_snippet(site_span) {
+        if let Some(bang) = code.find('!') {
+            suggestion = Some(code[bang + 1..].to_string());
+        }
+    }
+    if let Some(suggestion) = suggestion {
+        e.span_suggestion(
+            site_span,
+            "use a slice pattern here instead",
+            suggestion,
+            Applicability::MachineApplicable,
+        );
+    } else {
+        e.span_label(site_span, "use a slice pattern here instead");
+    }
+    e.help(
+        "for more information, see https://doc.rust-lang.org/edition-guide/\
+        rust-2018/slice-patterns.html"
+    );
+}
+
 impl<'a> ParserAnyMacro<'a> {
     crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
         let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
@@ -92,27 +116,7 @@ impl<'a> ParserAnyMacro<'a> {
             }
             match kind {
                 AstFragmentKind::Pat if macro_ident.name == sym::vec => {
-                    let mut suggestion = None;
-                    if let Ok(code) = parser.sess.source_map().span_to_snippet(site_span) {
-                        if let Some(bang) = code.find('!') {
-                            suggestion = Some(code[bang + 1..].to_string());
-                        }
-                    }
-                    if let Some(suggestion) = suggestion {
-                        e.span_suggestion(
-                            site_span,
-                            "use a slice pattern here instead",
-                            suggestion,
-                            Applicability::MachineApplicable,
-                        );
-                    } else {
-                        e.span_label(
-                            site_span,
-                            "use a slice pattern here instead",
-                        );
-                    }
-                    e.help("for more information, see https://doc.rust-lang.org/edition-guide/\
-                            rust-2018/slice-patterns.html");
+                    suggest_slice_pat(&mut e, site_span, parser);
                 }
                 _ => annotate_err_with_kind(&mut e, kind, site_span),
             };
diff --git a/src/libsyntax_expand/placeholders.rs b/src/libsyntax_expand/placeholders.rs
index 22e99baae5b..4298e0e74b6 100644
--- a/src/libsyntax_expand/placeholders.rs
+++ b/src/libsyntax_expand/placeholders.rs
@@ -5,7 +5,6 @@ use syntax::ast;
 use syntax::source_map::{DUMMY_SP, dummy_spanned};
 use syntax::mut_visit::*;
 use syntax::ptr::P;
-use syntax::ThinVec;
 
 use smallvec::{smallvec, SmallVec};
 
@@ -28,7 +27,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId, vis: Option<ast::Visi
     let span = DUMMY_SP;
     let expr_placeholder = || P(ast::Expr {
         id, span,
-        attrs: ThinVec::new(),
+        attrs: ast::AttrVec::new(),
         kind: ast::ExprKind::Mac(mac_placeholder()),
     });
     let ty = || P(ast::Ty {
@@ -75,7 +74,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId, vis: Option<ast::Visi
             id, span, kind: ast::TyKind::Mac(mac_placeholder()),
         })),
         AstFragmentKind::Stmts => AstFragment::Stmts(smallvec![{
-            let mac = P((mac_placeholder(), ast::MacStmtStyle::Braces, ThinVec::new()));
+            let mac = P((mac_placeholder(), ast::MacStmtStyle::Braces, ast::AttrVec::new()));
             ast::Stmt { id, span, kind: ast::StmtKind::Mac(mac) }
         }]),
         AstFragmentKind::Arms => AstFragment::Arms(smallvec![