@@ -320,22 +320,7 @@ impl<'a> PathSource<'a> {
320
320
}
321
321
}
322
322
323
- struct LateResolutionVisitor < ' a , ' b > {
324
- r : & ' b mut Resolver < ' a > ,
325
-
326
- /// The module that represents the current item scope.
327
- parent_scope : ParentScope < ' a > ,
328
-
329
- /// The current set of local scopes for types and values.
330
- /// FIXME #4948: Reuse ribs to avoid allocation.
331
- ribs : PerNS < Vec < Rib < ' a > > > ,
332
-
333
- /// The current set of local scopes, for labels.
334
- label_ribs : Vec < Rib < ' a , NodeId > > ,
335
-
336
- /// The trait that the current context can refer to.
337
- current_trait_ref : Option < ( Module < ' a > , TraitRef ) > ,
338
-
323
+ struct DiagnosticMetadata {
339
324
/// The current trait's associated types' ident, used for diagnostic suggestions.
340
325
current_trait_assoc_types : Vec < Ident > ,
341
326
@@ -356,7 +341,27 @@ struct LateResolutionVisitor<'a, 'b> {
356
341
current_type_ascription : Vec < Span > ,
357
342
358
343
/// Only used for better errors on `let <pat>: <expr, not type>;`.
359
- current_let_binding : Option < ( Span , Span ) > ,
344
+ current_let_binding : Option < ( Span , Option < Span > , Option < Span > ) > ,
345
+ }
346
+
347
+ struct LateResolutionVisitor < ' a , ' b > {
348
+ r : & ' b mut Resolver < ' a > ,
349
+
350
+ /// The module that represents the current item scope.
351
+ parent_scope : ParentScope < ' a > ,
352
+
353
+ /// The current set of local scopes for types and values.
354
+ /// FIXME #4948: Reuse ribs to avoid allocation.
355
+ ribs : PerNS < Vec < Rib < ' a > > > ,
356
+
357
+ /// The current set of local scopes, for labels.
358
+ label_ribs : Vec < Rib < ' a , NodeId > > ,
359
+
360
+ /// The trait that the current context can refer to.
361
+ current_trait_ref : Option < ( Module < ' a > , TraitRef ) > ,
362
+
363
+ /// Fields used to add information to diagnostic errors.
364
+ diagnostic_metadata : DiagnosticMetadata ,
360
365
}
361
366
362
367
/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
@@ -380,18 +385,18 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
380
385
self . resolve_expr ( expr, None ) ;
381
386
}
382
387
fn visit_local ( & mut self , local : & ' tcx Local ) {
383
- debug ! ( "visit_local {:?} {:?} {:?}" , local, local . pat, local . pat . kind) ;
384
- let val = match local {
385
- Local { pat , ty : Some ( ty ) , init : None , .. } => match pat . kind {
386
- // We check for this to avoid tuple struct fields.
387
- PatKind :: Wild => None ,
388
- _ => Some ( ( pat . span , ty. span ) ) ,
389
- } ,
390
- _ => None ,
388
+ let local_spans = match local. pat . kind {
389
+ // We check for this to avoid tuple struct fields.
390
+ PatKind :: Wild => None ,
391
+ _ => Some ( (
392
+ local . pat . span ,
393
+ local . ty . as_ref ( ) . map ( |ty| ty. span ) ,
394
+ local . init . as_ref ( ) . map ( |init| init . span ) ,
395
+ ) ) ,
391
396
} ;
392
- let original = replace ( & mut self . current_let_binding , val ) ;
397
+ let original = replace ( & mut self . diagnostic_metadata . current_let_binding , local_spans ) ;
393
398
self . resolve_local ( local) ;
394
- self . current_let_binding = original;
399
+ self . diagnostic_metadata . current_let_binding = original;
395
400
}
396
401
fn visit_ty ( & mut self , ty : & ' tcx Ty ) {
397
402
match ty. kind {
@@ -433,7 +438,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
433
438
}
434
439
}
435
440
fn visit_fn ( & mut self , fn_kind : FnKind < ' tcx > , declaration : & ' tcx FnDecl , sp : Span , _: NodeId ) {
436
- let previous_value = replace ( & mut self . current_function , Some ( sp) ) ;
441
+ let previous_value = replace ( & mut self . diagnostic_metadata . current_function , Some ( sp) ) ;
437
442
debug ! ( "(resolving function) entering function" ) ;
438
443
let rib_kind = match fn_kind {
439
444
FnKind :: ItemFn ( ..) => FnItemRibKind ,
@@ -459,7 +464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
459
464
debug ! ( "(resolving function) leaving function" ) ;
460
465
} )
461
466
} ) ;
462
- self . current_function = previous_value;
467
+ self . diagnostic_metadata . current_function = previous_value;
463
468
}
464
469
465
470
fn visit_generics ( & mut self , generics : & ' tcx Generics ) {
@@ -493,7 +498,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
493
498
// (We however cannot ban `Self` for defaults on *all* generic
494
499
// lists; e.g. trait generics can usefully refer to `Self`,
495
500
// such as in the case of `trait Add<Rhs = Self>`.)
496
- if self . current_self_item . is_some ( ) { // (`Some` if + only if we are in ADT's generics.)
501
+ if self . diagnostic_metadata . current_self_item . is_some ( ) {
502
+ // (`Some` if + only if we are in ADT's generics.)
497
503
default_ban_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , Res :: Err ) ;
498
504
}
499
505
@@ -562,13 +568,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
562
568
} ,
563
569
label_ribs : Vec :: new ( ) ,
564
570
current_trait_ref : None ,
565
- current_trait_assoc_types : Vec :: new ( ) ,
566
- current_self_type : None ,
567
- current_self_item : None ,
568
- current_function : None ,
569
- unused_labels : Default :: default ( ) ,
570
- current_type_ascription : Vec :: new ( ) ,
571
- current_let_binding : None ,
571
+ diagnostic_metadata : DiagnosticMetadata {
572
+ current_trait_assoc_types : Vec :: new ( ) ,
573
+ current_self_type : None ,
574
+ current_self_item : None ,
575
+ current_function : None ,
576
+ unused_labels : Default :: default ( ) ,
577
+ current_type_ascription : Vec :: new ( ) ,
578
+ current_let_binding : None ,
579
+ }
572
580
}
573
581
}
574
582
@@ -928,16 +936,22 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
928
936
929
937
fn with_current_self_type < T > ( & mut self , self_type : & Ty , f : impl FnOnce ( & mut Self ) -> T ) -> T {
930
938
// Handle nested impls (inside fn bodies)
931
- let previous_value = replace ( & mut self . current_self_type , Some ( self_type. clone ( ) ) ) ;
939
+ let previous_value = replace (
940
+ & mut self . diagnostic_metadata . current_self_type ,
941
+ Some ( self_type. clone ( ) ) ,
942
+ ) ;
932
943
let result = f ( self ) ;
933
- self . current_self_type = previous_value;
944
+ self . diagnostic_metadata . current_self_type = previous_value;
934
945
result
935
946
}
936
947
937
948
fn with_current_self_item < T > ( & mut self , self_item : & Item , f : impl FnOnce ( & mut Self ) -> T ) -> T {
938
- let previous_value = replace ( & mut self . current_self_item , Some ( self_item. id ) ) ;
949
+ let previous_value = replace (
950
+ & mut self . diagnostic_metadata . current_self_item ,
951
+ Some ( self_item. id ) ,
952
+ ) ;
939
953
let result = f ( self ) ;
940
- self . current_self_item = previous_value;
954
+ self . diagnostic_metadata . current_self_item = previous_value;
941
955
result
942
956
}
943
957
@@ -948,14 +962,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
948
962
f : impl FnOnce ( & mut Self ) -> T ,
949
963
) -> T {
950
964
let trait_assoc_types = replace (
951
- & mut self . current_trait_assoc_types ,
965
+ & mut self . diagnostic_metadata . current_trait_assoc_types ,
952
966
trait_items. iter ( ) . filter_map ( |item| match & item. kind {
953
967
TraitItemKind :: Type ( bounds, _) if bounds. len ( ) == 0 => Some ( item. ident ) ,
954
968
_ => None ,
955
969
} ) . collect ( ) ,
956
970
) ;
957
971
let result = f ( self ) ;
958
- self . current_trait_assoc_types = trait_assoc_types;
972
+ self . diagnostic_metadata . current_trait_assoc_types = trait_assoc_types;
959
973
result
960
974
}
961
975
@@ -1782,7 +1796,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1782
1796
1783
1797
fn with_resolved_label ( & mut self , label : Option < Label > , id : NodeId , f : impl FnOnce ( & mut Self ) ) {
1784
1798
if let Some ( label) = label {
1785
- self . unused_labels . insert ( id, label. ident . span ) ;
1799
+ self . diagnostic_metadata . unused_labels . insert ( id, label. ident . span ) ;
1786
1800
self . with_label_rib ( NormalRibKind , |this| {
1787
1801
let ident = label. ident . modern_and_legacy ( ) ;
1788
1802
this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, id) ;
@@ -1886,7 +1900,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1886
1900
Some ( node_id) => {
1887
1901
// Since this res is a label, it is never read.
1888
1902
self . r . label_res_map . insert ( expr. id , node_id) ;
1889
- self . unused_labels . remove ( & node_id) ;
1903
+ self . diagnostic_metadata . unused_labels . remove ( & node_id) ;
1890
1904
}
1891
1905
}
1892
1906
@@ -1948,9 +1962,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1948
1962
}
1949
1963
}
1950
1964
ExprKind :: Type ( ref type_expr, _) => {
1951
- self . current_type_ascription . push ( type_expr. span ) ;
1965
+ self . diagnostic_metadata . current_type_ascription . push ( type_expr. span ) ;
1952
1966
visit:: walk_expr ( self , expr) ;
1953
- self . current_type_ascription . pop ( ) ;
1967
+ self . diagnostic_metadata . current_type_ascription . pop ( ) ;
1954
1968
}
1955
1969
// `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
1956
1970
// resolve the arguments within the proper scopes so that usages of them inside the
@@ -2109,7 +2123,7 @@ impl<'a> Resolver<'a> {
2109
2123
pub ( crate ) fn late_resolve_crate ( & mut self , krate : & Crate ) {
2110
2124
let mut late_resolution_visitor = LateResolutionVisitor :: new ( self ) ;
2111
2125
visit:: walk_crate ( & mut late_resolution_visitor, krate) ;
2112
- for ( id, span) in late_resolution_visitor. unused_labels . iter ( ) {
2126
+ for ( id, span) in late_resolution_visitor. diagnostic_metadata . unused_labels . iter ( ) {
2113
2127
self . session . buffer_lint ( lint:: builtin:: UNUSED_LABELS , * id, * span, "unused label" ) ;
2114
2128
}
2115
2129
}
0 commit comments