@@ -240,6 +240,56 @@ impl<'a> Resolver<'a> {
240
240
( err, candidates)
241
241
}
242
242
243
+ fn followed_by_brace ( & self , span : Span ) -> ( bool , Option < ( Span , String ) > ) {
244
+ // HACK(estebank): find a better way to figure out that this was a
245
+ // parser issue where a struct literal is being used on an expression
246
+ // where a brace being opened means a block is being started. Look
247
+ // ahead for the next text to see if `span` is followed by a `{`.
248
+ let sm = self . session . source_map ( ) ;
249
+ let mut sp = span;
250
+ loop {
251
+ sp = sm. next_point ( sp) ;
252
+ match sm. span_to_snippet ( sp) {
253
+ Ok ( ref snippet) => {
254
+ if snippet. chars ( ) . any ( |c| { !c. is_whitespace ( ) } ) {
255
+ break ;
256
+ }
257
+ }
258
+ _ => break ,
259
+ }
260
+ }
261
+ let followed_by_brace = match sm. span_to_snippet ( sp) {
262
+ Ok ( ref snippet) if snippet == "{" => true ,
263
+ _ => false ,
264
+ } ;
265
+ // In case this could be a struct literal that needs to be surrounded
266
+ // by parenthesis, find the appropriate span.
267
+ let mut i = 0 ;
268
+ let mut closing_brace = None ;
269
+ loop {
270
+ sp = sm. next_point ( sp) ;
271
+ match sm. span_to_snippet ( sp) {
272
+ Ok ( ref snippet) => {
273
+ if snippet == "}" {
274
+ let sp = span. to ( sp) ;
275
+ if let Ok ( snippet) = sm. span_to_snippet ( sp) {
276
+ closing_brace = Some ( ( sp, snippet) ) ;
277
+ }
278
+ break ;
279
+ }
280
+ }
281
+ _ => break ,
282
+ }
283
+ i += 1 ;
284
+ // The bigger the span, the more likely we're incorrect --
285
+ // bound it to 100 chars long.
286
+ if i > 100 {
287
+ break ;
288
+ }
289
+ }
290
+ return ( followed_by_brace, closing_brace)
291
+ }
292
+
243
293
/// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment`
244
294
/// function.
245
295
/// Returns `true` if able to provide context-dependent help.
@@ -278,6 +328,8 @@ impl<'a> Resolver<'a> {
278
328
_ => false ,
279
329
} ;
280
330
331
+ let ( followed_by_brace, closing_brace) = self . followed_by_brace ( span) ;
332
+
281
333
match ( def, source) {
282
334
( Def :: Macro ( ..) , _) => {
283
335
err. span_suggestion (
@@ -331,52 +383,6 @@ impl<'a> Resolver<'a> {
331
383
) ;
332
384
}
333
385
} else {
334
- // HACK(estebank): find a better way to figure out that this was a
335
- // parser issue where a struct literal is being used on an expression
336
- // where a brace being opened means a block is being started. Look
337
- // ahead for the next text to see if `span` is followed by a `{`.
338
- let sm = self . session . source_map ( ) ;
339
- let mut sp = span;
340
- loop {
341
- sp = sm. next_point ( sp) ;
342
- match sm. span_to_snippet ( sp) {
343
- Ok ( ref snippet) => {
344
- if snippet. chars ( ) . any ( |c| { !c. is_whitespace ( ) } ) {
345
- break ;
346
- }
347
- }
348
- _ => break ,
349
- }
350
- }
351
- let followed_by_brace = match sm. span_to_snippet ( sp) {
352
- Ok ( ref snippet) if snippet == "{" => true ,
353
- _ => false ,
354
- } ;
355
- // In case this could be a struct literal that needs to be surrounded
356
- // by parenthesis, find the appropriate span.
357
- let mut i = 0 ;
358
- let mut closing_brace = None ;
359
- loop {
360
- sp = sm. next_point ( sp) ;
361
- match sm. span_to_snippet ( sp) {
362
- Ok ( ref snippet) => {
363
- if snippet == "}" {
364
- let sp = span. to ( sp) ;
365
- if let Ok ( snippet) = sm. span_to_snippet ( sp) {
366
- closing_brace = Some ( ( sp, snippet) ) ;
367
- }
368
- break ;
369
- }
370
- }
371
- _ => break ,
372
- }
373
- i += 1 ;
374
- // The bigger the span, the more likely we're incorrect --
375
- // bound it to 100 chars long.
376
- if i > 100 {
377
- break ;
378
- }
379
- }
380
386
match source {
381
387
PathSource :: Expr ( Some ( parent) ) => if !path_sep ( err, & parent) {
382
388
err. span_label (
@@ -411,7 +417,35 @@ impl<'a> Resolver<'a> {
411
417
( Def :: Union ( ..) , _) |
412
418
( Def :: Variant ( ..) , _) |
413
419
( Def :: Ctor ( _, _, CtorKind :: Fictive ) , _) if ns == ValueNS => {
414
- err. span_label ( span, format ! ( "did you mean `{} {{ /* fields */ }}`?" , path_str) ) ;
420
+ match source {
421
+ PathSource :: Expr ( Some ( parent) ) => if !path_sep ( err, & parent) {
422
+ err. span_label (
423
+ span,
424
+ format ! ( "did you mean `{} {{ /* fields */ }}`?" , path_str) ,
425
+ ) ;
426
+ }
427
+ PathSource :: Expr ( None ) if followed_by_brace == true => {
428
+ if let Some ( ( sp, snippet) ) = closing_brace {
429
+ err. span_suggestion (
430
+ sp,
431
+ "surround the struct literal with parenthesis" ,
432
+ format ! ( "({})" , snippet) ,
433
+ Applicability :: MaybeIncorrect ,
434
+ ) ;
435
+ } else {
436
+ err. span_label (
437
+ span,
438
+ format ! ( "did you mean `({} {{ /* fields */ }})`?" , path_str) ,
439
+ ) ;
440
+ }
441
+ } ,
442
+ _ => {
443
+ err. span_label (
444
+ span,
445
+ format ! ( "did you mean `{} {{ /* fields */ }}`?" , path_str) ,
446
+ ) ;
447
+ } ,
448
+ }
415
449
}
416
450
( Def :: SelfTy ( ..) , _) if ns == ValueNS => {
417
451
err. span_label ( span, fallback_label) ;
0 commit comments