Rollup merge of #70633 - kper:master, r=estebank
Confusing suggestion on incorrect closing `}` Compiler returns ``` error: unexpected closing delimiter: `}` --> main.rs:20:1 | 9 | ErrorHandled::Reported => {} | -- this block is empty, you might have not meant to close it temp ... 20 | } | ^ unexpected closing delimiter error: aborting due to previous error ```
This commit is contained in:
commit
1d3d80f773
@ -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)
|
||||
}
|
||||
|
20
src/test/ui/parser/issue-70583-block-is-empty-1.rs
Normal file
20
src/test/ui/parser/issue-70583-block-is-empty-1.rs
Normal file
@ -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: `}`
|
13
src/test/ui/parser/issue-70583-block-is-empty-1.stderr
Normal file
13
src/test/ui/parser/issue-70583-block-is-empty-1.stderr
Normal file
@ -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
|
||||
|
14
src/test/ui/parser/issue-70583-block-is-empty-2.rs
Normal file
14
src/test/ui/parser/issue-70583-block-is-empty-2.rs
Normal file
@ -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: `}`
|
11
src/test/ui/parser/issue-70583-block-is-empty-2.stderr
Normal file
11
src/test/ui/parser/issue-70583-block-is-empty-2.stderr
Normal file
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user