diff options
| author | bors <bors@rust-lang.org> | 2021-07-26 21:50:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-07-26 21:50:24 +0000 |
| commit | 8bebfe5cc2db1603be0d4ad79ad17d48e3b20e54 (patch) | |
| tree | 2de080e1558f17a4a5879c822811c024d5602715 /compiler/rustc_parse/src/parser | |
| parent | 08095fc1f875c89e507f17cf6c6a780c8ffa4c01 (diff) | |
| parent | 12c2092adb24e6cdc2bf2da71190beb2a66e381e (diff) | |
| download | rust-8bebfe5cc2db1603be0d4ad79ad17d48e3b20e54.tar.gz rust-8bebfe5cc2db1603be0d4ad79ad17d48e3b20e54.zip | |
Auto merge of #87480 - GuillaumeGomez:rollup-3ly8t5d, r=GuillaumeGomez
Rollup of 8 pull requests
Successful merges:
- #87436 (Suggest `;` on parse error where applicable)
- #87444 (Flatten nested `format!` calls)
- #87447 (Miri: santiy check that null pointer can never have an AllocId)
- #87457 (freebsd remove compiler workaround.)
- #87458 (Fix help message for modification to &T created by &{t})
- #87464 (Remove unnecessary `structhead` parameter from `render_union`)
- #87473 (Notify the Rust 2021 edition working group in zulip of edition bugs)
- #87474 (Add missing whitespace after attribute in HTML template)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 114 |
1 files changed, 57 insertions, 57 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index b37caaebfb6..9818bd8d314 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -242,6 +242,63 @@ impl<'a> Parser<'a> { expected.sort_by_cached_key(|x| x.to_string()); expected.dedup(); + let sm = self.sess.source_map(); + let msg = format!("expected `;`, found {}", super::token_descr(&self.token)); + let appl = Applicability::MachineApplicable; + if expected.contains(&TokenType::Token(token::Semi)) { + if self.token.span == DUMMY_SP || self.prev_token.span == DUMMY_SP { + // Likely inside a macro, can't provide meaningful suggestions. + } else if !sm.is_multiline(self.prev_token.span.until(self.token.span)) { + // The current token is in the same line as the prior token, not recoverable. + } else if [token::Comma, token::Colon].contains(&self.token.kind) + && self.prev_token.kind == token::CloseDelim(token::Paren) + { + // Likely typo: The current token is on a new line and is expected to be + // `.`, `;`, `?`, or an operator after a close delimiter token. + // + // let a = std::process::Command::new("echo") + // .arg("1") + // ,arg("2") + // ^ + // https://github.com/rust-lang/rust/issues/72253 + } else if self.look_ahead(1, |t| { + t == &token::CloseDelim(token::Brace) + || t.can_begin_expr() && t.kind != token::Colon + }) && [token::Comma, token::Colon].contains(&self.token.kind) + { + // Likely typo: `,` → `;` or `:` → `;`. This is triggered if the current token is + // either `,` or `:`, and the next token could either start a new statement or is a + // block close. For example: + // + // let x = 32: + // let y = 42; + self.bump(); + let sp = self.prev_token.span; + self.struct_span_err(sp, &msg) + .span_suggestion_short(sp, "change this to `;`", ";".to_string(), appl) + .emit(); + return Ok(false); + } else if self.look_ahead(0, |t| { + t == &token::CloseDelim(token::Brace) + || ( + t.can_begin_expr() && t != &token::Semi && t != &token::Pound + // Avoid triggering with too many trailing `#` in raw string. + ) + }) { + // Missing semicolon typo. This is triggered if the next token could either start a + // new statement or is a block close. For example: + // + // let x = 32 + // let y = 42; + let sp = self.prev_token.span.shrink_to_hi(); + self.struct_span_err(sp, &msg) + .span_label(self.token.span, "unexpected token") + .span_suggestion_short(sp, "add `;` here", ";".to_string(), appl) + .emit(); + return Ok(false); + } + } + let expect = tokens_to_string(&expected[..]); let actual = super::token_descr(&self.token); let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 { @@ -303,7 +360,6 @@ impl<'a> Parser<'a> { return Err(err); } - let sm = self.sess.source_map(); if self.prev_token.span == DUMMY_SP { // Account for macro context where the previous span might not be // available to avoid incorrect output (#54841). @@ -1144,62 +1200,6 @@ impl<'a> Parser<'a> { if self.eat(&token::Semi) { return Ok(()); } - let sm = self.sess.source_map(); - let msg = format!("expected `;`, found {}", super::token_descr(&self.token)); - let appl = Applicability::MachineApplicable; - if self.token.span == DUMMY_SP || self.prev_token.span == DUMMY_SP { - // Likely inside a macro, can't provide meaningful suggestions. - return self.expect(&token::Semi).map(drop); - } else if !sm.is_multiline(self.prev_token.span.until(self.token.span)) { - // The current token is in the same line as the prior token, not recoverable. - } else if [token::Comma, token::Colon].contains(&self.token.kind) - && self.prev_token.kind == token::CloseDelim(token::Paren) - { - // Likely typo: The current token is on a new line and is expected to be - // `.`, `;`, `?`, or an operator after a close delimiter token. - // - // let a = std::process::Command::new("echo") - // .arg("1") - // ,arg("2") - // ^ - // https://github.com/rust-lang/rust/issues/72253 - self.expect(&token::Semi)?; - return Ok(()); - } else if self.look_ahead(1, |t| { - t == &token::CloseDelim(token::Brace) || t.can_begin_expr() && t.kind != token::Colon - }) && [token::Comma, token::Colon].contains(&self.token.kind) - { - // Likely typo: `,` → `;` or `:` → `;`. This is triggered if the current token is - // either `,` or `:`, and the next token could either start a new statement or is a - // block close. For example: - // - // let x = 32: - // let y = 42; - self.bump(); - let sp = self.prev_token.span; - self.struct_span_err(sp, &msg) - .span_suggestion_short(sp, "change this to `;`", ";".to_string(), appl) - .emit(); - return Ok(()); - } else if self.look_ahead(0, |t| { - t == &token::CloseDelim(token::Brace) - || ( - t.can_begin_expr() && t != &token::Semi && t != &token::Pound - // Avoid triggering with too many trailing `#` in raw string. - ) - }) { - // Missing semicolon typo. This is triggered if the next token could either start a - // new statement or is a block close. For example: - // - // let x = 32 - // let y = 42; - let sp = self.prev_token.span.shrink_to_hi(); - self.struct_span_err(sp, &msg) - .span_label(self.token.span, "unexpected token") - .span_suggestion_short(sp, "add `;` here", ";".to_string(), appl) - .emit(); - return Ok(()); - } self.expect(&token::Semi).map(drop) // Error unconditionally } |
