about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-03-30 08:32:13 +0000
committerbors <bors@rust-lang.org>2019-03-30 08:32:13 +0000
commit6c49da45441d29aadd5935dabbaa8dc09ebad33a (patch)
treee3d8f54b557abdf322de702d4757293149e687c5 /src/libsyntax
parent709b72e7a73cbb798b728fd84c384bd0ad8ebf6c (diff)
parent62a78c4fcfca82cbdcdd13a5298885bd21e5d4d9 (diff)
downloadrust-6c49da45441d29aadd5935dabbaa8dc09ebad33a.tar.gz
rust-6c49da45441d29aadd5935dabbaa8dc09ebad33a.zip
Auto merge of #59550 - Centril:rollup, r=Centril
Rollup of 10 pull requests

Successful merges:

 - #59376 (RFC 2008: Enum Variants)
 - #59453 (Recover from parse error in tuple syntax)
 - #59455 (Account for short-hand field syntax when suggesting borrow)
 - #59499 (Fix broken download link in the armhf-gnu image)
 - #59512 (implement `AsRawFd` for stdio locks)
 - #59525 (Whitelist some rustc attrs)
 - #59528 (Improve the dbg! macro docs )
 - #59532 (In doc examples, don't ignore read/write results)
 - #59534 (rustdoc: collapse blanket impls in the same way as normal impls)
 - #59537 (Fix OnceWith docstring.)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/feature_gate.rs16
-rw-r--r--src/libsyntax/parse/parser.rs83
2 files changed, 72 insertions, 27 deletions
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 96c89d3176a..dcb55fb572f 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -906,7 +906,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
                                          not currently handle destructors.",
                                         cfg_fn!(thread_local))),
 
-    ("rustc_on_unimplemented", Normal, template!(List:
+    ("rustc_on_unimplemented", Whitelisted, template!(List:
                           r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
                           NameValueStr: "message"),
                                              Gated(Stability::Unstable,
@@ -962,6 +962,20 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
             is just used for rustc unit tests \
             and will never be stable",
            cfg_fn!(rustc_attrs))),
+    ("rustc_layout_scalar_valid_range_start", Whitelisted, template!(List: "value"),
+     Gated(Stability::Unstable,
+           "rustc_attrs",
+           "the `#[rustc_layout_scalar_valid_range_start]` attribute \
+            is just used to enable niche optimizations in libcore \
+            and will never be stable",
+           cfg_fn!(rustc_attrs))),
+    ("rustc_layout_scalar_valid_range_end", Whitelisted, template!(List: "value"),
+     Gated(Stability::Unstable,
+           "rustc_attrs",
+           "the `#[rustc_layout_scalar_valid_range_end]` attribute \
+            is just used to enable niche optimizations in libcore \
+            and will never be stable",
+           cfg_fn!(rustc_attrs))),
     ("rustc_regions", Normal, template!(Word), Gated(Stability::Unstable,
                                     "rustc_attrs",
                                     "the `#[rustc_regions]` attribute \
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 79c1f0cb4cc..ae8e57d54de 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2626,7 +2626,13 @@ impl<'a> Parser<'a> {
                 let mut trailing_comma = false;
                 let mut recovered = false;
                 while self.token != token::CloseDelim(token::Paren) {
-                    es.push(self.parse_expr()?);
+                    es.push(match self.parse_expr() {
+                        Ok(es) => es,
+                        Err(err) => {
+                            // recover from parse error in tuple list
+                            return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err)));
+                        }
+                    });
                     recovered = self.expect_one_of(
                         &[],
                         &[token::Comma, token::CloseDelim(token::Paren)],
@@ -3237,36 +3243,54 @@ impl<'a> Parser<'a> {
             }
             if self.expr_is_complete(&e) { break; }
             match self.token {
-              // expr(...)
-              token::OpenDelim(token::Paren) => {
-                let es = self.parse_unspanned_seq(
-                    &token::OpenDelim(token::Paren),
-                    &token::CloseDelim(token::Paren),
-                    SeqSep::trailing_allowed(token::Comma),
-                    |p| Ok(p.parse_expr()?)
-                )?;
-                hi = self.prev_span;
-
-                let nd = self.mk_call(e, es);
-                e = self.mk_expr(lo.to(hi), nd, ThinVec::new());
-              }
+                // expr(...)
+                token::OpenDelim(token::Paren) => {
+                    let seq = self.parse_unspanned_seq(
+                        &token::OpenDelim(token::Paren),
+                        &token::CloseDelim(token::Paren),
+                        SeqSep::trailing_allowed(token::Comma),
+                        |p| Ok(p.parse_expr()?)
+                    ).map(|es| {
+                        let nd = self.mk_call(e, es);
+                        let hi = self.prev_span;
+                        self.mk_expr(lo.to(hi), nd, ThinVec::new())
+                    });
+                    e = self.recover_seq_parse_error(token::Paren, lo, seq);
+                }
 
-              // expr[...]
-              // Could be either an index expression or a slicing expression.
-              token::OpenDelim(token::Bracket) => {
-                self.bump();
-                let ix = self.parse_expr()?;
-                hi = self.span;
-                self.expect(&token::CloseDelim(token::Bracket))?;
-                let index = self.mk_index(e, ix);
-                e = self.mk_expr(lo.to(hi), index, ThinVec::new())
-              }
-              _ => return Ok(e)
+                // expr[...]
+                // Could be either an index expression or a slicing expression.
+                token::OpenDelim(token::Bracket) => {
+                    self.bump();
+                    let ix = self.parse_expr()?;
+                    hi = self.span;
+                    self.expect(&token::CloseDelim(token::Bracket))?;
+                    let index = self.mk_index(e, ix);
+                    e = self.mk_expr(lo.to(hi), index, ThinVec::new())
+                }
+                _ => return Ok(e)
             }
         }
         return Ok(e);
     }
 
+    fn recover_seq_parse_error(
+        &mut self,
+        delim: token::DelimToken,
+        lo: Span,
+        result: PResult<'a, P<Expr>>,
+    ) -> P<Expr> {
+        match result {
+            Ok(x) => x,
+            Err(mut err) => {
+                err.emit();
+                // recover from parse error
+                self.consume_block(delim);
+                self.mk_expr(lo.to(self.prev_span), ExprKind::Err, ThinVec::new())
+            }
+        }
+    }
+
     crate fn process_potential_macro_variable(&mut self) {
         let (token, span) = match self.token {
             token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() &&
@@ -4253,7 +4277,14 @@ impl<'a> Parser<'a> {
     // Trailing commas are significant because (p) and (p,) are different patterns.
     fn parse_parenthesized_pat_list(&mut self) -> PResult<'a, (Vec<P<Pat>>, Option<usize>, bool)> {
         self.expect(&token::OpenDelim(token::Paren))?;
-        let result = self.parse_pat_list()?;
+        let result = match self.parse_pat_list() {
+            Ok(result) => result,
+            Err(mut err) => { // recover from parse error in tuple pattern list
+                err.emit();
+                self.consume_block(token::Paren);
+                return Ok((vec![], Some(0), false));
+            }
+        };
         self.expect(&token::CloseDelim(token::Paren))?;
         Ok(result)
     }