about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_parse/lexer/tokentrees.rs41
-rw-r--r--src/test/ui/parser/issue-70583-block-is-empty-1.rs20
-rw-r--r--src/test/ui/parser/issue-70583-block-is-empty-1.stderr13
-rw-r--r--src/test/ui/parser/issue-70583-block-is-empty-2.rs14
-rw-r--r--src/test/ui/parser/issue-70583-block-is-empty-2.stderr11
-rw-r--r--src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr5
-rw-r--r--src/test/ui/parser/mismatched-delim-brace-empty-block.stderr6
7 files changed, 104 insertions, 6 deletions
diff --git a/src/librustc_parse/lexer/tokentrees.rs b/src/librustc_parse/lexer/tokentrees.rs
index b65b8941728..c08659ec9f6 100644
--- a/src/librustc_parse/lexer/tokentrees.rs
+++ b/src/librustc_parse/lexer/tokentrees.rs
@@ -1,6 +1,6 @@
 use super::{StringReader, UnmatchedBrace};
 
-use rustc_ast::token::{self, Token};
+use rustc_ast::token::{self, DelimToken, Token};
 use rustc_ast::tokenstream::{
     DelimSpan,
     IsJoint::{self, *},
@@ -22,6 +22,7 @@ impl<'a> StringReader<'a> {
             matching_delim_spans: Vec::new(),
             last_unclosed_found_span: None,
             last_delim_empty_block_spans: FxHashMap::default(),
+            matching_block_spans: Vec::new(),
         };
         let res = tt_reader.parse_all_token_trees();
         (res, tt_reader.unmatched_braces)
@@ -42,6 +43,9 @@ struct TokenTreesReader<'a> {
     last_unclosed_found_span: Option<Span>,
     /// Collect empty block spans that might have been auto-inserted by editors.
     last_delim_empty_block_spans: FxHashMap<token::DelimToken, Span>,
+    /// Collect the spans of braces (Open, Close). Used only
+    /// for detecting if blocks are empty and only braces.
+    matching_block_spans: Vec<(Span, Span)>,
 }
 
 impl<'a> TokenTreesReader<'a> {
@@ -77,6 +81,7 @@ impl<'a> TokenTreesReader<'a> {
 
     fn parse_token_tree(&mut self) -> PResult<'a, TreeAndJoint> {
         let sm = self.string_reader.sess.source_map();
+
         match self.token.kind {
             token::Eof => {
                 let msg = "this file contains an unclosed delimiter";
@@ -146,6 +151,14 @@ impl<'a> TokenTreesReader<'a> {
                             }
                         }
 
+                        match (open_brace, delim) {
+                            //only add braces
+                            (DelimToken::Brace, DelimToken::Brace) => {
+                                self.matching_block_spans.push((open_brace_span, close_brace_span));
+                            }
+                            _ => {}
+                        }
+
                         if self.open_braces.is_empty() {
                             // Clear up these spans to avoid suggesting them as we've found
                             // properly matched delimiters so far for an entire block.
@@ -164,6 +177,7 @@ impl<'a> TokenTreesReader<'a> {
                     token::CloseDelim(other) => {
                         let mut unclosed_delimiter = None;
                         let mut candidate = None;
+
                         if self.last_unclosed_found_span != Some(self.token.span) {
                             // do not complain about the same unclosed delimiter multiple times
                             self.last_unclosed_found_span = Some(self.token.span);
@@ -224,12 +238,27 @@ impl<'a> TokenTreesReader<'a> {
                 let mut err =
                     self.string_reader.sess.span_diagnostic.struct_span_err(self.token.span, &msg);
 
-                if let Some(span) = self.last_delim_empty_block_spans.remove(&delim) {
-                    err.span_label(
-                        span,
-                        "this block is empty, you might have not meant to close it",
-                    );
+                // Braces are added at the end, so the last element is the biggest block
+                if let Some(parent) = self.matching_block_spans.last() {
+                    if let Some(span) = self.last_delim_empty_block_spans.remove(&delim) {
+                        // Check if the (empty block) is in the last properly closed block
+                        if (parent.0.to(parent.1)).contains(span) {
+                            err.span_label(
+                                span,
+                                "block is empty, you might have not meant to close it",
+                            );
+                        } else {
+                            err.span_label(parent.0, "this opening brace...");
+
+                            err.span_label(parent.1, "...matches this closing brace");
+                        }
+                    } else {
+                        err.span_label(parent.0, "this opening brace...");
+
+                        err.span_label(parent.1, "...matches this closing brace");
+                    }
                 }
+
                 err.span_label(self.token.span, "unexpected closing delimiter");
                 Err(err)
             }
diff --git a/src/test/ui/parser/issue-70583-block-is-empty-1.rs b/src/test/ui/parser/issue-70583-block-is-empty-1.rs
new file mode 100644
index 00000000000..f560f68f613
--- /dev/null
+++ b/src/test/ui/parser/issue-70583-block-is-empty-1.rs
@@ -0,0 +1,20 @@
+pub enum ErrorHandled {
+    Reported,
+    TooGeneric,
+}
+
+impl ErrorHandled {
+    pub fn assert_reported(self) {
+        match self {
+            ErrorHandled::Reported => {}
+            ErrorHandled::TooGeneric => panic!(),
+        }
+    }
+}
+
+fn struct_generic(x: Vec<i32>) {
+    for v in x {
+        println!("{}", v);
+    }
+    }
+} //~ ERROR unexpected closing delimiter: `}`
diff --git a/src/test/ui/parser/issue-70583-block-is-empty-1.stderr b/src/test/ui/parser/issue-70583-block-is-empty-1.stderr
new file mode 100644
index 00000000000..39bf113ef83
--- /dev/null
+++ b/src/test/ui/parser/issue-70583-block-is-empty-1.stderr
@@ -0,0 +1,13 @@
+error: unexpected closing delimiter: `}`
+  --> $DIR/issue-70583-block-is-empty-1.rs:20:1
+   |
+LL | fn struct_generic(x: Vec<i32>) {
+   |                                - this opening brace...
+...
+LL |     }
+   |     - ...matches this closing brace
+LL | }
+   | ^ unexpected closing delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-70583-block-is-empty-2.rs b/src/test/ui/parser/issue-70583-block-is-empty-2.rs
new file mode 100644
index 00000000000..80f53338a68
--- /dev/null
+++ b/src/test/ui/parser/issue-70583-block-is-empty-2.rs
@@ -0,0 +1,14 @@
+pub enum ErrorHandled {
+    Reported,
+    TooGeneric,
+}
+
+impl ErrorHandled {
+    pub fn assert_reported(self) {
+        match self {
+            ErrorHandled::Reported => {}}
+                                     //^~ ERROR block is empty, you might have not meant to close it
+            ErrorHandled::TooGeneric => panic!(),
+        }
+    }
+} //~ ERROR unexpected closing delimiter: `}`
diff --git a/src/test/ui/parser/issue-70583-block-is-empty-2.stderr b/src/test/ui/parser/issue-70583-block-is-empty-2.stderr
new file mode 100644
index 00000000000..5d37b216427
--- /dev/null
+++ b/src/test/ui/parser/issue-70583-block-is-empty-2.stderr
@@ -0,0 +1,11 @@
+error: unexpected closing delimiter: `}`
+  --> $DIR/issue-70583-block-is-empty-2.rs:14:1
+   |
+LL |             ErrorHandled::Reported => {}}
+   |                                       -- block is empty, you might have not meant to close it
+...
+LL | }
+   | ^ unexpected closing delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr b/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr
index 042142ac350..424c7a60c19 100644
--- a/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr
+++ b/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr
@@ -1,6 +1,11 @@
 error: unexpected closing delimiter: `}`
   --> $DIR/macro-mismatched-delim-paren-brace.rs:5:1
    |
+LL | fn main() {
+   |           - this opening brace...
+...
+LL |     }
+   |     - ...matches this closing brace
 LL | }
    | ^ unexpected closing delimiter
 
diff --git a/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr b/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr
index f1be5dc5ba7..c871e549c9e 100644
--- a/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr
+++ b/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr
@@ -1,6 +1,12 @@
 error: unexpected closing delimiter: `}`
   --> $DIR/mismatched-delim-brace-empty-block.rs:5:1
    |
+LL | fn main() {
+   |           - this opening brace...
+LL | 
+LL | }
+   | - ...matches this closing brace
+LL |     let _ = ();
 LL | }
    | ^ unexpected closing delimiter