@@ -16,6 +16,7 @@ use rustc_middle::middle::privacy;
1616use rustc_middle:: ty:: { self , DefIdTree , TyCtxt } ;
1717use rustc_session:: lint;
1818use rustc_span:: symbol:: { sym, Symbol } ;
19+ use rustc_span:: Span ;
1920use std:: mem;
2021
2122// Any local node that may call something in its body block should be
@@ -49,7 +50,9 @@ struct MarkSymbolVisitor<'tcx> {
4950 // maps from tuple struct constructors to tuple struct items
5051 struct_constructors : FxHashMap < LocalDefId , LocalDefId > ,
5152 // maps from ADTs to ignored derived traits (e.g. Debug and Clone)
52- ignored_derived_traits : FxHashMap < DefId , Vec < DefId > > ,
53+ // and the span of their respective impl (i.e., part of the derive
54+ // macro)
55+ ignored_derived_traits : FxHashMap < DefId , Vec < ( Span , DefId ) > > ,
5356}
5457
5558impl < ' tcx > MarkSymbolVisitor < ' tcx > {
@@ -255,10 +258,12 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
255258 if self . tcx . has_attr ( trait_of, sym:: rustc_trivial_field_reads) {
256259 let trait_ref = self . tcx . impl_trait_ref ( impl_of) . unwrap ( ) ;
257260 if let ty:: Adt ( adt_def, _) = trait_ref. self_ty ( ) . kind ( ) {
261+ let impl_span = self . tcx . def_span ( impl_of) ;
258262 if let Some ( v) = self . ignored_derived_traits . get_mut ( & adt_def. did ) {
259- v. push ( trait_of) ;
263+ v. push ( ( impl_span , trait_of) ) ;
260264 } else {
261- self . ignored_derived_traits . insert ( adt_def. did , vec ! [ trait_of] ) ;
265+ self . ignored_derived_traits
266+ . insert ( adt_def. did , vec ! [ ( impl_span, trait_of) ] ) ;
262267 }
263268 }
264269 return true ;
@@ -588,7 +593,7 @@ fn create_and_seed_worklist<'tcx>(
588593fn find_live < ' tcx > (
589594 tcx : TyCtxt < ' tcx > ,
590595 access_levels : & privacy:: AccessLevels ,
591- ) -> ( FxHashSet < LocalDefId > , FxHashMap < DefId , Vec < DefId > > ) {
596+ ) -> ( FxHashSet < LocalDefId > , FxHashMap < DefId , Vec < ( Span , DefId ) > > ) {
592597 let ( worklist, struct_constructors) = create_and_seed_worklist ( tcx, access_levels) ;
593598 let mut symbol_visitor = MarkSymbolVisitor {
594599 worklist,
@@ -610,7 +615,7 @@ fn find_live<'tcx>(
610615struct DeadVisitor < ' tcx > {
611616 tcx : TyCtxt < ' tcx > ,
612617 live_symbols : FxHashSet < LocalDefId > ,
613- ignored_derived_traits : FxHashMap < DefId , Vec < DefId > > ,
618+ ignored_derived_traits : FxHashMap < DefId , Vec < ( Span , DefId ) > > ,
614619}
615620
616621impl < ' tcx > DeadVisitor < ' tcx > {
@@ -683,26 +688,29 @@ impl<'tcx> DeadVisitor<'tcx> {
683688 let hir = self . tcx . hir ( ) ;
684689 if let Some ( encl_scope) = hir. get_enclosing_scope ( id) {
685690 if let Some ( encl_def_id) = hir. opt_local_def_id ( encl_scope) {
686- if let Some ( ign_traits) = self . ignored_derived_traits . get ( & encl_def_id. to_def_id ( ) ) {
691+ if let Some ( ign_traits) =
692+ self . ignored_derived_traits . get ( & encl_def_id. to_def_id ( ) )
693+ {
687694 let traits_str = ign_traits
688695 . iter ( )
689- . map ( |t| format ! ( "`{}`" , self . tcx. item_name( * t) ) ) . collect :: < Vec < _ > > ( )
696+ . map ( |( _, t) | format ! ( "`{}`" , self . tcx. item_name( * t) ) )
697+ . collect :: < Vec < _ > > ( )
690698 . join ( " and " ) ;
691699 let plural_s = pluralize ! ( ign_traits. len( ) ) ;
692700 let article = if ign_traits. len ( ) > 1 { "" } else { "a " } ;
693701 let is_are = if ign_traits. len ( ) > 1 { "these are" } else { "this is" } ;
694- let msg = format ! ( "`{}` has {}derived impl{} for the trait{} {}, but {} ignored during dead code analysis" ,
695- self . tcx . item_name ( encl_def_id . to_def_id ( ) ) ,
696- article ,
697- plural_s ,
698- plural_s ,
699- traits_str ,
700- is_are ) ;
701- if let Some ( span ) = self . tcx . def_ident_span ( encl_def_id ) {
702- err . span_note ( span , & msg ) ;
703- } else {
704- err . note ( & msg ) ;
705- }
702+ let msg = format ! (
703+ "`{}` has {}derived impl{} for the trait{} {}, but {} \
704+ intentionally ignored during dead code analysis" ,
705+ self . tcx . item_name ( encl_def_id . to_def_id ( ) ) ,
706+ article ,
707+ plural_s ,
708+ plural_s ,
709+ traits_str ,
710+ is_are
711+ ) ;
712+ let multispan = ign_traits . iter ( ) . map ( | ( s , _ ) | * s ) . collect :: < Vec < _ > > ( ) ;
713+ err . span_note ( multispan , & msg ) ;
706714 }
707715 }
708716 }
0 commit comments