@@ -316,22 +316,8 @@ impl<'a> PathSource<'a> {
316
316
}
317
317
}
318
318
319
- struct LateResolutionVisitor < ' a , ' b > {
320
- r : & ' b mut Resolver < ' a > ,
321
-
322
- /// The module that represents the current item scope.
323
- parent_scope : ParentScope < ' a > ,
324
-
325
- /// The current set of local scopes for types and values.
326
- /// FIXME #4948: Reuse ribs to avoid allocation.
327
- ribs : PerNS < Vec < Rib < ' a > > > ,
328
-
329
- /// The current set of local scopes, for labels.
330
- label_ribs : Vec < Rib < ' a , NodeId > > ,
331
-
332
- /// The trait that the current context can refer to.
333
- current_trait_ref : Option < ( Module < ' a > , TraitRef ) > ,
334
-
319
+ #[ derive( Default ) ]
320
+ struct DiagnosticMetadata {
335
321
/// The current trait's associated types' ident, used for diagnostic suggestions.
336
322
current_trait_assoc_types : Vec < Ident > ,
337
323
@@ -350,6 +336,29 @@ struct LateResolutionVisitor<'a, 'b> {
350
336
351
337
/// Only used for better errors on `fn(): fn()`.
352
338
current_type_ascription : Vec < Span > ,
339
+
340
+ /// Only used for better errors on `let <pat>: <expr, not type>;`.
341
+ current_let_binding : Option < ( Span , Option < Span > , Option < Span > ) > ,
342
+ }
343
+
344
+ struct LateResolutionVisitor < ' a , ' b > {
345
+ r : & ' b mut Resolver < ' a > ,
346
+
347
+ /// The module that represents the current item scope.
348
+ parent_scope : ParentScope < ' a > ,
349
+
350
+ /// The current set of local scopes for types and values.
351
+ /// FIXME #4948: Reuse ribs to avoid allocation.
352
+ ribs : PerNS < Vec < Rib < ' a > > > ,
353
+
354
+ /// The current set of local scopes, for labels.
355
+ label_ribs : Vec < Rib < ' a , NodeId > > ,
356
+
357
+ /// The trait that the current context can refer to.
358
+ current_trait_ref : Option < ( Module < ' a > , TraitRef ) > ,
359
+
360
+ /// Fields used to add information to diagnostic errors.
361
+ diagnostic_metadata : DiagnosticMetadata ,
353
362
}
354
363
355
364
/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
@@ -373,7 +382,18 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
373
382
self . resolve_expr ( expr, None ) ;
374
383
}
375
384
fn visit_local ( & mut self , local : & ' tcx Local ) {
385
+ let local_spans = match local. pat . kind {
386
+ // We check for this to avoid tuple struct fields.
387
+ PatKind :: Wild => None ,
388
+ _ => Some ( (
389
+ local. pat . span ,
390
+ local. ty . as_ref ( ) . map ( |ty| ty. span ) ,
391
+ local. init . as_ref ( ) . map ( |init| init. span ) ,
392
+ ) ) ,
393
+ } ;
394
+ let original = replace ( & mut self . diagnostic_metadata . current_let_binding , local_spans) ;
376
395
self . resolve_local ( local) ;
396
+ self . diagnostic_metadata . current_let_binding = original;
377
397
}
378
398
fn visit_ty ( & mut self , ty : & ' tcx Ty ) {
379
399
match ty. kind {
@@ -415,7 +435,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
415
435
}
416
436
}
417
437
fn visit_fn ( & mut self , fn_kind : FnKind < ' tcx > , declaration : & ' tcx FnDecl , sp : Span , _: NodeId ) {
418
- let previous_value = replace ( & mut self . current_function , Some ( sp) ) ;
438
+ let previous_value = replace ( & mut self . diagnostic_metadata . current_function , Some ( sp) ) ;
419
439
debug ! ( "(resolving function) entering function" ) ;
420
440
let rib_kind = match fn_kind {
421
441
FnKind :: ItemFn ( ..) => FnItemRibKind ,
@@ -441,7 +461,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
441
461
debug ! ( "(resolving function) leaving function" ) ;
442
462
} )
443
463
} ) ;
444
- self . current_function = previous_value;
464
+ self . diagnostic_metadata . current_function = previous_value;
445
465
}
446
466
447
467
fn visit_generics ( & mut self , generics : & ' tcx Generics ) {
@@ -475,7 +495,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
475
495
// (We however cannot ban `Self` for defaults on *all* generic
476
496
// lists; e.g. trait generics can usefully refer to `Self`,
477
497
// such as in the case of `trait Add<Rhs = Self>`.)
478
- if self . current_self_item . is_some ( ) { // (`Some` if + only if we are in ADT's generics.)
498
+ if self . diagnostic_metadata . current_self_item . is_some ( ) {
499
+ // (`Some` if + only if we are in ADT's generics.)
479
500
default_ban_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , Res :: Err ) ;
480
501
}
481
502
@@ -527,12 +548,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
527
548
} ,
528
549
label_ribs : Vec :: new ( ) ,
529
550
current_trait_ref : None ,
530
- current_trait_assoc_types : Vec :: new ( ) ,
531
- current_self_type : None ,
532
- current_self_item : None ,
533
- current_function : None ,
534
- unused_labels : Default :: default ( ) ,
535
- current_type_ascription : Vec :: new ( ) ,
551
+ diagnostic_metadata : DiagnosticMetadata :: default ( ) ,
536
552
}
537
553
}
538
554
@@ -892,16 +908,22 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
892
908
893
909
fn with_current_self_type < T > ( & mut self , self_type : & Ty , f : impl FnOnce ( & mut Self ) -> T ) -> T {
894
910
// Handle nested impls (inside fn bodies)
895
- let previous_value = replace ( & mut self . current_self_type , Some ( self_type. clone ( ) ) ) ;
911
+ let previous_value = replace (
912
+ & mut self . diagnostic_metadata . current_self_type ,
913
+ Some ( self_type. clone ( ) ) ,
914
+ ) ;
896
915
let result = f ( self ) ;
897
- self . current_self_type = previous_value;
916
+ self . diagnostic_metadata . current_self_type = previous_value;
898
917
result
899
918
}
900
919
901
920
fn with_current_self_item < T > ( & mut self , self_item : & Item , f : impl FnOnce ( & mut Self ) -> T ) -> T {
902
- let previous_value = replace ( & mut self . current_self_item , Some ( self_item. id ) ) ;
921
+ let previous_value = replace (
922
+ & mut self . diagnostic_metadata . current_self_item ,
923
+ Some ( self_item. id ) ,
924
+ ) ;
903
925
let result = f ( self ) ;
904
- self . current_self_item = previous_value;
926
+ self . diagnostic_metadata . current_self_item = previous_value;
905
927
result
906
928
}
907
929
@@ -912,14 +934,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
912
934
f : impl FnOnce ( & mut Self ) -> T ,
913
935
) -> T {
914
936
let trait_assoc_types = replace (
915
- & mut self . current_trait_assoc_types ,
937
+ & mut self . diagnostic_metadata . current_trait_assoc_types ,
916
938
trait_items. iter ( ) . filter_map ( |item| match & item. kind {
917
939
TraitItemKind :: Type ( bounds, _) if bounds. len ( ) == 0 => Some ( item. ident ) ,
918
940
_ => None ,
919
941
} ) . collect ( ) ,
920
942
) ;
921
943
let result = f ( self ) ;
922
- self . current_trait_assoc_types = trait_assoc_types;
944
+ self . diagnostic_metadata . current_trait_assoc_types = trait_assoc_types;
923
945
result
924
946
}
925
947
@@ -1746,7 +1768,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1746
1768
1747
1769
fn with_resolved_label ( & mut self , label : Option < Label > , id : NodeId , f : impl FnOnce ( & mut Self ) ) {
1748
1770
if let Some ( label) = label {
1749
- self . unused_labels . insert ( id, label. ident . span ) ;
1771
+ self . diagnostic_metadata . unused_labels . insert ( id, label. ident . span ) ;
1750
1772
self . with_label_rib ( NormalRibKind , |this| {
1751
1773
let ident = label. ident . modern_and_legacy ( ) ;
1752
1774
this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, id) ;
@@ -1850,7 +1872,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1850
1872
Some ( node_id) => {
1851
1873
// Since this res is a label, it is never read.
1852
1874
self . r . label_res_map . insert ( expr. id , node_id) ;
1853
- self . unused_labels . remove ( & node_id) ;
1875
+ self . diagnostic_metadata . unused_labels . remove ( & node_id) ;
1854
1876
}
1855
1877
}
1856
1878
@@ -1912,9 +1934,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1912
1934
}
1913
1935
}
1914
1936
ExprKind :: Type ( ref type_expr, _) => {
1915
- self . current_type_ascription . push ( type_expr. span ) ;
1937
+ self . diagnostic_metadata . current_type_ascription . push ( type_expr. span ) ;
1916
1938
visit:: walk_expr ( self , expr) ;
1917
- self . current_type_ascription . pop ( ) ;
1939
+ self . diagnostic_metadata . current_type_ascription . pop ( ) ;
1918
1940
}
1919
1941
// `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
1920
1942
// resolve the arguments within the proper scopes so that usages of them inside the
@@ -2073,7 +2095,7 @@ impl<'a> Resolver<'a> {
2073
2095
pub ( crate ) fn late_resolve_crate ( & mut self , krate : & Crate ) {
2074
2096
let mut late_resolution_visitor = LateResolutionVisitor :: new ( self ) ;
2075
2097
visit:: walk_crate ( & mut late_resolution_visitor, krate) ;
2076
- for ( id, span) in late_resolution_visitor. unused_labels . iter ( ) {
2098
+ for ( id, span) in late_resolution_visitor. diagnostic_metadata . unused_labels . iter ( ) {
2077
2099
self . session . buffer_lint ( lint:: builtin:: UNUSED_LABELS , * id, * span, "unused label" ) ;
2078
2100
}
2079
2101
}
0 commit comments