@@ -117,59 +117,8 @@ impl<'a> TokenTreesReader<'a> {
117117 // We stop at any delimiter so we can try to recover if the user
118118 // uses an incorrect delimiter.
119119 let ( tts, res) = self . parse_token_trees ( /* is_delimited */ true ) ;
120- if let Err ( mut errs) = res {
121- // If there are unclosed delims, see if there are diff markers and if so, point them
122- // out instead of complaining about the unclosed delims.
123- let mut parser = crate :: stream_to_parser ( self . string_reader . sess , tts, None ) ;
124- let mut diff_errs = vec ! [ ] ;
125- // Suggest removing a `{` we think appears in an `if`/`while` condition
126- // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition, but
127- // we have no way of tracking this in the lexer itself, so we piggyback on the parser
128- let mut in_cond = false ;
129- while parser. token != token:: Eof {
130- if let Err ( diff_err) = parser. err_diff_marker ( ) {
131- diff_errs. push ( diff_err) ;
132- } else if parser. is_keyword_ahead ( 0 , & [ kw:: If , kw:: While ] ) {
133- in_cond = true ;
134- } else if matches ! (
135- parser. token. kind,
136- token:: CloseDelim ( Delimiter :: Brace ) | token:: FatArrow
137- ) {
138- // end of the `if`/`while` body, or the end of a `match` guard
139- in_cond = false ;
140- } else if in_cond && parser. token == token:: OpenDelim ( Delimiter :: Brace ) {
141- // Store the `&&` and `let` to use their spans later when creating the diagnostic
142- let maybe_andand = parser. look_ahead ( 1 , |t| t. clone ( ) ) ;
143- let maybe_let = parser. look_ahead ( 2 , |t| t. clone ( ) ) ;
144- if maybe_andand == token:: OpenDelim ( Delimiter :: Brace ) {
145- // This might be the beginning of the `if`/`while` body (i.e., the end of the condition)
146- in_cond = false ;
147- } else if maybe_andand == token:: AndAnd && maybe_let. is_keyword ( kw:: Let ) {
148- let mut err = parser. struct_span_err (
149- parser. token . span ,
150- "found a `{` in the middle of a let-chain" ,
151- ) ;
152- err. span_suggestion (
153- parser. token . span ,
154- "consider removing this brace to parse the `let` as part of the same chain" ,
155- "" , Applicability :: MachineApplicable
156- ) ;
157- err. span_note (
158- maybe_andand. span . to ( maybe_let. span ) ,
159- "you might have meant to continue the let-chain here" ,
160- ) ;
161- errs. push ( err) ;
162- }
163- }
164- parser. bump ( ) ;
165- }
166- if !diff_errs. is_empty ( ) {
167- errs. iter_mut ( ) . for_each ( |err| {
168- err. delay_as_bug ( ) ;
169- } ) ;
170- return Err ( diff_errs) ;
171- }
172- return Err ( errs) ;
120+ if let Err ( errs) = res {
121+ return Err ( self . unclosed_delim_err ( tts, errs) ) ;
173122 }
174123
175124 // Expand to cover the entire delimited token tree
@@ -256,6 +205,62 @@ impl<'a> TokenTreesReader<'a> {
256205 Ok ( TokenTree :: Delimited ( delim_span, open_delim, tts) )
257206 }
258207
208+ fn unclosed_delim_err ( & mut self , tts : TokenStream , mut errs : Vec < PErr < ' a > > ) -> Vec < PErr < ' a > > {
209+ // If there are unclosed delims, see if there are diff markers and if so, point them
210+ // out instead of complaining about the unclosed delims.
211+ let mut parser = crate :: stream_to_parser ( self . string_reader . sess , tts, None ) ;
212+ let mut diff_errs = vec ! [ ] ;
213+ // Suggest removing a `{` we think appears in an `if`/`while` condition
214+ // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition, but
215+ // we have no way of tracking this in the lexer itself, so we piggyback on the parser
216+ let mut in_cond = false ;
217+ while parser. token != token:: Eof {
218+ if let Err ( diff_err) = parser. err_diff_marker ( ) {
219+ diff_errs. push ( diff_err) ;
220+ } else if parser. is_keyword_ahead ( 0 , & [ kw:: If , kw:: While ] ) {
221+ in_cond = true ;
222+ } else if matches ! (
223+ parser. token. kind,
224+ token:: CloseDelim ( Delimiter :: Brace ) | token:: FatArrow
225+ ) {
226+ // end of the `if`/`while` body, or the end of a `match` guard
227+ in_cond = false ;
228+ } else if in_cond && parser. token == token:: OpenDelim ( Delimiter :: Brace ) {
229+ // Store the `&&` and `let` to use their spans later when creating the diagnostic
230+ let maybe_andand = parser. look_ahead ( 1 , |t| t. clone ( ) ) ;
231+ let maybe_let = parser. look_ahead ( 2 , |t| t. clone ( ) ) ;
232+ if maybe_andand == token:: OpenDelim ( Delimiter :: Brace ) {
233+ // This might be the beginning of the `if`/`while` body (i.e., the end of the condition)
234+ in_cond = false ;
235+ } else if maybe_andand == token:: AndAnd && maybe_let. is_keyword ( kw:: Let ) {
236+ let mut err = parser. struct_span_err (
237+ parser. token . span ,
238+ "found a `{` in the middle of a let-chain" ,
239+ ) ;
240+ err. span_suggestion (
241+ parser. token . span ,
242+ "consider removing this brace to parse the `let` as part of the same chain" ,
243+ "" ,
244+ Applicability :: MachineApplicable ,
245+ ) ;
246+ err. span_label (
247+ maybe_andand. span . to ( maybe_let. span ) ,
248+ "you might have meant to continue the let-chain here" ,
249+ ) ;
250+ errs. push ( err) ;
251+ }
252+ }
253+ parser. bump ( ) ;
254+ }
255+ if !diff_errs. is_empty ( ) {
256+ errs. iter_mut ( ) . for_each ( |err| {
257+ err. delay_as_bug ( ) ;
258+ } ) ;
259+ return diff_errs;
260+ }
261+ return errs;
262+ }
263+
259264 fn close_delim_err ( & mut self , delim : Delimiter ) -> PErr < ' a > {
260265 // An unexpected closing delimiter (i.e., there is no
261266 // matching opening delimiter).
0 commit comments