@@ -472,6 +472,43 @@ path = "lib.rs"
472472 }
473473}
474474
475+ /// Detect the target directory by calling `cargo metadata`.
476+ fn detect_target_dir ( ) -> PathBuf {
477+ #[ derive( Deserialize ) ]
478+ struct Metadata {
479+ target_directory : PathBuf ,
480+ }
481+ let mut cmd = cargo ( ) ;
482+ // `-Zunstable-options` is required by `--config`.
483+ cmd. args ( [ "metadata" , "--no-deps" , "--format-version=1" , "-Zunstable-options" ] ) ;
484+ // The `build.target-dir` config can by passed by `--config` flags, so forward them to
485+ // `cargo metadata`.
486+ let config_flag = "--config" ;
487+ for arg in ArgFlagValueWithOtherArgsIter :: new (
488+ env:: args ( ) . skip ( 3 ) , // skip the program name, "miri" and "run" / "test"
489+ config_flag,
490+ ) {
491+ if let Ok ( config) = arg {
492+ cmd. arg ( config_flag) . arg ( config) ;
493+ }
494+ }
495+ let mut child = cmd
496+ . stdin ( Stdio :: null ( ) )
497+ . stdout ( Stdio :: piped ( ) )
498+ . spawn ( )
499+ . expect ( "failed ro run `cargo metadata`" ) ;
500+ // Check this `Result` after `status.success()` is checked, so we don't print the error
501+ // to stderr if `cargo metadata` is also printing to stderr.
502+ let metadata: Result < Metadata , _ > = serde_json:: from_reader ( child. stdout . take ( ) . unwrap ( ) ) ;
503+ let status = child. wait ( ) . expect ( "failed to wait `cargo metadata` to exit" ) ;
504+ if !status. success ( ) {
505+ std:: process:: exit ( status. code ( ) . unwrap_or ( -1 ) ) ;
506+ }
507+ metadata
508+ . unwrap_or_else ( |e| show_error ( format ! ( "invalid `cargo metadata` output: {}" , e) ) )
509+ . target_directory
510+ }
511+
475512fn phase_cargo_miri ( mut args : env:: Args ) {
476513 // Check for version and help flags even when invoked as `cargo-miri`.
477514 if has_arg_flag ( "--help" ) || has_arg_flag ( "-h" ) {
@@ -541,41 +578,7 @@ fn phase_cargo_miri(mut args: env::Args) {
541578 }
542579
543580 // Detect the target directory if it's not specified via `--target-dir`.
544- let target_dir = target_dir. get_or_insert_with ( || {
545- #[ derive( Deserialize ) ]
546- struct Metadata {
547- target_directory : PathBuf ,
548- }
549- let mut cmd = cargo ( ) ;
550- // `-Zunstable-options` is required by `--config`.
551- cmd. args ( [ "metadata" , "--no-deps" , "--format-version=1" , "-Zunstable-options" ] ) ;
552- // The `build.target-dir` config can by passed by `--config` flags, so forward them to
553- // `cargo metadata`.
554- let config_flag = "--config" ;
555- for arg in ArgFlagValueWithOtherArgsIter :: new (
556- env:: args ( ) . skip ( 3 ) , // skip the program name, "miri" and "run" / "test"
557- config_flag,
558- ) {
559- if let Ok ( config) = arg {
560- cmd. arg ( config_flag) . arg ( config) ;
561- }
562- }
563- let mut child = cmd
564- . stdin ( Stdio :: null ( ) )
565- . stdout ( Stdio :: piped ( ) )
566- . spawn ( )
567- . expect ( "failed ro run `cargo metadata`" ) ;
568- // Check this `Result` after `status.success()` is checked, so we don't print the error
569- // to stderr if `cargo metadata` is also printing to stderr.
570- let metadata: Result < Metadata , _ > = serde_json:: from_reader ( child. stdout . take ( ) . unwrap ( ) ) ;
571- let status = child. wait ( ) . expect ( "failed to wait `cargo metadata` to exit" ) ;
572- if !status. success ( ) {
573- std:: process:: exit ( status. code ( ) . unwrap_or ( -1 ) ) ;
574- }
575- metadata
576- . unwrap_or_else ( |e| show_error ( format ! ( "invalid `cargo metadata` output: {}" , e) ) )
577- . target_directory
578- } ) ;
581+ let target_dir = target_dir. get_or_insert_with ( detect_target_dir) ;
579582
580583 // Set `--target-dir` to `miri` inside the original target directory.
581584 target_dir. push ( "miri" ) ;
0 commit comments