diff options
| author | bors <bors@rust-lang.org> | 2020-03-11 13:05:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-03-11 13:05:52 +0000 |
| commit | c20d7eecbc0928b57da8fe30b2ef8528e2bdd5be (patch) | |
| tree | e8f110a9249dbcf8ce290bda1b3c7702488247fa /src/librustc_parse/parser/stmt.rs | |
| parent | 303d8aff6092709edd4dbd35b1c88e9aa40bf6d8 (diff) | |
| parent | a77206fa4a35e7926fb4404bd167b06e342b7626 (diff) | |
Auto merge of #69919 - Centril:rollup-fxo33zs, r=Centril
Rollup of 8 pull requests Successful merges: - #66472 (--show-coverage json) - #69603 (tidy: replace `make check` with `./x.py test` in documentation) - #69760 (Improve expression & attribute parsing) - #69828 (fix memory leak when vec::IntoIter panics during drop) - #69850 (panic_bounds_check: use caller_location, like PanicFnLangItem) - #69876 (Add long error explanation for E0739) - #69888 ([Miri] Use a session variable instead of checking for an env var always) - #69893 (librustc_codegen_llvm: Use slices instead of 0-terminated strings) Failed merges: r? @ghost
Diffstat (limited to 'src/librustc_parse/parser/stmt.rs')
| -rw-r--r-- | src/librustc_parse/parser/stmt.rs | 57 |
1 files changed, 28 insertions, 29 deletions
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 3864ec3aaa1..489549a5750 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -1,3 +1,4 @@ +use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN; use super::diagnostics::Error; use super::expr::LhsExpr; use super::pat::GateOr; @@ -47,10 +48,7 @@ impl<'a> Parser<'a> { self.bump(); // `var` let msg = "write `let` instead of `var` to introduce a new variable"; self.recover_stmt_local(lo, attrs.into(), msg, "let")? - } else if self.token.is_path_start() - && !self.token.is_qpath_start() - && !self.is_path_start_item() - { + } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() { // We have avoided contextual keywords like `union`, items with `crate` visibility, // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something // that starts like a path (1 token), but it fact not a path. @@ -238,15 +236,11 @@ impl<'a> Parser<'a> { /// Parses a block. No inner attributes are allowed. pub fn parse_block(&mut self) -> PResult<'a, P<Block>> { - maybe_whole!(self, NtBlock, |x| x); - - let lo = self.token.span; - - if !self.eat(&token::OpenDelim(token::Brace)) { - return self.error_block_no_opening_brace(); + let (attrs, block) = self.parse_inner_attrs_and_block()?; + if let [.., last] = &*attrs { + self.error_on_forbidden_inner_attr(last.span, DEFAULT_INNER_ATTR_FORBIDDEN); } - - self.parse_block_tail(lo, BlockCheckMode::Default) + Ok(block) } fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> { @@ -262,16 +256,14 @@ impl<'a> Parser<'a> { // // which is valid in other languages, but not Rust. match self.parse_stmt_without_recovery() { - Ok(Some(stmt)) => { + // If the next token is an open brace (e.g., `if a b {`), the place- + // inside-a-block suggestion would be more likely wrong than right. + Ok(Some(_)) if self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace)) - || do_not_suggest_help - { - // If the next token is an open brace (e.g., `if a b {`), the place- - // inside-a-block suggestion would be more likely wrong than right. - e.span_label(sp, "expected `{`"); - return Err(e); - } - let stmt_span = if self.eat(&token::Semi) { + || do_not_suggest_help => {} + Ok(Some(stmt)) => { + let stmt_own_line = self.sess.source_map().is_line_before_span_empty(sp); + let stmt_span = if stmt_own_line && self.eat(&token::Semi) { // Expand the span to include the semicolon. stmt.span.with_hi(self.prev_token.span.hi()) } else { @@ -301,20 +293,27 @@ impl<'a> Parser<'a> { pub(super) fn parse_inner_attrs_and_block( &mut self, ) -> PResult<'a, (Vec<Attribute>, P<Block>)> { + self.parse_block_common(self.token.span, BlockCheckMode::Default) + } + + /// Parses a block. Inner attributes are allowed. + pub(super) fn parse_block_common( + &mut self, + lo: Span, + blk_mode: BlockCheckMode, + ) -> PResult<'a, (Vec<Attribute>, P<Block>)> { maybe_whole!(self, NtBlock, |x| (Vec::new(), x)); - let lo = self.token.span; - self.expect(&token::OpenDelim(token::Brace))?; - Ok((self.parse_inner_attributes()?, self.parse_block_tail(lo, BlockCheckMode::Default)?)) + if !self.eat(&token::OpenDelim(token::Brace)) { + return self.error_block_no_opening_brace(); + } + + Ok((self.parse_inner_attributes()?, self.parse_block_tail(lo, blk_mode)?)) } /// Parses the rest of a block expression or function body. /// Precondition: already parsed the '{'. - pub(super) fn parse_block_tail( - &mut self, - lo: Span, - s: BlockCheckMode, - ) -> PResult<'a, P<Block>> { + fn parse_block_tail(&mut self, lo: Span, s: BlockCheckMode) -> PResult<'a, P<Block>> { let mut stmts = vec![]; while !self.eat(&token::CloseDelim(token::Brace)) { if self.token == token::Eof { |
