Skip to content

Commit 3bd891d

Browse files
committed
Auto merge of #14389 - weihanglo:rustdoc, r=epage
feat(trim-paths): rustdoc supports trim-paths for diagnostics
2 parents 7ac34d3 + b8a3dbe commit 3bd891d

File tree

2 files changed

+182
-61
lines changed

2 files changed

+182
-61
lines changed

src/cargo/core/compiler/mod.rs

Lines changed: 95 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ use crate::util::{add_path_args, internal};
9797
use cargo_util::{paths, ProcessBuilder, ProcessError};
9898
use cargo_util_schemas::manifest::TomlDebugInfo;
9999
use cargo_util_schemas::manifest::TomlTrimPaths;
100+
use cargo_util_schemas::manifest::TomlTrimPathsValue;
100101
use rustfix::diagnostics::Applicability;
101102

102103
const RUSTDOC_CRATE_VERSION_FLAG: &str = "--crate-version";
@@ -737,6 +738,10 @@ fn prepare_rustdoc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResu
737738
add_error_format_and_color(build_runner, &mut rustdoc);
738739
add_allow_features(build_runner, &mut rustdoc);
739740

741+
if let Some(trim_paths) = unit.profile.trim_paths.as_ref() {
742+
trim_paths_args_rustdoc(&mut rustdoc, build_runner, unit, trim_paths)?;
743+
}
744+
740745
rustdoc.args(unit.pkg.manifest().lint_rustflags());
741746
if let Some(args) = build_runner.bcx.extra_args_for(unit) {
742747
rustdoc.args(args);
@@ -1223,6 +1228,32 @@ fn features_args(unit: &Unit) -> Vec<OsString> {
12231228
args
12241229
}
12251230

1231+
/// Like [`trim_paths_args`] but for rustdoc invocations.
1232+
fn trim_paths_args_rustdoc(
1233+
cmd: &mut ProcessBuilder,
1234+
build_runner: &BuildRunner<'_, '_>,
1235+
unit: &Unit,
1236+
trim_paths: &TomlTrimPaths,
1237+
) -> CargoResult<()> {
1238+
match trim_paths {
1239+
// rustdoc supports diagnostics trimming only.
1240+
TomlTrimPaths::Values(values) if !values.contains(&TomlTrimPathsValue::Diagnostics) => {
1241+
return Ok(())
1242+
}
1243+
_ => {}
1244+
}
1245+
1246+
// feature gate was checked during manifest/config parsing.
1247+
cmd.arg("-Zunstable-options");
1248+
1249+
// Order of `--remap-path-prefix` flags is important for `-Zbuild-std`.
1250+
// We want to show `/rustc/<hash>/library/std` instead of `std-0.0.0`.
1251+
cmd.arg(package_remap(build_runner, unit));
1252+
cmd.arg(sysroot_remap(build_runner, unit));
1253+
1254+
Ok(())
1255+
}
1256+
12261257
/// Generates the `--remap-path-scope` and `--remap-path-prefix` for [RFC 3127].
12271258
/// See also unstable feature [`-Ztrim-paths`].
12281259
///
@@ -1242,73 +1273,76 @@ fn trim_paths_args(
12421273
cmd.arg("-Zunstable-options");
12431274
cmd.arg(format!("-Zremap-path-scope={trim_paths}"));
12441275

1245-
let sysroot_remap = {
1246-
let sysroot = &build_runner.bcx.target_data.info(unit.kind).sysroot;
1247-
let mut remap = OsString::from("--remap-path-prefix=");
1248-
remap.push(sysroot);
1249-
remap.push("/lib/rustlib/src/rust"); // See also `detect_sysroot_src_path()`.
1250-
remap.push("=");
1251-
remap.push("/rustc/");
1252-
// This remap logic aligns with rustc:
1253-
// <https://github.com/rust-lang/rust/blob/c2ef3516/src/bootstrap/src/lib.rs#L1113-L1116>
1254-
if let Some(commit_hash) = build_runner.bcx.rustc().commit_hash.as_ref() {
1255-
remap.push(commit_hash);
1256-
} else {
1257-
remap.push(build_runner.bcx.rustc().version.to_string());
1258-
}
1259-
remap
1260-
};
1261-
let package_remap = {
1262-
let pkg_root = unit.pkg.root();
1263-
let ws_root = build_runner.bcx.ws.root();
1264-
let mut remap = OsString::from("--remap-path-prefix=");
1265-
// Remap rules for dependencies
1266-
//
1267-
// * Git dependencies: remove ~/.cargo/git/checkouts prefix.
1268-
// * Registry dependencies: remove ~/.cargo/registry/src prefix.
1269-
// * Others (e.g. path dependencies):
1270-
// * relative paths to workspace root if inside the workspace directory.
1271-
// * otherwise remapped to `<pkg>-<version>`.
1272-
let source_id = unit.pkg.package_id().source_id();
1273-
if source_id.is_git() {
1274-
remap.push(
1275-
build_runner
1276-
.bcx
1277-
.gctx
1278-
.git_checkouts_path()
1279-
.as_path_unlocked(),
1280-
);
1281-
remap.push("=");
1282-
} else if source_id.is_registry() {
1283-
remap.push(
1284-
build_runner
1285-
.bcx
1286-
.gctx
1287-
.registry_source_path()
1288-
.as_path_unlocked(),
1289-
);
1290-
remap.push("=");
1291-
} else if pkg_root.strip_prefix(ws_root).is_ok() {
1292-
remap.push(ws_root);
1293-
remap.push("=."); // remap to relative rustc work dir explicitly
1294-
} else {
1295-
remap.push(pkg_root);
1296-
remap.push("=");
1297-
remap.push(unit.pkg.name());
1298-
remap.push("-");
1299-
remap.push(unit.pkg.version().to_string());
1300-
}
1301-
remap
1302-
};
1303-
13041276
// Order of `--remap-path-prefix` flags is important for `-Zbuild-std`.
13051277
// We want to show `/rustc/<hash>/library/std` instead of `std-0.0.0`.
1306-
cmd.arg(package_remap);
1307-
cmd.arg(sysroot_remap);
1278+
cmd.arg(package_remap(build_runner, unit));
1279+
cmd.arg(sysroot_remap(build_runner, unit));
13081280

13091281
Ok(())
13101282
}
13111283

1284+
/// Path prefix remap rules for sysroot.
1285+
///
1286+
/// This remap logic aligns with rustc:
1287+
/// <https://github.com/rust-lang/rust/blob/c2ef3516/src/bootstrap/src/lib.rs#L1113-L1116>
1288+
fn sysroot_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> OsString {
1289+
let sysroot = &build_runner.bcx.target_data.info(unit.kind).sysroot;
1290+
let mut remap = OsString::from("--remap-path-prefix=");
1291+
remap.push(sysroot);
1292+
remap.push("/lib/rustlib/src/rust"); // See also `detect_sysroot_src_path()`.
1293+
remap.push("=");
1294+
remap.push("/rustc/");
1295+
if let Some(commit_hash) = build_runner.bcx.rustc().commit_hash.as_ref() {
1296+
remap.push(commit_hash);
1297+
} else {
1298+
remap.push(build_runner.bcx.rustc().version.to_string());
1299+
}
1300+
remap
1301+
}
1302+
1303+
/// Path prefix remap rules for dependencies.
1304+
///
1305+
/// * Git dependencies: remove `~/.cargo/git/checkouts` prefix.
1306+
/// * Registry dependencies: remove `~/.cargo/registry/src` prefix.
1307+
/// * Others (e.g. path dependencies):
1308+
/// * relative paths to workspace root if inside the workspace directory.
1309+
/// * otherwise remapped to `<pkg>-<version>`.
1310+
fn package_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> OsString {
1311+
let pkg_root = unit.pkg.root();
1312+
let ws_root = build_runner.bcx.ws.root();
1313+
let mut remap = OsString::from("--remap-path-prefix=");
1314+
let source_id = unit.pkg.package_id().source_id();
1315+
if source_id.is_git() {
1316+
remap.push(
1317+
build_runner
1318+
.bcx
1319+
.gctx
1320+
.git_checkouts_path()
1321+
.as_path_unlocked(),
1322+
);
1323+
remap.push("=");
1324+
} else if source_id.is_registry() {
1325+
remap.push(
1326+
build_runner
1327+
.bcx
1328+
.gctx
1329+
.registry_source_path()
1330+
.as_path_unlocked(),
1331+
);
1332+
remap.push("=");
1333+
} else if pkg_root.strip_prefix(ws_root).is_ok() {
1334+
remap.push(ws_root);
1335+
remap.push("=."); // remap to relative rustc work dir explicitly
1336+
} else {
1337+
remap.push(pkg_root);
1338+
remap.push("=");
1339+
remap.push(unit.pkg.name());
1340+
remap.push("-");
1341+
remap.push(unit.pkg.version().to_string());
1342+
}
1343+
remap
1344+
}
1345+
13121346
/// Generates the `--check-cfg` arguments for the `unit`.
13131347
fn check_cfg_args(unit: &Unit) -> CargoResult<Vec<OsString>> {
13141348
// The routine below generates the --check-cfg arguments. Our goals here are to

tests/testsuite/profile_trim_paths.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,3 +752,90 @@ Hello, Ferris!
752752
"#]],
753753
);
754754
}
755+
756+
#[cargo_test(nightly, reason = "rustdoc --remap-path-prefix is unstable")]
757+
fn rustdoc_without_diagnostics_scope() {
758+
Package::new("bar", "0.0.1")
759+
.file("Cargo.toml", &basic_manifest("bar", "0.0.1"))
760+
.file(
761+
"src/lib.rs",
762+
r#"
763+
/// </script>
764+
pub struct Bar;
765+
"#,
766+
)
767+
.publish();
768+
let p = project()
769+
.file(
770+
"Cargo.toml",
771+
r#"
772+
[package]
773+
name = "foo"
774+
version = "0.0.1"
775+
edition = "2015"
776+
777+
[dependencies]
778+
bar = "0.0.1"
779+
780+
[profile.dev]
781+
trim-paths = "object"
782+
"#,
783+
)
784+
.file("src/lib.rs", "")
785+
.build();
786+
787+
p.cargo("doc -vv -Ztrim-paths")
788+
.masquerade_as_nightly_cargo(&["-Ztrim-paths"])
789+
.with_stderr_data(str![[r#"
790+
...
791+
[WARNING] unopened HTML tag `script`
792+
--> [ROOT]/home/.cargo/registry/src/-[HASH]/bar-0.0.1/src/lib.rs:2:17
793+
...
794+
"#]])
795+
.run();
796+
}
797+
798+
#[cargo_test(nightly, reason = "rustdoc --remap-path-prefix is unstable")]
799+
fn rustdoc_diagnostics_works() {
800+
// This is expected to work after rust-lang/rust#128736
801+
Package::new("bar", "0.0.1")
802+
.file("Cargo.toml", &basic_manifest("bar", "0.0.1"))
803+
.file(
804+
"src/lib.rs",
805+
r#"
806+
/// </script>
807+
pub struct Bar;
808+
"#,
809+
)
810+
.publish();
811+
let p = project()
812+
.file(
813+
"Cargo.toml",
814+
r#"
815+
[package]
816+
name = "foo"
817+
version = "0.0.1"
818+
edition = "2015"
819+
820+
[dependencies]
821+
bar = "0.0.1"
822+
823+
[profile.dev]
824+
trim-paths = "diagnostics"
825+
"#,
826+
)
827+
.file("src/lib.rs", "")
828+
.build();
829+
830+
p.cargo("doc -vv -Ztrim-paths")
831+
.masquerade_as_nightly_cargo(&["-Ztrim-paths"])
832+
.with_stderr_data(str![[r#"
833+
...
834+
[RUNNING] `[..]rustc [..]-Zremap-path-scope=diagnostics --remap-path-prefix=[ROOT]/home/.cargo/registry/src= --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]`
835+
...
836+
[WARNING] unopened HTML tag `script`
837+
--> -[..]/bar-0.0.1/src/lib.rs:2:17
838+
...
839+
"#]])
840+
.run();
841+
}

0 commit comments

Comments
 (0)