1
Fork 0

Auto merge of #88386 - estebank:unmatched-delims, r=jackh726

Point at unclosed delimiters as part of the primary MultiSpan

Both the place where the parser encounters a needed closed delimiter and
the unclosed opening delimiter are important, so they should get the
same level of highlighting in the output.

_Context: https://twitter.com/mwk4/status/1430631546432675840_
This commit is contained in:
bors 2021-09-03 03:13:18 +00:00
commit 29d8fb746d
21 changed files with 82 additions and 67 deletions

View file

@ -1432,12 +1432,22 @@ impl<'a> Parser<'a> {
// the most sense, which is immediately after the last token: // the most sense, which is immediately after the last token:
// //
// {foo(bar {}} // {foo(bar {}}
// - ^ // ^ ^
// | | // | |
// | help: `)` may belong here // | help: `)` may belong here
// | // |
// unclosed delimiter // unclosed delimiter
if let Some(sp) = unmatched.unclosed_span { if let Some(sp) = unmatched.unclosed_span {
let mut primary_span: Vec<Span> =
err.span.primary_spans().iter().cloned().collect();
primary_span.push(sp);
let mut primary_span: MultiSpan = primary_span.into();
for span_label in err.span.span_labels() {
if let Some(label) = span_label.label {
primary_span.push_span_label(span_label.span, label);
}
}
err.set_span(primary_span);
err.span_label(sp, "unclosed delimiter"); err.span_label(sp, "unclosed delimiter");
} }
// Backticks should be removed to apply suggestions. // Backticks should be removed to apply suggestions.

View file

@ -33,7 +33,7 @@ use rustc_data_structures::sync::Lrc;
use rustc_errors::PResult; use rustc_errors::PResult;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError};
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_span::source_map::{MultiSpan, Span, DUMMY_SP};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use tracing::debug; use tracing::debug;
@ -1335,8 +1335,13 @@ crate fn make_unclosed_delims_error(
// `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to // `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to
// `unmatched_braces` only for error recovery in the `Parser`. // `unmatched_braces` only for error recovery in the `Parser`.
let found_delim = unmatched.found_delim?; let found_delim = unmatched.found_delim?;
let span: MultiSpan = if let Some(sp) = unmatched.unclosed_span {
vec![unmatched.found_span, sp].into()
} else {
unmatched.found_span.into()
};
let mut err = sess.span_diagnostic.struct_span_err( let mut err = sess.span_diagnostic.struct_span_err(
unmatched.found_span, span,
&format!( &format!(
"mismatched closing delimiter: `{}`", "mismatched closing delimiter: `{}`",
pprust::token_kind_to_string(&token::CloseDelim(found_delim)), pprust::token_kind_to_string(&token::CloseDelim(found_delim)),

View file

@ -1,8 +1,8 @@
error: mismatched closing delimiter: `)` error: mismatched closing delimiter: `)`
--> $DIR/issue-10636-1.rs:4:1 --> $DIR/issue-10636-1.rs:1:12
| |
LL | struct Obj { LL | struct Obj {
| - unclosed delimiter | ^ unclosed delimiter
... ...
LL | ) LL | )
| ^ mismatched closing delimiter | ^ mismatched closing delimiter

View file

@ -1,8 +1,8 @@
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
--> $DIR/issue-10636-2.rs:5:25 --> $DIR/issue-10636-2.rs:5:15
| |
LL | option.map(|some| 42; LL | option.map(|some| 42;
| - ^ help: `)` may belong here | ^ ^ help: `)` may belong here
| | | |
| unclosed delimiter | unclosed delimiter

View file

@ -1,8 +1,8 @@
error: expected one of `)`, `,`, or `:`, found `>` error: expected one of `)`, `,`, or `:`, found `>`
--> $DIR/issue-58856-1.rs:3:14 --> $DIR/issue-58856-1.rs:3:9
| |
LL | fn b(self> LL | fn b(self>
| - ^ help: `)` may belong here | ^ ^ help: `)` may belong here
| | | |
| unclosed delimiter | unclosed delimiter

View file

@ -1,8 +1,8 @@
error: expected one of `)` or `,`, found `->` error: expected one of `)` or `,`, found `->`
--> $DIR/issue-58856-2.rs:6:26 --> $DIR/issue-58856-2.rs:6:19
| |
LL | fn how_are_you(&self -> Empty { LL | fn how_are_you(&self -> Empty {
| - -^^ | ^ -^^
| | | | | |
| | help: `)` may belong here | | help: `)` may belong here
| unclosed delimiter | unclosed delimiter

View file

@ -17,10 +17,10 @@ LL | }
| - item list ends here | - item list ends here
error: mismatched closing delimiter: `)` error: mismatched closing delimiter: `)`
--> $DIR/issue-60075.rs:6:10 --> $DIR/issue-60075.rs:4:31
| |
LL | fn qux() -> Option<usize> { LL | fn qux() -> Option<usize> {
| - unclosed delimiter | ^ unclosed delimiter
LL | let _ = if true { LL | let _ = if true {
LL | }); LL | });
| ^ mismatched closing delimiter | ^ mismatched closing delimiter

View file

@ -21,10 +21,10 @@ LL |
| ^ | ^
error: expected one of `,` or `}`, found `{` error: expected one of `,` or `}`, found `{`
--> $DIR/issue-62973.rs:6:25 --> $DIR/issue-62973.rs:6:8
| |
LL | fn p() { match s { v, E { [) {) } LL | fn p() { match s { v, E { [) {) }
| - - -^ expected one of `,` or `}` | ^ - -^ expected one of `,` or `}`
| | | | | | | |
| | | help: `}` may belong here | | | help: `}` may belong here
| | while parsing this struct | | while parsing this struct
@ -56,18 +56,18 @@ LL |
| ^ expected one of `.`, `?`, `{`, or an operator | ^ expected one of `.`, `?`, `{`, or an operator
error: mismatched closing delimiter: `)` error: mismatched closing delimiter: `)`
--> $DIR/issue-62973.rs:6:28 --> $DIR/issue-62973.rs:6:27
| |
LL | fn p() { match s { v, E { [) {) } LL | fn p() { match s { v, E { [) {) }
| -^ mismatched closing delimiter | ^^ mismatched closing delimiter
| | | |
| unclosed delimiter | unclosed delimiter
error: mismatched closing delimiter: `)` error: mismatched closing delimiter: `)`
--> $DIR/issue-62973.rs:6:31 --> $DIR/issue-62973.rs:6:30
| |
LL | fn p() { match s { v, E { [) {) } LL | fn p() { match s { v, E { [) {) }
| -^ mismatched closing delimiter | ^^ mismatched closing delimiter
| | | |
| unclosed delimiter | unclosed delimiter

View file

@ -13,10 +13,10 @@ LL | impl W <s(f;Y(;]
| ^ expected one of 7 possible tokens | ^ expected one of 7 possible tokens
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-63116.rs:3:16 --> $DIR/issue-63116.rs:3:14
| |
LL | impl W <s(f;Y(;] LL | impl W <s(f;Y(;]
| - ^ mismatched closing delimiter | ^ ^ mismatched closing delimiter
| | | |
| unclosed delimiter | unclosed delimiter

View file

@ -5,10 +5,10 @@ LL | fn f() { |[](* }
| ^ expected one of `,` or `:` | ^ expected one of `,` or `:`
error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*`
--> $DIR/issue-66357-unexpected-unreachable.rs:12:14 --> $DIR/issue-66357-unexpected-unreachable.rs:12:13
| |
LL | fn f() { |[](* } LL | fn f() { |[](* }
| -^ help: `)` may belong here | ^^ help: `)` may belong here
| | | |
| unclosed delimiter | unclosed delimiter

View file

@ -1,107 +1,107 @@
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27
| |
LL | V = [PhantomData; { [ () ].len() ].len() as isize, LL | V = [PhantomData; { [ () ].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24
| |
LL | V = [Vec::new; { [].len() ].len() as isize, LL | V = [Vec::new; { [].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24
| |
LL | V = [Vec::new; { [0].len() ].len() as isize, LL | V = [Vec::new; { [0].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27
| |
LL | V = [PhantomData; { [ () ].len() ].len() as isize, LL | V = [PhantomData; { [ () ].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24
| |
LL | V = [Vec::new; { [].len() ].len() as isize, LL | V = [Vec::new; { [].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24
| |
LL | V = [Vec::new; { [0].len() ].len() as isize, LL | V = [Vec::new; { [0].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27
| |
LL | V = [PhantomData; { [ () ].len() ].len() as isize, LL | V = [PhantomData; { [ () ].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24
| |
LL | V = [Vec::new; { [].len() ].len() as isize, LL | V = [Vec::new; { [].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24
| |
LL | V = [Vec::new; { [0].len() ].len() as isize, LL | V = [Vec::new; { [0].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27
| |
LL | V = [PhantomData; { [ () ].len() ].len() as isize, LL | V = [PhantomData; { [ () ].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24
| |
LL | V = [Vec::new; { [].len() ].len() as isize, LL | V = [Vec::new; { [].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this
error: mismatched closing delimiter: `]` error: mismatched closing delimiter: `]`
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24
| |
LL | V = [Vec::new; { [0].len() ].len() as isize, LL | V = [Vec::new; { [0].len() ].len() as isize,
| - - ^ mismatched closing delimiter | - ^ ^ mismatched closing delimiter
| | | | | |
| | unclosed delimiter | | unclosed delimiter
| closing delimiter possibly meant for this | closing delimiter possibly meant for this

View file

@ -1,8 +1,8 @@
error: mismatched closing delimiter: `)` error: mismatched closing delimiter: `)`
--> $DIR/macro-mismatched-delim-brace-paren.rs:6:5 --> $DIR/macro-mismatched-delim-brace-paren.rs:4:10
| |
LL | foo! { LL | foo! {
| - unclosed delimiter | ^ unclosed delimiter
LL | bar, "baz", 1, 2.0 LL | bar, "baz", 1, 2.0
LL | ) LL | )
| ^ mismatched closing delimiter | ^ mismatched closing delimiter

View file

@ -10,10 +10,10 @@ LL | }
| ^ unexpected closing delimiter | ^ unexpected closing delimiter
error: mismatched closing delimiter: `}` error: mismatched closing delimiter: `}`
--> $DIR/macro-mismatched-delim-paren-brace.rs:4:5 --> $DIR/macro-mismatched-delim-paren-brace.rs:2:10
| |
LL | foo! ( LL | foo! (
| - unclosed delimiter | ^ unclosed delimiter
LL | bar, "baz", 1, 2.0 LL | bar, "baz", 1, 2.0
LL | } LL | }
| ^ mismatched closing delimiter | ^ mismatched closing delimiter

View file

@ -5,10 +5,10 @@ LL | let x = y.;
| ^ | ^
error: mismatched closing delimiter: `)` error: mismatched closing delimiter: `)`
--> $DIR/parser-recovery-2.rs:6:5 --> $DIR/parser-recovery-2.rs:4:14
| |
LL | fn bar() { LL | fn bar() {
| - unclosed delimiter | ^ unclosed delimiter
LL | let x = foo(); LL | let x = foo();
LL | ) LL | )
| ^ mismatched closing delimiter | ^ mismatched closing delimiter

View file

@ -1,10 +1,10 @@
error: mismatched closing delimiter: `}` error: mismatched closing delimiter: `}`
--> $DIR/unclosed_delim_mod.rs:7:1 --> $DIR/unclosed_delim_mod.rs:5:7
| |
LL | pub fn new() -> Result<Value, ()> { LL | pub fn new() -> Result<Value, ()> {
| - closing delimiter possibly meant for this | - closing delimiter possibly meant for this
LL | Ok(Value { LL | Ok(Value {
| - unclosed delimiter | ^ unclosed delimiter
LL | } LL | }
LL | } LL | }
| ^ mismatched closing delimiter | ^ mismatched closing delimiter

View file

@ -1,10 +1,10 @@
error: mismatched closing delimiter: `}` error: mismatched closing delimiter: `}`
--> $DIR/unclosed_delim_mod.rs:7:1 --> $DIR/unclosed_delim_mod.rs:5:7
| |
LL | pub fn new() -> Result<Value, ()> { LL | pub fn new() -> Result<Value, ()> {
| - closing delimiter possibly meant for this | - closing delimiter possibly meant for this
LL | Ok(Value { LL | Ok(Value {
| - unclosed delimiter | ^ unclosed delimiter
LL | } LL | }
LL | } LL | }
| ^ mismatched closing delimiter | ^ mismatched closing delimiter

View file

@ -8,10 +8,10 @@ LL | fn main() {}
| ^ | ^
error: expected one of `,`, `::`, `as`, or `}`, found `;` error: expected one of `,`, `::`, `as`, or `}`, found `;`
--> $DIR/use-unclosed-brace.rs:4:19 --> $DIR/use-unclosed-brace.rs:4:10
| |
LL | use foo::{bar, baz; LL | use foo::{bar, baz;
| - ^ | ^ ^
| | | | | |
| | expected one of `,`, `::`, `as`, or `}` | | expected one of `,`, `::`, `as`, or `}`
| | help: `}` may belong here | | help: `}` may belong here

View file

@ -1,8 +1,8 @@
error: mismatched closing delimiter: `)` error: mismatched closing delimiter: `)`
--> $DIR/token-error-correct-2.rs:6:5 --> $DIR/token-error-correct-2.rs:4:12
| |
LL | if foo { LL | if foo {
| - unclosed delimiter | ^ unclosed delimiter
LL | LL |
LL | ) LL | )
| ^ mismatched closing delimiter | ^ mismatched closing delimiter

View file

@ -1,8 +1,8 @@
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
--> $DIR/token-error-correct-3.rs:13:35 --> $DIR/token-error-correct-3.rs:13:21
| |
LL | callback(path.as_ref(); LL | callback(path.as_ref();
| - ^ help: `)` may belong here | ^ ^ help: `)` may belong here
| | | |
| unclosed delimiter | unclosed delimiter

View file

@ -1,8 +1,8 @@
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
--> $DIR/token-error-correct-4.rs:9:21 --> $DIR/token-error-correct-4.rs:9:12
| |
LL | setsuna(kazusa(); LL | setsuna(kazusa();
| - ^ help: `)` may belong here | ^ ^ help: `)` may belong here
| | | |
| unclosed delimiter | unclosed delimiter

View file

@ -1,10 +1,10 @@
error: mismatched closing delimiter: `}` error: mismatched closing delimiter: `}`
--> $DIR/token-error-correct.rs:6:1 --> $DIR/token-error-correct.rs:4:12
| |
LL | fn main() { LL | fn main() {
| - closing delimiter possibly meant for this | - closing delimiter possibly meant for this
LL | foo(bar(; LL | foo(bar(;
| - unclosed delimiter | ^ unclosed delimiter
LL | LL |
LL | } LL | }
| ^ mismatched closing delimiter | ^ mismatched closing delimiter