@@ -16,7 +16,6 @@ use log::debug;
1616use rustc_session:: CtfeBacktrace ;
1717use rustc_driver:: Compilation ;
1818use rustc_hir:: def_id:: LOCAL_CRATE ;
19- use rustc_interface:: { interface, Queries } ;
2019use rustc_middle:: ty:: TyCtxt ;
2120
2221struct MiriCompilerCalls {
@@ -26,8 +25,8 @@ struct MiriCompilerCalls {
2625impl rustc_driver:: Callbacks for MiriCompilerCalls {
2726 fn after_analysis < ' tcx > (
2827 & mut self ,
29- compiler : & interface:: Compiler ,
30- queries : & ' tcx Queries < ' tcx > ,
28+ compiler : & rustc_interface :: interface:: Compiler ,
29+ queries : & ' tcx rustc_interface :: Queries < ' tcx > ,
3130 ) -> Compilation {
3231 compiler. session ( ) . abort_if_errors ( ) ;
3332
@@ -106,12 +105,12 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
106105fn compile_time_sysroot ( ) -> Option < String > {
107106 if option_env ! ( "RUSTC_STAGE" ) . is_some ( ) {
108107 // 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 .
110109 return None ;
111110 }
112111 // 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`) .
115114 // Taken from PR <https://github.com/Manishearth/rust-clippy/pull/911>.
116115 let home = option_env ! ( "RUSTUP_HOME" ) . or ( option_env ! ( "MULTIRUST_HOME" ) ) ;
117116 let toolchain = option_env ! ( "RUSTUP_TOOLCHAIN" ) . or ( option_env ! ( "MULTIRUST_TOOLCHAIN" ) ) ;
@@ -123,13 +122,47 @@ fn compile_time_sysroot() -> Option<String> {
123122 } )
124123}
125124
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+ // Make sure we use the right default sysroot. The default sysroot is wrong,
128+ // because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`.
129+ //
130+ // Make sure we always call `compile_time_sysroot` as that also does some sanity-checks
131+ // of the environment we were built in.
132+ // FIXME: Ideally we'd turn a bad build env into a compile-time error via CTFE or so.
133+ if let Some ( sysroot) = compile_time_sysroot ( ) {
134+ let sysroot_flag = "--sysroot" ;
135+ if !args. iter ( ) . any ( |e| e == sysroot_flag) {
136+ // We need to overwrite the default that librustc_session would compute.
137+ args. push ( sysroot_flag. to_owned ( ) ) ;
138+ args. push ( sysroot) ;
139+ }
140+ }
141+
142+ // Invoke compiler, and handle return code.
143+ let result = rustc_driver:: catch_fatal_errors ( move || {
144+ rustc_driver:: run_compiler ( & args, callbacks, None , None )
145+ } )
146+ . and_then ( |result| result) ;
147+ let exit_code = match result {
148+ Ok ( ( ) ) => rustc_driver:: EXIT_SUCCESS ,
149+ Err ( _) => rustc_driver:: EXIT_FAILURE ,
150+ } ;
151+ std:: process:: exit ( exit_code) ;
152+ }
153+
126154fn main ( ) {
155+ rustc_driver:: install_ice_hook ( ) ;
156+
127157 // If the environment asks us to actually be rustc, then do that.
128158 if env:: var_os ( "MIRI_BE_RUSTC" ) . is_some ( ) {
129- eprintln ! ( "miri-as-rustc called with args: {:?}" , env:: args( ) ) ;
130- return rustc_driver:: main ( ) ;
159+ rustc_driver:: init_rustc_env_logger ( ) ;
160+ // We cannot use `rustc_driver::main` as we need to adjust the CLI arguments.
161+ let mut callbacks = rustc_driver:: TimePassesCallbacks :: default ( ) ;
162+ return run_compiler ( env:: args ( ) . collect ( ) , & mut callbacks) ;
131163 }
132164
165+ // Init loggers the Miri way.
133166 init_early_loggers ( ) ;
134167
135168 // Parse our arguments and split them across `rustc` and `miri`.
@@ -142,16 +175,20 @@ fn main() {
142175 let mut tracked_pointer_tag: Option < miri:: PtrId > = None ;
143176 let mut tracked_alloc_id: Option < miri:: AllocId > = None ;
144177 let mut rustc_args = vec ! [ ] ;
145- let mut miri_args = vec ! [ ] ;
178+ let mut crate_args = vec ! [ ] ;
146179 let mut after_dashdash = false ;
147180 let mut excluded_env_vars = vec ! [ ] ;
148- for arg in std :: env:: args ( ) {
181+ for arg in env:: args ( ) {
149182 if rustc_args. is_empty ( ) {
150- // Very first arg: for `rustc` .
183+ // Very first arg: binary name .
151184 rustc_args. push ( arg) ;
185+ // After this, push Miri default args (before everything else so they can be overwritten).
186+ for arg in miri:: miri_default_args ( ) . iter ( ) {
187+ rustc_args. push ( arg. to_string ( ) ) ;
188+ }
152189 } else if after_dashdash {
153- // Everything that comes after are `miri` args .
154- miri_args . push ( arg) ;
190+ // Everything that comes after `--` is forwarded to the interpreted crate .
191+ crate_args . push ( arg) ;
155192 } else {
156193 match arg. as_str ( ) {
157194 "-Zmiri-disable-validation" => {
@@ -227,30 +264,15 @@ fn main() {
227264 tracked_alloc_id = Some ( miri:: AllocId ( id) ) ;
228265 }
229266 _ => {
267+ // Forward to rustc.
230268 rustc_args. push ( arg) ;
231269 }
232270 }
233271 }
234272 }
235273
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-
252274 debug ! ( "rustc arguments: {:?}" , rustc_args) ;
253- debug ! ( "miri arguments: {:?}" , miri_args ) ;
275+ debug ! ( "crate arguments: {:?}" , crate_args ) ;
254276 let miri_config = miri:: MiriConfig {
255277 validate,
256278 stacked_borrows,
@@ -259,18 +281,9 @@ fn main() {
259281 ignore_leaks,
260282 excluded_env_vars,
261283 seed,
262- args : miri_args ,
284+ args : crate_args ,
263285 tracked_pointer_tag,
264286 tracked_alloc_id,
265287 } ;
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) ;
288+ return run_compiler ( rustc_args, & mut MiriCompilerCalls { miri_config } ) ;
276289}
0 commit comments