@@ -5,7 +5,7 @@ use std::num::NonZeroU64;
5
5
use log:: trace;
6
6
7
7
use 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 } ;
9
9
10
10
use crate :: * ;
11
11
@@ -14,8 +14,18 @@ pub enum TerminationInfo {
14
14
Exit ( i64 ) ,
15
15
Abort ( String ) ,
16
16
UnsupportedInIsolation ( String ) ,
17
- ExperimentalUb { msg : String , url : String } ,
17
+ ExperimentalUb {
18
+ msg : String ,
19
+ url : String ,
20
+ } ,
18
21
Deadlock ,
22
+ MultipleSymbolDefinitions {
23
+ link_name : Symbol ,
24
+ first : SpanData ,
25
+ first_crate : Symbol ,
26
+ second : SpanData ,
27
+ second_crate : Symbol ,
28
+ } ,
19
29
}
20
30
21
31
impl fmt:: Display for TerminationInfo {
@@ -27,6 +37,8 @@ impl fmt::Display for TerminationInfo {
27
37
UnsupportedInIsolation ( msg) => write ! ( f, "{}" , msg) ,
28
38
ExperimentalUb { msg, .. } => write ! ( f, "{}" , msg) ,
29
39
Deadlock => write ! ( f, "the evaluated program deadlocked" ) ,
40
+ MultipleSymbolDefinitions { link_name, .. } =>
41
+ write ! ( f, "multiple definitions of symbol `{}`" , link_name) ,
30
42
}
31
43
}
32
44
}
@@ -55,19 +67,25 @@ pub fn report_error<'tcx, 'mir>(
55
67
use TerminationInfo :: * ;
56
68
let title = match info {
57
69
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 ,
62
75
} ;
63
76
#[ rustfmt:: skip]
64
77
let helps = match info {
65
78
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" ) ) ] ,
67
80
ExperimentalUb { url, .. } =>
68
81
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) ) ,
71
89
] ,
72
90
_ => vec ! [ ] ,
73
91
} ;
@@ -92,26 +110,26 @@ pub fn report_error<'tcx, 'mir>(
92
110
#[ rustfmt:: skip]
93
111
let helps = match e. kind ( ) {
94
112
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`" ) ) ] ,
96
114
Unsupported ( UnsupportedOpInfo :: ReadBytesAsPointer | UnsupportedOpInfo :: ThreadLocalStatic ( _) | UnsupportedOpInfo :: ReadExternStatic ( _) ) =>
97
115
panic ! ( "Error should never be raised by Miri: {:?}" , e. kind( ) ) ,
98
116
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" ) ) ] ,
100
118
UndefinedBehavior ( UndefinedBehaviorInfo :: AlignmentCheckFailed { .. } )
101
119
if ecx. memory . extra . check_alignment == AlignmentCheck :: Symbolic
102
120
=>
103
121
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" ) ) ,
106
124
] ,
107
125
UndefinedBehavior ( _) =>
108
126
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" ) ) ,
111
129
] ,
112
130
_ => vec ! [ ] ,
113
131
} ;
114
- ( title, helps)
132
+ ( Some ( title) , helps)
115
133
}
116
134
} ;
117
135
@@ -120,7 +138,7 @@ pub fn report_error<'tcx, 'mir>(
120
138
report_msg (
121
139
* ecx. tcx ,
122
140
/*error*/ true ,
123
- & format ! ( "{}: {}" , title, msg) ,
141
+ & if let Some ( title ) = title { format ! ( "{}: {}" , title, msg) } else { msg . clone ( ) } ,
124
142
msg,
125
143
helps,
126
144
& ecx. generate_stacktrace ( ) ,
@@ -159,7 +177,7 @@ fn report_msg<'tcx>(
159
177
error : bool ,
160
178
title : & str ,
161
179
span_msg : String ,
162
- mut helps : Vec < String > ,
180
+ mut helps : Vec < ( Option < SpanData > , String ) > ,
163
181
stacktrace : & [ FrameInfo < ' tcx > ] ,
164
182
) {
165
183
let span = stacktrace. first ( ) . map_or ( DUMMY_SP , |fi| fi. span ) ;
@@ -179,9 +197,13 @@ fn report_msg<'tcx>(
179
197
// Show help messages.
180
198
if !helps. is_empty ( ) {
181
199
// 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
+ }
185
207
}
186
208
}
187
209
// Add backtrace
0 commit comments