@@ -5,7 +5,7 @@ use std::num::NonZeroU64;
55use log:: trace;
66
77use rustc_middle:: ty:: { self , TyCtxt } ;
8- use rustc_span:: { source_map:: DUMMY_SP , Span } ;
8+ use rustc_span:: { source_map:: DUMMY_SP , Span , SpanData , Symbol } ;
99
1010use crate :: * ;
1111
@@ -14,8 +14,18 @@ pub enum TerminationInfo {
1414 Exit ( i64 ) ,
1515 Abort ( String ) ,
1616 UnsupportedInIsolation ( String ) ,
17- ExperimentalUb { msg : String , url : String } ,
17+ ExperimentalUb {
18+ msg : String ,
19+ url : String ,
20+ } ,
1821 Deadlock ,
22+ MultipleSymbolDefinitions {
23+ link_name : Symbol ,
24+ first : SpanData ,
25+ first_crate : Symbol ,
26+ second : SpanData ,
27+ second_crate : Symbol ,
28+ } ,
1929}
2030
2131impl fmt:: Display for TerminationInfo {
@@ -27,6 +37,8 @@ impl fmt::Display for TerminationInfo {
2737 UnsupportedInIsolation ( msg) => write ! ( f, "{}" , msg) ,
2838 ExperimentalUb { msg, .. } => write ! ( f, "{}" , msg) ,
2939 Deadlock => write ! ( f, "the evaluated program deadlocked" ) ,
40+ MultipleSymbolDefinitions { link_name, .. } =>
41+ write ! ( f, "multiple definitions of symbol `{}`" , link_name) ,
3042 }
3143 }
3244}
@@ -55,19 +67,25 @@ pub fn report_error<'tcx, 'mir>(
5567 use TerminationInfo :: * ;
5668 let title = match info {
5769 Exit ( code) => return Some ( * code) ,
58- Abort ( _) => "abnormal termination" ,
59- UnsupportedInIsolation ( _) => "unsupported operation" ,
60- ExperimentalUb { .. } => "Undefined Behavior" ,
61- Deadlock => "deadlock" ,
70+ Abort ( _) => Some ( "abnormal termination" ) ,
71+ UnsupportedInIsolation ( _) => Some ( "unsupported operation" ) ,
72+ ExperimentalUb { .. } => Some ( "Undefined Behavior" ) ,
73+ Deadlock => Some ( "deadlock" ) ,
74+ MultipleSymbolDefinitions { .. } => None ,
6275 } ;
6376 #[ rustfmt:: skip]
6477 let helps = match info {
6578 UnsupportedInIsolation ( _) =>
66- vec ! [ format!( "pass the flag `-Zmiri-disable-isolation` to disable isolation" ) ] ,
79+ vec ! [ ( None , format!( "pass the flag `-Zmiri-disable-isolation` to disable isolation" ) ) ] ,
6780 ExperimentalUb { url, .. } =>
6881 vec ! [
69- format!( "this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental" ) ,
70- format!( "see {} for further information" , url) ,
82+ ( None , format!( "this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental" ) ) ,
83+ ( None , format!( "see {} for further information" , url) ) ,
84+ ] ,
85+ MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } =>
86+ vec ! [
87+ ( Some ( * first) , format!( "it's first defined here, in crate `{}`" , first_crate) ) ,
88+ ( Some ( * second) , format!( "then it's defined here again, in crate `{}`" , second_crate) ) ,
7189 ] ,
7290 _ => vec ! [ ] ,
7391 } ;
@@ -92,26 +110,26 @@ pub fn report_error<'tcx, 'mir>(
92110 #[ rustfmt:: skip]
93111 let helps = match e. kind ( ) {
94112 Unsupported ( UnsupportedOpInfo :: NoMirFor ( ..) ) =>
95- vec ! [ format!( "make sure to use a Miri sysroot, which you can prepare with `cargo miri setup`" ) ] ,
113+ vec ! [ ( None , format!( "make sure to use a Miri sysroot, which you can prepare with `cargo miri setup`" ) ) ] ,
96114 Unsupported ( UnsupportedOpInfo :: ReadBytesAsPointer | UnsupportedOpInfo :: ThreadLocalStatic ( _) | UnsupportedOpInfo :: ReadExternStatic ( _) ) =>
97115 panic ! ( "Error should never be raised by Miri: {:?}" , e. kind( ) ) ,
98116 Unsupported ( _) =>
99- vec ! [ format!( "this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support" ) ] ,
117+ vec ! [ ( None , format!( "this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support" ) ) ] ,
100118 UndefinedBehavior ( UndefinedBehaviorInfo :: AlignmentCheckFailed { .. } )
101119 if ecx. memory . extra . check_alignment == AlignmentCheck :: Symbolic
102120 =>
103121 vec ! [
104- format!( "this usually indicates that your program performed an invalid operation and caused Undefined Behavior" ) ,
105- format!( "but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives" ) ,
122+ ( None , format!( "this usually indicates that your program performed an invalid operation and caused Undefined Behavior" ) ) ,
123+ ( None , format!( "but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives" ) ) ,
106124 ] ,
107125 UndefinedBehavior ( _) =>
108126 vec ! [
109- format!( "this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior" ) ,
110- format!( "see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information" ) ,
127+ ( None , format!( "this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior" ) ) ,
128+ ( None , format!( "see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information" ) ) ,
111129 ] ,
112130 _ => vec ! [ ] ,
113131 } ;
114- ( title, helps)
132+ ( Some ( title) , helps)
115133 }
116134 } ;
117135
@@ -120,7 +138,7 @@ pub fn report_error<'tcx, 'mir>(
120138 report_msg (
121139 * ecx. tcx ,
122140 /*error*/ true ,
123- & format ! ( "{}: {}" , title, msg) ,
141+ & if let Some ( title ) = title { format ! ( "{}: {}" , title, msg) } else { msg . clone ( ) } ,
124142 msg,
125143 helps,
126144 & ecx. generate_stacktrace ( ) ,
@@ -159,7 +177,7 @@ fn report_msg<'tcx>(
159177 error : bool ,
160178 title : & str ,
161179 span_msg : String ,
162- mut helps : Vec < String > ,
180+ mut helps : Vec < ( Option < SpanData > , String ) > ,
163181 stacktrace : & [ FrameInfo < ' tcx > ] ,
164182) {
165183 let span = stacktrace. first ( ) . map_or ( DUMMY_SP , |fi| fi. span ) ;
@@ -179,9 +197,13 @@ fn report_msg<'tcx>(
179197 // Show help messages.
180198 if !helps. is_empty ( ) {
181199 // Add visual separator before backtrace.
182- helps. last_mut ( ) . unwrap ( ) . push_str ( "\n " ) ;
183- for help in helps {
184- err. help ( & help) ;
200+ helps. last_mut ( ) . unwrap ( ) . 1 . push_str ( "\n " ) ;
201+ for ( span_data, help) in helps {
202+ if let Some ( span_data) = span_data {
203+ err. span_help ( span_data. span ( ) , & help) ;
204+ } else {
205+ err. help ( & help) ;
206+ }
185207 }
186208 }
187209 // Add backtrace
0 commit comments