@@ -316,22 +316,7 @@ impl<'a> PathSource<'a> {
316316 }
317317}
318318
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 {
335320 /// The current trait's associated types' ident, used for diagnostic suggestions.
336321 current_trait_assoc_types : Vec < Ident > ,
337322
@@ -352,7 +337,27 @@ struct LateResolutionVisitor<'a, 'b> {
352337 current_type_ascription : Vec < Span > ,
353338
354339 /// 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 ,
356361}
357362
358363/// 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, '_> {
376381 self . resolve_expr ( expr, None ) ;
377382 }
378383 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+ ) ) ,
387392 } ;
388- let original = replace ( & mut self . current_let_binding , val ) ;
393+ let original = replace ( & mut self . diagnostic_metadata . current_let_binding , local_spans ) ;
389394 self . resolve_local ( local) ;
390- self . current_let_binding = original;
395+ self . diagnostic_metadata . current_let_binding = original;
391396 }
392397 fn visit_ty ( & mut self , ty : & ' tcx Ty ) {
393398 match ty. kind {
@@ -429,7 +434,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
429434 }
430435 }
431436 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) ) ;
433438 debug ! ( "(resolving function) entering function" ) ;
434439 let rib_kind = match fn_kind {
435440 FnKind :: ItemFn ( ..) => FnItemRibKind ,
@@ -455,7 +460,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
455460 debug ! ( "(resolving function) leaving function" ) ;
456461 } )
457462 } ) ;
458- self . current_function = previous_value;
463+ self . diagnostic_metadata . current_function = previous_value;
459464 }
460465
461466 fn visit_generics ( & mut self , generics : & ' tcx Generics ) {
@@ -489,7 +494,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
489494 // (We however cannot ban `Self` for defaults on *all* generic
490495 // lists; e.g. trait generics can usefully refer to `Self`,
491496 // 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.)
493499 default_ban_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , Res :: Err ) ;
494500 }
495501
@@ -541,13 +547,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
541547 } ,
542548 label_ribs : Vec :: new ( ) ,
543549 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+ }
551559 }
552560 }
553561
@@ -907,16 +915,22 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
907915
908916 fn with_current_self_type < T > ( & mut self , self_type : & Ty , f : impl FnOnce ( & mut Self ) -> T ) -> T {
909917 // 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+ ) ;
911922 let result = f ( self ) ;
912- self . current_self_type = previous_value;
923+ self . diagnostic_metadata . current_self_type = previous_value;
913924 result
914925 }
915926
916927 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+ ) ;
918932 let result = f ( self ) ;
919- self . current_self_item = previous_value;
933+ self . diagnostic_metadata . current_self_item = previous_value;
920934 result
921935 }
922936
@@ -927,14 +941,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
927941 f : impl FnOnce ( & mut Self ) -> T ,
928942 ) -> T {
929943 let trait_assoc_types = replace (
930- & mut self . current_trait_assoc_types ,
944+ & mut self . diagnostic_metadata . current_trait_assoc_types ,
931945 trait_items. iter ( ) . filter_map ( |item| match & item. kind {
932946 TraitItemKind :: Type ( bounds, _) if bounds. len ( ) == 0 => Some ( item. ident ) ,
933947 _ => None ,
934948 } ) . collect ( ) ,
935949 ) ;
936950 let result = f ( self ) ;
937- self . current_trait_assoc_types = trait_assoc_types;
951+ self . diagnostic_metadata . current_trait_assoc_types = trait_assoc_types;
938952 result
939953 }
940954
@@ -1761,7 +1775,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
17611775
17621776 fn with_resolved_label ( & mut self , label : Option < Label > , id : NodeId , f : impl FnOnce ( & mut Self ) ) {
17631777 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 ) ;
17651779 self . with_label_rib ( NormalRibKind , |this| {
17661780 let ident = label. ident . modern_and_legacy ( ) ;
17671781 this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, id) ;
@@ -1865,7 +1879,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
18651879 Some ( node_id) => {
18661880 // Since this res is a label, it is never read.
18671881 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) ;
18691883 }
18701884 }
18711885
@@ -1927,9 +1941,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
19271941 }
19281942 }
19291943 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 ) ;
19311945 visit:: walk_expr ( self , expr) ;
1932- self . current_type_ascription . pop ( ) ;
1946+ self . diagnostic_metadata . current_type_ascription . pop ( ) ;
19331947 }
19341948 // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
19351949 // resolve the arguments within the proper scopes so that usages of them inside the
@@ -2088,7 +2102,7 @@ impl<'a> Resolver<'a> {
20882102 pub ( crate ) fn late_resolve_crate ( & mut self , krate : & Crate ) {
20892103 let mut late_resolution_visitor = LateResolutionVisitor :: new ( self ) ;
20902104 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 ( ) {
20922106 self . session . buffer_lint ( lint:: builtin:: UNUSED_LABELS , * id, * span, "unused label" ) ;
20932107 }
20942108 }
0 commit comments