From ec3c5b0199045b3ae3959631998451543bd99518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 21:19:30 -0800 Subject: [PATCH] Use structured suggestion to surround struct literal with parenthesis --- src/librustc_resolve/lib.rs | 42 ++++++++++++++++++++++++---- src/test/ui/error-codes/E0423.stderr | 12 ++++++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 39be3cb7440..430edcafae2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3369,6 +3369,29 @@ impl<'a> Resolver<'a> { Ok(ref snippet) if snippet == "{" => true, _ => false, }; + // In case this could be a struct literal that needs to be surrounded + // by parenthesis, find the appropriate span. + let mut i = 0; + let mut closing_brace = None; + loop { + sp = sm.next_point(sp); + match sm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet == "}" { + let sp = span.to(sp); + if let Ok(snippet) = sm.span_to_snippet(sp) { + closing_brace = Some((sp, snippet)); + } + break; + } + } + _ => break, + } + i += 1; + if i > 100 { // The bigger the span the more likely we're + break; // incorrect. Bound it to 100 chars long. + } + } match source { PathSource::Expr(Some(parent)) => { match parent.node { @@ -3395,11 +3418,20 @@ impl<'a> Resolver<'a> { } }, PathSource::Expr(None) if followed_by_brace == true => { - err.span_label( - span, - format!("did you mean `({} {{ /* fields */ }})`?", - path_str), - ); + if let Some((sp, snippet)) = closing_brace { + err.span_suggestion_with_applicability( + sp, + "surround the struct literal with parenthesis", + format!("({})", snippet), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label( + span, + format!("did you mean `({} {{ /* fields */ }})`?", + path_str), + ); + } return (err, candidates); }, _ => { diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index df9ed631a1c..3f3c78c68d0 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -29,19 +29,25 @@ error[E0423]: expected value, found struct `S` --> $DIR/E0423.rs:12:32 | LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } - | ^ did you mean `(S { /* fields */ })`? + | ^--------------- + | | + | help: surround the struct literal with parenthesis: `(S { x: 1, y: 2 })` error[E0423]: expected value, found struct `T` --> $DIR/E0423.rs:15:8 | LL | if T {} == T {} { println!("Ok"); } - | ^ did you mean `(T { /* fields */ })`? + | ^--- + | | + | help: surround the struct literal with parenthesis: `(T {})` error[E0423]: expected value, found struct `std::ops::Range` --> $DIR/E0423.rs:21:14 | LL | for _ in std::ops::Range { start: 0, end: 10 } {} - | ^^^^^^^^^^^^^^^ did you mean `(std::ops::Range { /* fields */ })`? + | ^^^^^^^^^^^^^^^---------------------- + | | + | help: surround the struct literal with parenthesis: `(std::ops::Range { start: 0, end: 10 })` error: aborting due to 7 previous errors