@@ -882,6 +882,50 @@ fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
882882 }
883883}
884884
885+ #[ inline( never) ] // give this a place in the profiler
886+ fn assert_symbols_are_distinct < ' a , ' tcx , I > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , mono_items : I )
887+ where I : Iterator < Item =& ' a MonoItem < ' tcx > >
888+ {
889+ let mut symbols: Vec < _ > = mono_items. map ( |mono_item| {
890+ ( mono_item, mono_item. symbol_name ( tcx) )
891+ } ) . collect ( ) ;
892+
893+ symbols. sort_by_key ( |sym| sym. 1 ) ;
894+
895+ for pair in symbols. windows ( 2 ) {
896+ let sym1 = & pair[ 0 ] . 1 ;
897+ let sym2 = & pair[ 1 ] . 1 ;
898+
899+ if sym1 == sym2 {
900+ let mono_item1 = pair[ 0 ] . 0 ;
901+ let mono_item2 = pair[ 1 ] . 0 ;
902+
903+ let span1 = mono_item1. local_span ( tcx) ;
904+ let span2 = mono_item2. local_span ( tcx) ;
905+
906+ // Deterministically select one of the spans for error reporting
907+ let span = match ( span1, span2) {
908+ ( Some ( span1) , Some ( span2) ) => {
909+ Some ( if span1. lo ( ) . 0 > span2. lo ( ) . 0 {
910+ span1
911+ } else {
912+ span2
913+ } )
914+ }
915+ ( span1, span2) => span1. or ( span2) ,
916+ } ;
917+
918+ let error_message = format ! ( "symbol `{}` is already defined" , sym1) ;
919+
920+ if let Some ( span) = span {
921+ tcx. sess . span_fatal ( span, & error_message)
922+ } else {
923+ tcx. sess . fatal ( & error_message)
924+ }
925+ }
926+ }
927+ }
928+
885929fn collect_and_partition_mono_items < ' a , ' tcx > (
886930 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
887931 cnum : CrateNum ,
@@ -922,7 +966,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>(
922966
923967 tcx. sess . abort_if_errors ( ) ;
924968
925- crate :: monomorphize :: assert_symbols_are_distinct ( tcx, items. iter ( ) ) ;
969+ assert_symbols_are_distinct ( tcx, items. iter ( ) ) ;
926970
927971 let strategy = if tcx. sess . opts . incremental . is_some ( ) {
928972 PartitioningStrategy :: PerModule
0 commit comments