@@ -80,7 +80,7 @@ fn get_arg_flag_value(name: &str) -> Option<String> {
8080 }
8181}
8282
83- fn list_targets ( ) -> impl Iterator < Item =cargo_metadata:: Target > {
83+ fn list_targets ( ) -> ( impl Iterator < Item =cargo_metadata:: Target > , String ) {
8484 // We need to get the manifest, and then the metadata, to enumerate targets.
8585 let manifest_path = get_arg_flag_value ( "--manifest-path" ) . map ( |m|
8686 Path :: new ( & m) . canonicalize ( ) . unwrap ( )
@@ -119,7 +119,7 @@ fn list_targets() -> impl Iterator<Item=cargo_metadata::Target> {
119119 let package = metadata. packages . remove ( package_index) ;
120120
121121 // Finally we got the list of targets to build
122- package. targets . into_iter ( )
122+ ( package. targets . into_iter ( ) , metadata . workspace_root . to_string_lossy ( ) . to_string ( ) )
123123}
124124
125125/// Returns the path to the `miri` binary
@@ -342,6 +342,7 @@ path = "lib.rs"
342342 show_error ( format ! ( "Failed to run xargo" ) ) ;
343343 }
344344
345+
345346 // That should be it! But we need to figure out where xargo built stuff.
346347 // Unfortunately, it puts things into a different directory when the
347348 // architecture matches the host.
@@ -410,8 +411,10 @@ fn in_cargo_miri() {
410411 return ;
411412 }
412413
414+ let ( targets, root_dir) = list_targets ( ) ;
415+
413416 // Now run the command.
414- for target in list_targets ( ) {
417+ for target in targets {
415418 let mut args = std:: env:: args ( ) . skip ( skip) ;
416419 let kind = target. kind . get ( 0 ) . expect (
417420 "badly formatted cargo metadata: target::kind is an empty array" ,
@@ -420,7 +423,7 @@ fn in_cargo_miri() {
420423 // change to add additional arguments. `FLAGS` is set to identify
421424 // this target. The user gets to control what gets actually passed to Miri.
422425 let mut cmd = cargo ( ) ;
423- cmd. arg ( "rustc " ) ;
426+ cmd. arg ( "check " ) ;
424427 match ( subcommand, kind. as_str ( ) ) {
425428 ( MiriCommand :: Run , "bin" ) => {
426429 // FIXME: we just run all the binaries here.
@@ -447,14 +450,24 @@ fn in_cargo_miri() {
447450 }
448451 cmd. arg ( arg) ;
449452 }
453+
454+ let mut prefixed_args = String :: new ( ) ;
455+ for arg in args {
456+ prefixed_args += & arg. len ( ) . to_string ( ) ;
457+ prefixed_args. push ( ';' ) ;
458+ prefixed_args += & arg;
459+ }
460+
461+ cmd. env ( "MIRI_MAGIC_ARGS" , prefixed_args) ;
462+ cmd. env ( "MIRI_MAGIC_DIR" , root_dir. clone ( ) ) ;
450463 // Add `--` (to end the `cargo` flags), and then the user flags. We add markers around the
451464 // user flags to be able to identify them later. "cargo rustc" adds more stuff after this,
452465 // so we have to mark both the beginning and the end.
453- cmd
466+ /* cmd
454467 .arg("--")
455468 .arg("cargo-miri-marker-begin")
456469 .args(args)
457- . arg ( "cargo-miri-marker-end" ) ;
470+ .arg("cargo-miri-marker-end");*/
458471 let path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
459472 cmd. env ( "RUSTC_WRAPPER" , path) ;
460473 if verbose {
@@ -479,31 +492,71 @@ fn inside_cargo_rustc() {
479492
480493 let rustc_args = std:: env:: args ( ) . skip ( 2 ) ; // skip `cargo rustc`
481494
482- let mut args = if std:: env:: args ( ) . skip ( 2 ) . find ( |arg| arg == "build_script_build" ) . is_some ( ) {
483- rustc_args. collect ( )
495+ let ( mut args, is_build_script ) = if std:: env:: args ( ) . skip ( 2 ) . find ( |arg| arg == "build_script_build" ) . is_some ( ) {
496+ ( rustc_args. collect ( ) , true )
484497 } else {
485498 let mut args: Vec < String > = rustc_args
486499 . chain ( Some ( "--sysroot" . to_owned ( ) ) )
487500 . chain ( Some ( sysroot) )
488501 . collect ( ) ;
489502 args. splice ( 0 ..0 , miri:: miri_default_args ( ) . iter ( ) . map ( ToString :: to_string) ) ;
490- args
503+ ( args, false )
491504 } ;
492505
506+
507+ let is_test = args. contains ( & "--test" . to_string ( ) ) ;
508+ let mut is_bin = false ;
509+ for ( i, arg) in args. iter ( ) . enumerate ( ) {
510+ if arg == "--crate-type" && args[ i + 1 ] == "bin" {
511+ is_bin = true ;
512+ break ;
513+ }
514+ }
515+
516+
517+ let manifest_dir = std:: env:: var ( "CARGO_MANIFEST_DIR" ) . ok ( ) ;
518+ let expected_dir = std:: env:: var ( "MIRI_MAGIC_DIR" ) . ok ( ) ;
519+
520+ //eprintln!("Manifest: {:?}", manifest_dir);
521+ //eprintln!("Magic dir: {:?}", expected_dir);
522+
523+
493524 // See if we can find the `cargo-miri` markers. Those only get added to the binary we want to
494525 // run. They also serve to mark the user-defined arguments, which we have to move all the way
495526 // to the end (they get added somewhere in the middle).
496- let needs_miri = if let Some ( begin) = args. iter ( ) . position ( |arg| arg == "cargo-miri-marker-begin" ) {
497- let end = args
527+ //let needs_miri = if let Some(begin) = args.iter().position(|arg| arg == "cargo-miri-marker-begin") {
528+ let needs_miri = if manifest_dir == expected_dir && ( is_bin || is_test) && !is_build_script {
529+ /*let end = args
498530 .iter()
499531 .position(|arg| arg == "cargo-miri-marker-end")
500532 .expect("cannot find end marker");
501533 // These mark the user arguments. We remove the first and last as they are the markers.
502- let mut user_args = args. drain ( begin..=end) ;
503- assert_eq ! ( user_args. next( ) . unwrap( ) , "cargo-miri-marker-begin" ) ;
504- assert_eq ! ( user_args. next_back( ) . unwrap( ) , "cargo-miri-marker-end" ) ;
534+ let mut user_args = args.drain(begin..=end);*/
535+
536+ let raw_args = std:: env:: var ( "MIRI_MAGIC_ARGS" ) . expect ( "Misisng magic!" ) ;
537+ let mut user_args = vec ! [ ] ;
538+ let mut slice = raw_args. as_str ( ) ;
539+ //eprintln!("Raw args: {:?}", raw_args);
540+ loop {
541+ match slice. find ( ';' ) {
542+ Some ( pos) => {
543+ //eprintln!("Slice: {:?} Len str: (pos {}) {:?}", slice, pos, &slice[..(pos)]);
544+ let len: usize = slice[ ..( pos) ] . parse ( ) . unwrap ( ) ;
545+ //eprintln!("Parsed len: {:?}", len);
546+ let arg = slice[ ( pos+1 ) ..=( pos+len) ] . to_string ( ) ;
547+ user_args. push ( arg) ;
548+ slice = & slice[ ( pos+len+1 ) ..] ;
549+ } ,
550+ None => break
551+ }
552+ }
553+
554+ //println!("User args: {:?}", user_args);
555+
556+ //assert_eq!(user_args.next().unwrap(), "cargo-miri-marker-begin");
557+ //assert_eq!(user_args.next_back().unwrap(), "cargo-miri-marker-end");
505558 // Collect the rest and add it back at the end.
506- let mut user_args = user_args. collect :: < Vec < String > > ( ) ;
559+ // let mut user_args = user_args.collect::<Vec<String>>();
507560 args. append ( & mut user_args) ;
508561 // Run this in Miri.
509562 true
0 commit comments