@@ -320,22 +320,7 @@ impl<'a> PathSource<'a> {
320320 }
321321}
322322
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 {
339324 /// The current trait's associated types' ident, used for diagnostic suggestions.
340325 current_trait_assoc_types : Vec < Ident > ,
341326
@@ -356,7 +341,27 @@ struct LateResolutionVisitor<'a, 'b> {
356341 current_type_ascription : Vec < Span > ,
357342
358343 /// 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 ,
360365}
361366
362367/// 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, '_> {
380385 self . resolve_expr ( expr, None ) ;
381386 }
382387 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+ ) ) ,
391396 } ;
392- let original = replace ( & mut self . current_let_binding , val ) ;
397+ let original = replace ( & mut self . diagnostic_metadata . current_let_binding , local_spans ) ;
393398 self . resolve_local ( local) ;
394- self . current_let_binding = original;
399+ self . diagnostic_metadata . current_let_binding = original;
395400 }
396401 fn visit_ty ( & mut self , ty : & ' tcx Ty ) {
397402 match ty. kind {
@@ -433,7 +438,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
433438 }
434439 }
435440 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) ) ;
437442 debug ! ( "(resolving function) entering function" ) ;
438443 let rib_kind = match fn_kind {
439444 FnKind :: ItemFn ( ..) => FnItemRibKind ,
@@ -459,7 +464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
459464 debug ! ( "(resolving function) leaving function" ) ;
460465 } )
461466 } ) ;
462- self . current_function = previous_value;
467+ self . diagnostic_metadata . current_function = previous_value;
463468 }
464469
465470 fn visit_generics ( & mut self , generics : & ' tcx Generics ) {
@@ -493,7 +498,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
493498 // (We however cannot ban `Self` for defaults on *all* generic
494499 // lists; e.g. trait generics can usefully refer to `Self`,
495500 // 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.)
497503 default_ban_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , Res :: Err ) ;
498504 }
499505
@@ -562,13 +568,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
562568 } ,
563569 label_ribs : Vec :: new ( ) ,
564570 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+ }
572580 }
573581 }
574582
@@ -928,16 +936,22 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
928936
929937 fn with_current_self_type < T > ( & mut self , self_type : & Ty , f : impl FnOnce ( & mut Self ) -> T ) -> T {
930938 // 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+ ) ;
932943 let result = f ( self ) ;
933- self . current_self_type = previous_value;
944+ self . diagnostic_metadata . current_self_type = previous_value;
934945 result
935946 }
936947
937948 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+ ) ;
939953 let result = f ( self ) ;
940- self . current_self_item = previous_value;
954+ self . diagnostic_metadata . current_self_item = previous_value;
941955 result
942956 }
943957
@@ -948,14 +962,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
948962 f : impl FnOnce ( & mut Self ) -> T ,
949963 ) -> T {
950964 let trait_assoc_types = replace (
951- & mut self . current_trait_assoc_types ,
965+ & mut self . diagnostic_metadata . current_trait_assoc_types ,
952966 trait_items. iter ( ) . filter_map ( |item| match & item. kind {
953967 TraitItemKind :: Type ( bounds, _) if bounds. len ( ) == 0 => Some ( item. ident ) ,
954968 _ => None ,
955969 } ) . collect ( ) ,
956970 ) ;
957971 let result = f ( self ) ;
958- self . current_trait_assoc_types = trait_assoc_types;
972+ self . diagnostic_metadata . current_trait_assoc_types = trait_assoc_types;
959973 result
960974 }
961975
@@ -1782,7 +1796,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
17821796
17831797 fn with_resolved_label ( & mut self , label : Option < Label > , id : NodeId , f : impl FnOnce ( & mut Self ) ) {
17841798 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 ) ;
17861800 self . with_label_rib ( NormalRibKind , |this| {
17871801 let ident = label. ident . modern_and_legacy ( ) ;
17881802 this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, id) ;
@@ -1886,7 +1900,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
18861900 Some ( node_id) => {
18871901 // Since this res is a label, it is never read.
18881902 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) ;
18901904 }
18911905 }
18921906
@@ -1948,9 +1962,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
19481962 }
19491963 }
19501964 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 ) ;
19521966 visit:: walk_expr ( self , expr) ;
1953- self . current_type_ascription . pop ( ) ;
1967+ self . diagnostic_metadata . current_type_ascription . pop ( ) ;
19541968 }
19551969 // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
19561970 // resolve the arguments within the proper scopes so that usages of them inside the
@@ -2109,7 +2123,7 @@ impl<'a> Resolver<'a> {
21092123 pub ( crate ) fn late_resolve_crate ( & mut self , krate : & Crate ) {
21102124 let mut late_resolution_visitor = LateResolutionVisitor :: new ( self ) ;
21112125 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 ( ) {
21132127 self . session . buffer_lint ( lint:: builtin:: UNUSED_LABELS , * id, * span, "unused label" ) ;
21142128 }
21152129 }
0 commit comments