@@ -55,7 +55,7 @@ use crate::util::errors::{self, CargoResult, CargoResultExt, ProcessError, Verbo
5555use crate :: util:: interning:: InternedString ;
5656use crate :: util:: machine_message:: Message ;
5757use crate :: util:: { self , machine_message, ProcessBuilder } ;
58- use crate :: util:: { add_path_args , internal, join_paths, paths, profile} ;
58+ use crate :: util:: { internal, join_paths, paths, profile} ;
5959
6060const RUSTDOC_CRATE_VERSION_FLAG : & str = "--crate-version" ;
6161
@@ -583,7 +583,7 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
583583 let mut rustdoc = cx. compilation . rustdoc_process ( unit) ?;
584584 rustdoc. inherit_jobserver ( & cx. jobserver ) ;
585585 rustdoc. arg ( "--crate-name" ) . arg ( & unit. target . crate_name ( ) ) ;
586- add_path_args ( bcx. ws , unit, & mut rustdoc) ;
586+ add_path_args ( bcx, unit, & mut rustdoc) ;
587587 add_cap_lints ( bcx, unit, & mut rustdoc) ;
588588
589589 if let CompileKind :: Target ( target) = unit. kind {
@@ -669,6 +669,41 @@ fn append_crate_version_flag(unit: &Unit, rustdoc: &mut ProcessBuilder) {
669669 . arg ( unit. pkg . version ( ) . to_string ( ) ) ;
670670}
671671
672+ // The path that we pass to rustc is actually fairly important because it will
673+ // show up in error messages (important for readability), debug information
674+ // (important for caching), etc. As a result we need to be pretty careful how we
675+ // actually invoke rustc.
676+ //
677+ // In general users don't expect `cargo build` to cause rebuilds if you change
678+ // directories. That could be if you just change directories in the package or
679+ // if you literally move the whole package wholesale to a new directory. As a
680+ // result we mostly don't factor in `cwd` to this calculation. Instead we try to
681+ // track the workspace as much as possible and we update the current directory
682+ // of rustc/rustdoc where appropriate.
683+ //
684+ // The first returned value here is the argument to pass to rustc, and the
685+ // second is the cwd that rustc should operate in.
686+ fn path_args ( bcx : & BuildContext < ' _ , ' _ > , unit : & Unit ) -> ( PathBuf , PathBuf ) {
687+ let ws_root = bcx. ws . root ( ) ;
688+ let src = match unit. target . src_path ( ) {
689+ TargetSourcePath :: Path ( path) => path. to_path_buf ( ) ,
690+ TargetSourcePath :: Metabuild => unit. pkg . manifest ( ) . metabuild_path ( bcx. ws . target_dir ( ) ) ,
691+ } ;
692+ assert ! ( src. is_absolute( ) ) ;
693+ if unit. pkg . package_id ( ) . source_id ( ) . is_path ( ) {
694+ if let Ok ( path) = src. strip_prefix ( ws_root) {
695+ return ( path. to_path_buf ( ) , ws_root. to_path_buf ( ) ) ;
696+ }
697+ }
698+ ( src, unit. pkg . root ( ) . to_path_buf ( ) )
699+ }
700+
701+ fn add_path_args ( bcx : & BuildContext < ' _ , ' _ > , unit : & Unit , cmd : & mut ProcessBuilder ) {
702+ let ( arg, cwd) = path_args ( bcx, unit) ;
703+ cmd. arg ( arg) ;
704+ cmd. cwd ( cwd) ;
705+ }
706+
672707fn add_cap_lints ( bcx : & BuildContext < ' _ , ' _ > , unit : & Unit , cmd : & mut ProcessBuilder ) {
673708 // If this is an upstream dep we don't want warnings from, turn off all
674709 // lints.
@@ -763,7 +798,7 @@ fn build_base_args(
763798 cmd. arg ( format ! ( "--edition={}" , edition) ) ;
764799 }
765800
766- add_path_args ( bcx. ws , unit, cmd) ;
801+ add_path_args ( bcx, unit, cmd) ;
767802 add_error_format_and_color ( cx, cmd, cx. rmeta_required ( unit) ) ?;
768803
769804 if !test {
0 commit comments