@@ -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
} ;
@@ -90,26 +108,26 @@ pub fn report_error<'tcx, 'mir>(
90
108
#[ rustfmt:: skip]
91
109
let helps = match e. kind ( ) {
92
110
Unsupported ( UnsupportedOpInfo :: NoMirFor ( ..) ) =>
93
- vec ! [ format!( "make sure to use a Miri sysroot, which you can prepare with `cargo miri setup`" ) ] ,
111
+ vec ! [ ( None , format!( "make sure to use a Miri sysroot, which you can prepare with `cargo miri setup`" ) ) ] ,
94
112
Unsupported ( UnsupportedOpInfo :: ReadBytesAsPointer | UnsupportedOpInfo :: ThreadLocalStatic ( _) | UnsupportedOpInfo :: ReadExternStatic ( _) ) =>
95
113
panic ! ( "Error should never be raised by Miri: {:?}" , e. kind( ) ) ,
96
114
Unsupported ( _) =>
97
- 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" ) ] ,
115
+ 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" ) ) ] ,
98
116
UndefinedBehavior ( UndefinedBehaviorInfo :: AlignmentCheckFailed { .. } )
99
117
if ecx. memory . extra . check_alignment == AlignmentCheck :: Symbolic
100
118
=>
101
119
vec ! [
102
- format!( "this usually indicates that your program performed an invalid operation and caused Undefined Behavior" ) ,
103
- format!( "but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives" ) ,
120
+ ( None , format!( "this usually indicates that your program performed an invalid operation and caused Undefined Behavior" ) ) ,
121
+ ( None , format!( "but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives" ) ) ,
104
122
] ,
105
123
UndefinedBehavior ( _) =>
106
124
vec ! [
107
- format!( "this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior" ) ,
108
- format!( "see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information" ) ,
125
+ ( None , format!( "this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior" ) ) ,
126
+ ( None , format!( "see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information" ) ) ,
109
127
] ,
110
128
_ => vec ! [ ] ,
111
129
} ;
112
- ( title, helps)
130
+ ( Some ( title) , helps)
113
131
}
114
132
} ;
115
133
@@ -118,7 +136,7 @@ pub fn report_error<'tcx, 'mir>(
118
136
report_msg (
119
137
* ecx. tcx ,
120
138
/*error*/ true ,
121
- & format ! ( "{}: {}" , title, msg) ,
139
+ & if let Some ( title ) = title { format ! ( "{}: {}" , title, msg) } else { msg . clone ( ) } ,
122
140
msg,
123
141
helps,
124
142
& ecx. generate_stacktrace ( ) ,
@@ -157,7 +175,7 @@ fn report_msg<'tcx>(
157
175
error : bool ,
158
176
title : & str ,
159
177
span_msg : String ,
160
- mut helps : Vec < String > ,
178
+ mut helps : Vec < ( Option < SpanData > , String ) > ,
161
179
stacktrace : & [ FrameInfo < ' tcx > ] ,
162
180
) {
163
181
let span = stacktrace. first ( ) . map_or ( DUMMY_SP , |fi| fi. span ) ;
@@ -177,9 +195,13 @@ fn report_msg<'tcx>(
177
195
// Show help messages.
178
196
if !helps. is_empty ( ) {
179
197
// Add visual separator before backtrace.
180
- helps. last_mut ( ) . unwrap ( ) . push_str ( "\n " ) ;
181
- for help in helps {
182
- err. help ( & help) ;
198
+ helps. last_mut ( ) . unwrap ( ) . 1 . push_str ( "\n " ) ;
199
+ for ( span_data, help) in helps {
200
+ if let Some ( span_data) = span_data {
201
+ err. span_help ( span_data. span ( ) , & help) ;
202
+ } else {
203
+ err. help ( & help) ;
204
+ }
183
205
}
184
206
}
185
207
// Add backtrace
0 commit comments