@@ -316,22 +316,7 @@ 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
+ struct DiagnosticMetadata {
335
320
/// The current trait's associated types' ident, used for diagnostic suggestions.
336
321
current_trait_assoc_types : Vec < Ident > ,
337
322
@@ -352,7 +337,27 @@ struct LateResolutionVisitor<'a, 'b> {
352
337
current_type_ascription : Vec < Span > ,
353
338
354
339
/// Only used for better errors on `let <pat>: <expr, not type>;`.
355
- current_let_binding : Option < ( Span , Span ) > ,
340
+ current_let_binding : Option < ( Span , Option < Span > , Option < Span > ) > ,
341
+ }
342
+
343
+ struct LateResolutionVisitor < ' a , ' b > {
344
+ r : & ' b mut Resolver < ' a > ,
345
+
346
+ /// The module that represents the current item scope.
347
+ parent_scope : ParentScope < ' a > ,
348
+
349
+ /// The current set of local scopes for types and values.
350
+ /// FIXME #4948: Reuse ribs to avoid allocation.
351
+ ribs : PerNS < Vec < Rib < ' a > > > ,
352
+
353
+ /// The current set of local scopes, for labels.
354
+ label_ribs : Vec < Rib < ' a , NodeId > > ,
355
+
356
+ /// The trait that the current context can refer to.
357
+ current_trait_ref : Option < ( Module < ' a > , TraitRef ) > ,
358
+
359
+ /// Fields used to add information to diagnostic errors.
360
+ diagnostic_metadata : DiagnosticMetadata ,
356
361
}
357
362
358
363
/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
@@ -376,18 +381,18 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
376
381
self . resolve_expr ( expr, None ) ;
377
382
}
378
383
fn visit_local ( & mut self , local : & ' tcx Local ) {
379
- debug ! ( "visit_local {:?} {:?} {:?}" , local, local . pat, local . pat . kind) ;
380
- let val = match local {
381
- Local { pat , ty : Some ( ty ) , init : None , .. } => match pat . kind {
382
- // We check for this to avoid tuple struct fields.
383
- PatKind :: Wild => None ,
384
- _ => Some ( ( pat . span , ty. span ) ) ,
385
- } ,
386
- _ => None ,
384
+ let local_spans = match local. pat . kind {
385
+ // We check for this to avoid tuple struct fields.
386
+ PatKind :: Wild => None ,
387
+ _ => Some ( (
388
+ local . pat . span ,
389
+ local . ty . as_ref ( ) . map ( |ty| ty. span ) ,
390
+ local . init . as_ref ( ) . map ( |init| init . span ) ,
391
+ ) ) ,
387
392
} ;
388
- let original = replace ( & mut self . current_let_binding , val ) ;
393
+ let original = replace ( & mut self . diagnostic_metadata . current_let_binding , local_spans ) ;
389
394
self . resolve_local ( local) ;
390
- self . current_let_binding = original;
395
+ self . diagnostic_metadata . current_let_binding = original;
391
396
}
392
397
fn visit_ty ( & mut self , ty : & ' tcx Ty ) {
393
398
match ty. kind {
@@ -429,7 +434,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
429
434
}
430
435
}
431
436
fn visit_fn ( & mut self , fn_kind : FnKind < ' tcx > , declaration : & ' tcx FnDecl , sp : Span , _: NodeId ) {
432
- let previous_value = replace ( & mut self . current_function , Some ( sp) ) ;
437
+ let previous_value = replace ( & mut self . diagnostic_metadata . current_function , Some ( sp) ) ;
433
438
debug ! ( "(resolving function) entering function" ) ;
434
439
let rib_kind = match fn_kind {
435
440
FnKind :: ItemFn ( ..) => FnItemRibKind ,
@@ -455,7 +460,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
455
460
debug ! ( "(resolving function) leaving function" ) ;
456
461
} )
457
462
} ) ;
458
- self . current_function = previous_value;
463
+ self . diagnostic_metadata . current_function = previous_value;
459
464
}
460
465
461
466
fn visit_generics ( & mut self , generics : & ' tcx Generics ) {
@@ -489,7 +494,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
489
494
// (We however cannot ban `Self` for defaults on *all* generic
490
495
// lists; e.g. trait generics can usefully refer to `Self`,
491
496
// such as in the case of `trait Add<Rhs = Self>`.)
492
- if self . current_self_item . is_some ( ) { // (`Some` if + only if we are in ADT's generics.)
497
+ if self . diagnostic_metadata . current_self_item . is_some ( ) {
498
+ // (`Some` if + only if we are in ADT's generics.)
493
499
default_ban_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , Res :: Err ) ;
494
500
}
495
501
@@ -541,13 +547,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
541
547
} ,
542
548
label_ribs : Vec :: new ( ) ,
543
549
current_trait_ref : None ,
544
- current_trait_assoc_types : Vec :: new ( ) ,
545
- current_self_type : None ,
546
- current_self_item : None ,
547
- current_function : None ,
548
- unused_labels : Default :: default ( ) ,
549
- current_type_ascription : Vec :: new ( ) ,
550
- current_let_binding : None ,
550
+ diagnostic_metadata : DiagnosticMetadata {
551
+ current_trait_assoc_types : Vec :: new ( ) ,
552
+ current_self_type : None ,
553
+ current_self_item : None ,
554
+ current_function : None ,
555
+ unused_labels : Default :: default ( ) ,
556
+ current_type_ascription : Vec :: new ( ) ,
557
+ current_let_binding : None ,
558
+ }
551
559
}
552
560
}
553
561
@@ -907,16 +915,22 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
907
915
908
916
fn with_current_self_type < T > ( & mut self , self_type : & Ty , f : impl FnOnce ( & mut Self ) -> T ) -> T {
909
917
// Handle nested impls (inside fn bodies)
910
- let previous_value = replace ( & mut self . current_self_type , Some ( self_type. clone ( ) ) ) ;
918
+ let previous_value = replace (
919
+ & mut self . diagnostic_metadata . current_self_type ,
920
+ Some ( self_type. clone ( ) ) ,
921
+ ) ;
911
922
let result = f ( self ) ;
912
- self . current_self_type = previous_value;
923
+ self . diagnostic_metadata . current_self_type = previous_value;
913
924
result
914
925
}
915
926
916
927
fn with_current_self_item < T > ( & mut self , self_item : & Item , f : impl FnOnce ( & mut Self ) -> T ) -> T {
917
- let previous_value = replace ( & mut self . current_self_item , Some ( self_item. id ) ) ;
928
+ let previous_value = replace (
929
+ & mut self . diagnostic_metadata . current_self_item ,
930
+ Some ( self_item. id ) ,
931
+ ) ;
918
932
let result = f ( self ) ;
919
- self . current_self_item = previous_value;
933
+ self . diagnostic_metadata . current_self_item = previous_value;
920
934
result
921
935
}
922
936
@@ -927,14 +941,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
927
941
f : impl FnOnce ( & mut Self ) -> T ,
928
942
) -> T {
929
943
let trait_assoc_types = replace (
930
- & mut self . current_trait_assoc_types ,
944
+ & mut self . diagnostic_metadata . current_trait_assoc_types ,
931
945
trait_items. iter ( ) . filter_map ( |item| match & item. kind {
932
946
TraitItemKind :: Type ( bounds, _) if bounds. len ( ) == 0 => Some ( item. ident ) ,
933
947
_ => None ,
934
948
} ) . collect ( ) ,
935
949
) ;
936
950
let result = f ( self ) ;
937
- self . current_trait_assoc_types = trait_assoc_types;
951
+ self . diagnostic_metadata . current_trait_assoc_types = trait_assoc_types;
938
952
result
939
953
}
940
954
@@ -1761,7 +1775,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1761
1775
1762
1776
fn with_resolved_label ( & mut self , label : Option < Label > , id : NodeId , f : impl FnOnce ( & mut Self ) ) {
1763
1777
if let Some ( label) = label {
1764
- self . unused_labels . insert ( id, label. ident . span ) ;
1778
+ self . diagnostic_metadata . unused_labels . insert ( id, label. ident . span ) ;
1765
1779
self . with_label_rib ( NormalRibKind , |this| {
1766
1780
let ident = label. ident . modern_and_legacy ( ) ;
1767
1781
this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, id) ;
@@ -1865,7 +1879,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1865
1879
Some ( node_id) => {
1866
1880
// Since this res is a label, it is never read.
1867
1881
self . r . label_res_map . insert ( expr. id , node_id) ;
1868
- self . unused_labels . remove ( & node_id) ;
1882
+ self . diagnostic_metadata . unused_labels . remove ( & node_id) ;
1869
1883
}
1870
1884
}
1871
1885
@@ -1927,9 +1941,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1927
1941
}
1928
1942
}
1929
1943
ExprKind :: Type ( ref type_expr, _) => {
1930
- self . current_type_ascription . push ( type_expr. span ) ;
1944
+ self . diagnostic_metadata . current_type_ascription . push ( type_expr. span ) ;
1931
1945
visit:: walk_expr ( self , expr) ;
1932
- self . current_type_ascription . pop ( ) ;
1946
+ self . diagnostic_metadata . current_type_ascription . pop ( ) ;
1933
1947
}
1934
1948
// `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
1935
1949
// resolve the arguments within the proper scopes so that usages of them inside the
@@ -2088,7 +2102,7 @@ impl<'a> Resolver<'a> {
2088
2102
pub ( crate ) fn late_resolve_crate ( & mut self , krate : & Crate ) {
2089
2103
let mut late_resolution_visitor = LateResolutionVisitor :: new ( self ) ;
2090
2104
visit:: walk_crate ( & mut late_resolution_visitor, krate) ;
2091
- for ( id, span) in late_resolution_visitor. unused_labels . iter ( ) {
2105
+ for ( id, span) in late_resolution_visitor. diagnostic_metadata . unused_labels . iter ( ) {
2092
2106
self . session . buffer_lint ( lint:: builtin:: UNUSED_LABELS , * id, * span, "unused label" ) ;
2093
2107
}
2094
2108
}
0 commit comments