@@ -16,7 +16,6 @@ use log::debug;
16
16
use rustc_session:: CtfeBacktrace ;
17
17
use rustc_driver:: Compilation ;
18
18
use rustc_hir:: def_id:: LOCAL_CRATE ;
19
- use rustc_interface:: { interface, Queries } ;
20
19
use rustc_middle:: ty:: TyCtxt ;
21
20
22
21
struct MiriCompilerCalls {
@@ -26,8 +25,8 @@ struct MiriCompilerCalls {
26
25
impl rustc_driver:: Callbacks for MiriCompilerCalls {
27
26
fn after_analysis < ' tcx > (
28
27
& mut self ,
29
- compiler : & interface:: Compiler ,
30
- queries : & ' tcx Queries < ' tcx > ,
28
+ compiler : & rustc_interface :: interface:: Compiler ,
29
+ queries : & ' tcx rustc_interface :: Queries < ' tcx > ,
31
30
) -> Compilation {
32
31
compiler. session ( ) . abort_if_errors ( ) ;
33
32
@@ -106,12 +105,12 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
106
105
fn compile_time_sysroot ( ) -> Option < String > {
107
106
if option_env ! ( "RUSTC_STAGE" ) . is_some ( ) {
108
107
// This is being built as part of rustc, and gets shipped with rustup.
109
- // We can rely on the sysroot computation in librustc .
108
+ // We can rely on the sysroot computation in librustc_session .
110
109
return None ;
111
110
}
112
111
// For builds outside rustc, we need to ensure that we got a sysroot
113
- // that gets used as a default. The sysroot computation in librustc would
114
- // end up somewhere in the build dir.
112
+ // that gets used as a default. The sysroot computation in librustc_session would
113
+ // end up somewhere in the build dir (see `get_or_default_sysroot`) .
115
114
// Taken from PR <https://github.com/Manishearth/rust-clippy/pull/911>.
116
115
let home = option_env ! ( "RUSTUP_HOME" ) . or ( option_env ! ( "MULTIRUST_HOME" ) ) ;
117
116
let toolchain = option_env ! ( "RUSTUP_TOOLCHAIN" ) . or ( option_env ! ( "MULTIRUST_TOOLCHAIN" ) ) ;
@@ -123,13 +122,48 @@ fn compile_time_sysroot() -> Option<String> {
123
122
} )
124
123
}
125
124
125
+ /// Execute a compiler with the given CLI arguments and callbacks.
126
+ fn run_compiler ( mut args : Vec < String > , callbacks : & mut ( dyn rustc_driver:: Callbacks + Send ) ) {
127
+
128
+ // Make sure we use the right default sysroot. The default sysroot is wrong,
129
+ // because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`.
130
+ //
131
+ // Make sure we always call `compile_time_sysroot` as that also does some sanity-checks
132
+ // of the environment we were built in.
133
+ // FIXME: Ideally we'd turn a bad build env into a compile-time error via CTFE or so.
134
+ if let Some ( sysroot) = compile_time_sysroot ( ) {
135
+ let sysroot_flag = "--sysroot" ;
136
+ if !args. iter ( ) . any ( |e| e == sysroot_flag) {
137
+ // We need to overwrite the default that librustc_session would compute.
138
+ args. push ( sysroot_flag. to_owned ( ) ) ;
139
+ args. push ( sysroot) ;
140
+ }
141
+ }
142
+
143
+ // Invoke compiler, and handle return code.
144
+ let result = rustc_driver:: catch_fatal_errors ( move || {
145
+ rustc_driver:: run_compiler ( & args, callbacks, None , None )
146
+ } )
147
+ . and_then ( |result| result) ;
148
+ let exit_code = match result {
149
+ Ok ( ( ) ) => rustc_driver:: EXIT_SUCCESS ,
150
+ Err ( _) => rustc_driver:: EXIT_FAILURE ,
151
+ } ;
152
+ std:: process:: exit ( exit_code) ;
153
+ }
154
+
126
155
fn main ( ) {
156
+ rustc_driver:: install_ice_hook ( ) ;
157
+
127
158
// If the environment asks us to actually be rustc, then do that.
128
159
if env:: var_os ( "MIRI_BE_RUSTC" ) . is_some ( ) {
129
- eprintln ! ( "miri-as-rustc called with args: {:?}" , env:: args( ) ) ;
130
- return rustc_driver:: main ( ) ;
160
+ rustc_driver:: init_rustc_env_logger ( ) ;
161
+ // We cannot use `rustc_driver::main` as we need to adjust the CLI arguments.
162
+ let mut callbacks = rustc_driver:: TimePassesCallbacks :: default ( ) ;
163
+ return run_compiler ( env:: args ( ) . collect ( ) , & mut callbacks) ;
131
164
}
132
165
166
+ // Init loggers the Miri way.
133
167
init_early_loggers ( ) ;
134
168
135
169
// Parse our arguments and split them across `rustc` and `miri`.
@@ -142,16 +176,20 @@ fn main() {
142
176
let mut tracked_pointer_tag: Option < miri:: PtrId > = None ;
143
177
let mut tracked_alloc_id: Option < miri:: AllocId > = None ;
144
178
let mut rustc_args = vec ! [ ] ;
145
- let mut miri_args = vec ! [ ] ;
179
+ let mut crate_args = vec ! [ ] ;
146
180
let mut after_dashdash = false ;
147
181
let mut excluded_env_vars = vec ! [ ] ;
148
- for arg in std :: env:: args ( ) {
182
+ for arg in env:: args ( ) {
149
183
if rustc_args. is_empty ( ) {
150
- // Very first arg: for `rustc` .
184
+ // Very first arg: binary name .
151
185
rustc_args. push ( arg) ;
186
+ // After this, push Miri default args (before everything else so they can be overwritten).
187
+ for arg in miri:: miri_default_args ( ) . iter ( ) {
188
+ rustc_args. push ( arg. to_string ( ) ) ;
189
+ }
152
190
} else if after_dashdash {
153
- // Everything that comes after are `miri` args .
154
- miri_args . push ( arg) ;
191
+ // Everything that comes after `--` is forwarded to the interpreted crate .
192
+ crate_args . push ( arg) ;
155
193
} else {
156
194
match arg. as_str ( ) {
157
195
"-Zmiri-disable-validation" => {
@@ -227,30 +265,15 @@ fn main() {
227
265
tracked_alloc_id = Some ( miri:: AllocId ( id) ) ;
228
266
}
229
267
_ => {
268
+ // Forward to rustc.
230
269
rustc_args. push ( arg) ;
231
270
}
232
271
}
233
272
}
234
273
}
235
274
236
- // Determine sysroot if needed. Make sure we always call `compile_time_sysroot`
237
- // as that also does some sanity-checks of the environment we were built in.
238
- // FIXME: Ideally we'd turn a bad build env into a compile-time error, but
239
- // CTFE does not seem powerful enough for that yet.
240
- if let Some ( sysroot) = compile_time_sysroot ( ) {
241
- let sysroot_flag = "--sysroot" ;
242
- if !rustc_args. iter ( ) . any ( |e| e == sysroot_flag) {
243
- // We need to overwrite the default that librustc would compute.
244
- rustc_args. push ( sysroot_flag. to_owned ( ) ) ;
245
- rustc_args. push ( sysroot) ;
246
- }
247
- }
248
-
249
- // Finally, add the default flags all the way in the beginning, but after the binary name.
250
- rustc_args. splice ( 1 ..1 , miri:: miri_default_args ( ) . iter ( ) . map ( ToString :: to_string) ) ;
251
-
252
275
debug ! ( "rustc arguments: {:?}" , rustc_args) ;
253
- debug ! ( "miri arguments: {:?}" , miri_args ) ;
276
+ debug ! ( "crate arguments: {:?}" , crate_args ) ;
254
277
let miri_config = miri:: MiriConfig {
255
278
validate,
256
279
stacked_borrows,
@@ -259,18 +282,9 @@ fn main() {
259
282
ignore_leaks,
260
283
excluded_env_vars,
261
284
seed,
262
- args : miri_args ,
285
+ args : crate_args ,
263
286
tracked_pointer_tag,
264
287
tracked_alloc_id,
265
288
} ;
266
- rustc_driver:: install_ice_hook ( ) ;
267
- let result = rustc_driver:: catch_fatal_errors ( move || {
268
- rustc_driver:: run_compiler ( & rustc_args, & mut MiriCompilerCalls { miri_config } , None , None )
269
- } )
270
- . and_then ( |result| result) ;
271
- let exit_code = match result {
272
- Ok ( ( ) ) => rustc_driver:: EXIT_SUCCESS ,
273
- Err ( _) => rustc_driver:: EXIT_FAILURE ,
274
- } ;
275
- std:: process:: exit ( exit_code) ;
289
+ return run_compiler ( rustc_args, & mut MiriCompilerCalls { miri_config } ) ;
276
290
}
0 commit comments