about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-14 06:40:58 +0000
committerbors <bors@rust-lang.org>2022-08-14 06:40:58 +0000
commit2fbc08e2ce64dee45a29cb6133da6b32366268aa (patch)
tree1f98e1b9929f847869ccbbc86f2f241e81126588 /compiler/rustc_parse/src/parser
parentd70c0ecfae6dd9cb00ffae9ad806c47256c9ef15 (diff)
parentb3e76aa491e798bdc998d67f0b327147cf675734 (diff)
downloadrust-2fbc08e2ce64dee45a29cb6133da6b32366268aa.tar.gz
rust-2fbc08e2ce64dee45a29cb6133da6b32366268aa.zip
Auto merge of #100516 - compiler-errors:rollup-fgrfeb3, r=compiler-errors
Rollup of 8 pull requests

Successful merges:

 - #99646 (Only point out a single function parameter if we have a single arg incompatibility)
 - #100299 (make `clean::Item::span` return `Option` instead of dummy span)
 - #100335 (Rustdoc-Json: Add `Path` type for traits.)
 - #100367 (Suggest the path separator when a dot is used on a trait)
 - #100431 (Enum variant ctor inherits the stability of the enum variant)
 - #100446 (Suggest removing a semicolon after impl/trait items)
 - #100468 (Use an extensionless `x` script for non-Windows)
 - #100479 (Argument type error improvements)

Failed merges:

 - #100483 (Point to generic or arg if it's the self type of unsatisfied projection predicate)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs38
2 files changed, 35 insertions, 5 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 2880ef78c8d..33bebfc2c9a 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2268,7 +2268,7 @@ impl<'a> Parser<'a> {
                     attrs: attrs.into(),
                     ty,
                     pat,
-                    span: lo.to(this.token.span),
+                    span: lo.to(this.prev_token.span),
                     id: DUMMY_NODE_ID,
                     is_placeholder: false,
                 },
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index ac55aee9883..c6dd5e7fda3 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -675,14 +675,44 @@ impl<'a> Parser<'a> {
             }
             match parse_item(self) {
                 Ok(None) => {
+                    let is_unnecessary_semicolon = !items.is_empty()
+                        // When the close delim is `)` in a case like the following, `token.kind` is expected to be `token::CloseDelim(Delimiter::Parenthesis)`,
+                        // but the actual `token.kind` is `token::CloseDelim(Delimiter::Bracket)`.
+                        // This is because the `token.kind` of the close delim is treated as the same as
+                        // that of the open delim in `TokenTreesReader::parse_token_tree`, even if the delimiters of them are different.
+                        // Therefore, `token.kind` should not be compared here.
+                        //
+                        // issue-60075.rs
+                        // ```
+                        // trait T {
+                        //     fn qux() -> Option<usize> {
+                        //         let _ = if true {
+                        //         });
+                        //          ^ this close delim
+                        //         Some(4)
+                        //     }
+                        // ```
+                        && self
+                            .span_to_snippet(self.prev_token.span)
+                            .map_or(false, |snippet| snippet == "}")
+                        && self.token.kind == token::Semi;
+                    let semicolon_span = self.token.span;
                     // We have to bail or we'll potentially never make progress.
                     let non_item_span = self.token.span;
                     self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
-                    self.struct_span_err(non_item_span, "non-item in item list")
-                        .span_label(open_brace_span, "item list starts here")
+                    let mut err = self.struct_span_err(non_item_span, "non-item in item list");
+                    err.span_label(open_brace_span, "item list starts here")
                         .span_label(non_item_span, "non-item starts here")
-                        .span_label(self.prev_token.span, "item list ends here")
-                        .emit();
+                        .span_label(self.prev_token.span, "item list ends here");
+                    if is_unnecessary_semicolon {
+                        err.span_suggestion(
+                            semicolon_span,
+                            "consider removing this semicolon",
+                            "",
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    err.emit();
                     break;
                 }
                 Ok(Some(item)) => items.extend(item),