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