Skip to content

Commit 3c0b534

Browse files
authored
fix(trim-paths)!: limit options to none|object|all (#17432)
### What does this PR try to resolve? This limits profile `trim-paths` options to only `none`, `object`, and `all`. For other scopes and boolean values, we can add it in the future when needed. This is a stabilization preparation for `-Ztrim-paths`. See <#12137 (comment)>. ### How to test and review this PR? Also rewrote the profile trim-paths doc a bit but not extremely satisfied. Please help proofread.
2 parents b1e1089 + e7c7688 commit 3c0b534

10 files changed

Lines changed: 72 additions & 267 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ cargo-platform = { path = "crates/cargo-platform", version = "0.3.3" }
3636
cargo-test-macro = { version = "0.4.15", path = "crates/cargo-test-macro" }
3737
cargo-test-support = { version = "0.12.0", path = "crates/cargo-test-support" }
3838
cargo-util = { version = "0.2.33", path = "crates/cargo-util" }
39-
cargo-util-schemas = { version = "0.14.4", path = "crates/cargo-util-schemas" }
39+
cargo-util-schemas = { version = "0.15.0", path = "crates/cargo-util-schemas" }
4040
cargo-util-terminal = { version = "0.1.3", path = "crates/cargo-util-terminal" }
4141
cargo_metadata = "0.23.1"
4242
clap = "4.6.0"

crates/cargo-util-schemas/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cargo-util-schemas"
3-
version = "0.14.4"
3+
version = "0.15.0"
44
rust-version = "1.98" # MSRV:1
55
edition.workspace = true
66
license.workspace = true

crates/cargo-util-schemas/manifest.schema.json

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,11 @@
14731473
"type": "string"
14741474
},
14751475
"TomlDebugInfo": {
1476-
"type": ["string", "integer", "boolean"],
1476+
"type": [
1477+
"string",
1478+
"integer",
1479+
"boolean"
1480+
],
14771481
"enum": [
14781482
"none",
14791483
"line-directives-only",
@@ -1491,24 +1495,11 @@
14911495
"type": "string"
14921496
},
14931497
"TomlTrimPaths": {
1494-
"anyOf": [
1495-
{
1496-
"type": "array",
1497-
"items": {
1498-
"$ref": "#/$defs/TomlTrimPathsValue"
1499-
}
1500-
},
1501-
{
1502-
"type": "null"
1503-
}
1504-
]
1505-
},
1506-
"TomlTrimPathsValue": {
15071498
"type": "string",
15081499
"enum": [
1509-
"diagnostics",
1510-
"macro",
1511-
"object"
1500+
"none",
1501+
"object",
1502+
"all"
15121503
]
15131504
}
15141505
}

crates/cargo-util-schemas/src/manifest/mod.rs

Lines changed: 10 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,119 +1233,30 @@ impl<'de> de::Deserialize<'de> for TomlDebugInfo {
12331233
}
12341234
}
12351235

1236-
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize)]
1237-
#[serde(untagged, rename_all = "kebab-case")]
1236+
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
1237+
#[serde(rename_all = "kebab-case")]
12381238
#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))]
12391239
pub enum TomlTrimPaths {
1240-
Values(Vec<TomlTrimPathsValue>),
1240+
None,
1241+
Object,
12411242
All,
12421243
}
12431244

12441245
impl TomlTrimPaths {
1245-
pub fn none() -> Self {
1246-
TomlTrimPaths::Values(Vec::new())
1247-
}
1248-
12491246
pub fn is_none(&self) -> bool {
1250-
match self {
1251-
TomlTrimPaths::Values(v) => v.is_empty(),
1252-
TomlTrimPaths::All => false,
1253-
}
1247+
matches!(self, TomlTrimPaths::None)
12541248
}
1255-
}
12561249

1257-
impl<'de> de::Deserialize<'de> for TomlTrimPaths {
1258-
fn deserialize<D>(d: D) -> Result<TomlTrimPaths, D::Error>
1259-
where
1260-
D: de::Deserializer<'de>,
1261-
{
1262-
use serde::de::Error as _;
1263-
let expecting = r#"a boolean, "none", "diagnostics", "macro", "object", "all", or an array with these options"#;
1264-
UntaggedEnumVisitor::new()
1265-
.expecting(expecting)
1266-
.bool(|value| {
1267-
Ok(if value {
1268-
TomlTrimPaths::All
1269-
} else {
1270-
TomlTrimPaths::none()
1271-
})
1272-
})
1273-
.string(|v| match v {
1274-
"none" => Ok(TomlTrimPaths::none()),
1275-
"all" => Ok(TomlTrimPaths::All),
1276-
v => {
1277-
let d = v.into_deserializer();
1278-
let err = |_: D::Error| {
1279-
serde_untagged::de::Error::custom(format!("expected {expecting}"))
1280-
};
1281-
TomlTrimPathsValue::deserialize(d)
1282-
.map_err(err)
1283-
.map(|v| v.into())
1284-
}
1285-
})
1286-
.seq(|seq| {
1287-
let seq: Vec<String> = seq.deserialize()?;
1288-
let seq: Vec<_> = seq
1289-
.into_iter()
1290-
.map(|s| TomlTrimPathsValue::deserialize(s.into_deserializer()))
1291-
.collect::<Result<_, _>>()?;
1292-
Ok(seq.into())
1293-
})
1294-
.deserialize(d)
1295-
}
1296-
}
1297-
1298-
impl fmt::Display for TomlTrimPaths {
1299-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1250+
fn as_str(&self) -> &'static str {
13001251
match self {
1301-
TomlTrimPaths::All => write!(f, "all"),
1302-
TomlTrimPaths::Values(v) if v.is_empty() => write!(f, "none"),
1303-
TomlTrimPaths::Values(v) => {
1304-
let mut iter = v.iter();
1305-
if let Some(value) = iter.next() {
1306-
write!(f, "{value}")?;
1307-
}
1308-
for value in iter {
1309-
write!(f, ",{value}")?;
1310-
}
1311-
Ok(())
1312-
}
1252+
TomlTrimPaths::None => "none",
1253+
TomlTrimPaths::Object => "object",
1254+
TomlTrimPaths::All => "all",
13131255
}
13141256
}
13151257
}
13161258

1317-
impl From<TomlTrimPathsValue> for TomlTrimPaths {
1318-
fn from(value: TomlTrimPathsValue) -> Self {
1319-
TomlTrimPaths::Values(vec![value])
1320-
}
1321-
}
1322-
1323-
impl From<Vec<TomlTrimPathsValue>> for TomlTrimPaths {
1324-
fn from(value: Vec<TomlTrimPathsValue>) -> Self {
1325-
TomlTrimPaths::Values(value)
1326-
}
1327-
}
1328-
1329-
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
1330-
#[serde(rename_all = "kebab-case")]
1331-
#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))]
1332-
pub enum TomlTrimPathsValue {
1333-
Diagnostics,
1334-
Macro,
1335-
Object,
1336-
}
1337-
1338-
impl TomlTrimPathsValue {
1339-
pub fn as_str(&self) -> &'static str {
1340-
match self {
1341-
TomlTrimPathsValue::Diagnostics => "diagnostics",
1342-
TomlTrimPathsValue::Macro => "macro",
1343-
TomlTrimPathsValue::Object => "object",
1344-
}
1345-
}
1346-
}
1347-
1348-
impl fmt::Display for TomlTrimPathsValue {
1259+
impl fmt::Display for TomlTrimPaths {
13491260
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13501261
write!(f, "{}", self.as_str())
13511262
}

doc/book/src/reference/unstable.md

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ cargo-features = ["trim-paths"]
14941494
# ...
14951495

14961496
[profile.release]
1497-
trim-paths = ["diagnostics", "object"]
1497+
trim-paths = "object"
14981498
```
14991499

15001500
To set this in a profile in Cargo configuration,
@@ -1507,7 +1507,7 @@ For example,
15071507
trim-paths = true
15081508

15091509
[profile.release]
1510-
trim-paths = ["diagnostics", "object"]
1510+
trim-paths = "object"
15111511
```
15121512

15131513
### Documentation updates
@@ -1516,17 +1516,27 @@ trim-paths = ["diagnostics", "object"]
15161516

15171517
*as a new ["Profiles settings" entry](./profiles.html#profile-settings)*
15181518

1519-
`trim-paths` is a profile setting which enables and controls the sanitization of file paths in build outputs.
1520-
It takes the following values:
1519+
The `trim-paths` option controls the scope of path sanitization in build outputs
1520+
Paths are sanitized according to these [remapping rules].
15211521

1522-
- `"none"` and `false` --- disable path sanitization
1523-
- `"macro"` --- sanitize paths in the expansion of `std::file!()` macro.
1524-
This is where paths in embedded panic messages come from
1525-
- `"diagnostics"` --- sanitize paths in printed compiler diagnostics
1526-
- `"object"` --- sanitize paths in compiled executables or libraries
1527-
- `"all"` and `true` --- sanitize paths in all possible locations
1522+
The valid options are:
15281523

1529-
It also takes an array with the combinations of `"macro"`, `"diagnostics"`, and `"object"`.
1524+
- `"none"` --- disables path sanitization.
1525+
- `"object"` --- sanitizes paths embedded in compiled executables and libraries.
1526+
Useful for improving artifact reproducibility
1527+
with less impact on local development.
1528+
- `"all"` --- sanitizes paths in all supported locations.
1529+
Useful for hermetic or remote builds that need artifacts and diagnostics
1530+
to be independent of the build environment.
1531+
1532+
> [!WARNING]
1533+
> The `"all"` option remaps compiler diagnostics,
1534+
> including [compiler JSON messages](./external-tools.md#json-messages).
1535+
> Some remapped paths may not resolve to files on the local filesystem,
1536+
> which can affect editors and other tools that consume the diagnostic output.
1537+
1538+
For details about each scope,
1539+
see rustc's [`--remap-path-scope`] documentation.
15301540

15311541
By default, `trim-paths` is not set and path sanitization is disabled for all profiles.
15321542
You can enable it by specifying this option in `Cargo.toml`:
@@ -1536,13 +1546,11 @@ You can enable it by specifying this option in `Cargo.toml`:
15361546
trim-paths = "all"
15371547

15381548
[profile.release]
1539-
trim-paths = ["object", "diagnostics"]
1549+
trim-paths = "object"
15401550
```
15411551

1542-
For more information about each scope,
1543-
see rustc's documentation on [`--remap-path-scope`].
1544-
15451552
[`--remap-path-scope`]: ../../rustc/remap-source-paths.html#--remap-path-scope
1553+
[remapping rules]: #remapping-rules
15461554

15471555
##### Remapping rules
15481556

@@ -1552,7 +1560,7 @@ should consume [unremap files] instead of interpreting these prefixes.
15521560

15531561
[unremap files]: #unremap-files
15541562

1555-
If `trim-paths` is not `"none"` or `false`,
1563+
If `trim-paths` is not `"none"`,
15561564
then the following paths are sanitized if they appear in a selected scope:
15571565

15581566
1. Path to the source files of the standard and core library (sysroot) will begin with `/rustc/<rustc commit hash>`,
@@ -1657,13 +1665,13 @@ but it still contains absolute paths.
16571665
*as a new entry of ["Environment variables Cargo sets for build scripts"](./environment-variables.md#environment-variables-cargo-sets-for-crates)*
16581666

16591667
* `CARGO_TRIM_PATHS_SCOPE` --- The value of `trim-paths` profile option.
1660-
`false`, `"none"`, and empty arrays would be converted to `none`.
1661-
`true` and `"all"` become `all`.
1662-
Values in a non-empty array would be joined into a comma-separated list.
16631668
If the build script introduces absolute paths to built artifacts (such as by invoking a compiler),
16641669
the user may request them to be sanitized in different types of artifacts.
16651670
Common paths requiring sanitization include `OUT_DIR`, `CARGO_MANIFEST_DIR` and `CARGO_MANIFEST_PATH`,
16661671
plus any other introduced by the build script, such as include directories.
1672+
> [!NOTE]
1673+
> For forward compatibility,
1674+
> build scripts should accept a comma-separated list of scopes.
16671675
* `CARGO_TRIM_PATHS_REMAP` --- The `<from>=<to>` path remap pairs Cargo passes to the compiler,
16681676
joined by the platform path separator.
16691677
Only set when `trim-paths` profile is active.

src/compiler/trim_paths.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use std::path::PathBuf;
1111

1212
use cargo_util::ProcessBuilder;
1313
use cargo_util_schemas::manifest::TomlTrimPaths;
14-
use cargo_util_schemas::manifest::TomlTrimPathsValue;
1514
use serde::Serialize;
1615
use tracing::debug;
1716

@@ -44,12 +43,9 @@ pub(crate) fn trim_paths_args_rustdoc(
4443
unit: &Unit,
4544
trim_paths: &TomlTrimPaths,
4645
) -> CargoResult<()> {
47-
match trim_paths {
48-
// rustdoc supports diagnostics trimming only.
49-
TomlTrimPaths::Values(values) if !values.contains(&TomlTrimPathsValue::Diagnostics) => {
50-
return Ok(());
51-
}
52-
_ => {}
46+
// rustdoc supports diagnostics trimming only.
47+
if !matches!(trim_paths, TomlTrimPaths::All) {
48+
return Ok(());
5349
}
5450

5551
for pair in trim_paths_remap(build_runner, unit) {
@@ -298,8 +294,8 @@ pub(crate) fn should_emit_unremap_file(unit: &Unit) -> bool {
298294

299295
match unit.profile.trim_paths.as_ref() {
300296
None => false,
301-
Some(TomlTrimPaths::All) => true,
302-
Some(TomlTrimPaths::Values(values)) => values.contains(&TomlTrimPathsValue::Object),
297+
Some(TomlTrimPaths::None) => false,
298+
Some(TomlTrimPaths::Object | TomlTrimPaths::All) => true,
303299
}
304300
}
305301

tests/testsuite/bad_config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3268,7 +3268,7 @@ fn bad_trim_paths() {
32683268
.masquerade_as_nightly_cargo(&["trim-paths"])
32693269
.with_status(101)
32703270
.with_stderr_data(str![[r#"
3271-
[ERROR] expected a boolean, "none", "diagnostics", "macro", "object", "all", or an array with these options
3271+
[ERROR] unknown variant `split-debuginfo`, expected one of `none`, `object`, `all`
32723272
--> Cargo.toml:8:30
32733273
|
32743274
8 | trim-paths = "split-debuginfo"

tests/testsuite/config.rs

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use cargo_test_support::compare::assert_e2e;
1919
use cargo_test_support::str;
2020
use cargo_test_support::{paths, project, project_in_home, symlink_supported, t};
2121
use cargo_util_schemas::manifest::TomlTrimPaths;
22-
use cargo_util_schemas::manifest::TomlTrimPathsValue;
2322
use cargo_util_schemas::manifest::{self as cargo_toml, TomlDebugInfo, VecStringOrBool as VSOB};
2423
use cargo_util_terminal::Shell;
2524
use serde::Deserialize;
@@ -1872,9 +1871,9 @@ fn trim_paths_parsing() {
18721871
assert_eq!(p.trim_paths, None);
18731872

18741873
let test_cases = [
1875-
(TomlTrimPathsValue::Diagnostics.into(), "diagnostics"),
1876-
(TomlTrimPathsValue::Macro.into(), "macro"),
1877-
(TomlTrimPathsValue::Object.into(), "object"),
1874+
(TomlTrimPaths::None, "none"),
1875+
(TomlTrimPaths::Object, "object"),
1876+
(TomlTrimPaths::All, "all"),
18781877
];
18791878
for (expected, val) in test_cases {
18801879
// env
@@ -1891,38 +1890,6 @@ fn trim_paths_parsing() {
18911890
let trim_paths: TomlTrimPaths = gctx.get("profile.dev.trim-paths").unwrap();
18921891
assert_eq!(trim_paths, expected, "failed to parse {val}");
18931892
}
1894-
1895-
let test_cases = [(TomlTrimPaths::none(), false), (TomlTrimPaths::All, true)];
1896-
1897-
for (expected, val) in test_cases {
1898-
// env
1899-
let gctx = GlobalContextBuilder::new()
1900-
.env("CARGO_PROFILE_DEV_TRIM_PATHS", format!("{val}"))
1901-
.build();
1902-
let trim_paths: TomlTrimPaths = gctx.get("profile.dev.trim-paths").unwrap();
1903-
assert_eq!(trim_paths, expected, "failed to parse {val}");
1904-
1905-
// config.toml
1906-
let gctx = GlobalContextBuilder::new()
1907-
.config_arg(format!("profile.dev.trim-paths={val}"))
1908-
.build();
1909-
let trim_paths: TomlTrimPaths = gctx.get("profile.dev.trim-paths").unwrap();
1910-
assert_eq!(trim_paths, expected, "failed to parse {val}");
1911-
}
1912-
1913-
let expected = vec![
1914-
TomlTrimPathsValue::Diagnostics,
1915-
TomlTrimPathsValue::Macro,
1916-
TomlTrimPathsValue::Object,
1917-
]
1918-
.into();
1919-
let val = r#"["diagnostics", "macro", "object"]"#;
1920-
// config.toml
1921-
let gctx = GlobalContextBuilder::new()
1922-
.config_arg(format!("profile.dev.trim-paths={val}"))
1923-
.build();
1924-
let trim_paths: TomlTrimPaths = gctx.get("profile.dev.trim-paths").unwrap();
1925-
assert_eq!(trim_paths, expected, "failed to parse {val}");
19261893
}
19271894

19281895
#[cargo_test]

0 commit comments

Comments
 (0)