Skip to content

Commit 405c00d

Browse files
committed
recognize inline Cargo lint tables
1 parent a43ca50 commit 405c00d

7 files changed

Lines changed: 90 additions & 6 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Cargo inline lint tables
2+
3+
## Summary
4+
5+
The Cargo engine now recognizes standard and inline TOML tables as package-local lint-table identities. Exact-empty and required-table requirements therefore match every Cargo-supported table syntax.
6+
7+
## Decisions made
8+
9+
- Kept syntax recognition in the Cargo engine because `[lints.<tool>]` identity is Cargo-specific.
10+
- Reused one predicate for required, forbidden, and exact reconciliation.
11+
- Added direct regressions for required and exact-empty behavior.
12+
13+
## Key files for context
14+
15+
- `packages/file-types/toml/aqc-cargo-toml-engine/src/reconcile/package_lint_tables.rs`
16+
- `packages/file-types/toml/aqc-cargo-toml-engine/tests/package_lint_tables.rs`
17+
- `packages/file-types/toml/aqc-rust-toolchain-toml-engine/tests/behavior.rs`
18+
19+
## Next steps
20+
21+
- Publish `aqc-cargo-toml-engine 0.5.2` and refresh downstream locks.

‎packages/file-types/toml/aqc-cargo-toml-engine/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.

‎packages/file-types/toml/aqc-cargo-toml-engine/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aqc-cargo-toml-engine"
3-
version = "0.5.1"
3+
version = "0.5.2"
44
edition = "2024"
55
license = "MIT OR Apache-2.0"
66
rust-version = "1.85"

‎packages/file-types/toml/aqc-cargo-toml-engine/src/reconcile/package_lint_tables.rs‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ pub(crate) fn apply(
1717
.flat_map(|items| items.iter())
1818
.filter(|(tool, _)| !requirements.required.contains_key(*tool)),
1919
) {
20-
let present = table_ref(doc, "lints")
21-
.is_some_and(|table| table.get(tool).is_some_and(Item::is_table_like));
20+
let present =
21+
table_ref(doc, "lints").is_some_and(|table| table.get(tool).is_some_and(is_lint_table));
2222
if present {
2323
continue;
2424
}
@@ -38,7 +38,7 @@ pub(crate) fn apply(
3838
.map(|table| {
3939
table
4040
.iter()
41-
.filter(|(_, item)| item.is_table_like())
41+
.filter(|(_, item)| is_lint_table(item))
4242
.map(|(key, _)| key.to_owned())
4343
.collect::<Vec<_>>()
4444
})
@@ -87,6 +87,11 @@ pub(crate) fn apply(
8787
}
8888
}
8989

90+
/// Cargo accepts package-local lint groups as standard or inline TOML tables.
91+
fn is_lint_table(item: &Item) -> bool {
92+
item.is_table_like() || item.as_inline_table().is_some()
93+
}
94+
9095
/// Remove one local lint table while preserving the surrounding `[lints]` table.
9196
fn remove_table(doc: &mut DocumentMut, tool: &str) {
9297
if let Some(table) = doc.get_mut("lints").and_then(Item::as_table_like_mut) {

‎packages/file-types/toml/aqc-cargo-toml-engine/tests/package_lint_tables.rs‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ fn required_table_accepts_an_existing_table() {
9595
assert!(findings.is_empty());
9696
}
9797

98+
#[test]
99+
fn required_table_accepts_an_existing_inline_table() {
100+
let findings = cargo_findings_with(
101+
Some(b"[lints]\nrust = { unsafe_code = \"forbid\" }\n"),
102+
vec![(
103+
prov("rust"),
104+
table_requirements(vec![("rust", "need rust")], Vec::new(), None),
105+
)],
106+
);
107+
assert!(findings.is_empty());
108+
}
109+
98110
#[test]
99111
fn forbidden_table_reports_only_the_named_table() {
100112
let findings = cargo_findings_with(
@@ -124,6 +136,20 @@ fn exact_empty_reports_each_local_lint_table_separately() {
124136
assert_eq!(mismatch_count_for_key(&findings, "[lints.clippy]"), 1);
125137
}
126138

139+
#[test]
140+
fn exact_empty_reports_inline_local_lint_tables() {
141+
let findings = cargo_findings_with(
142+
Some(b"[lints]\nrust = { unsafe_code = \"forbid\" }\n"),
143+
vec![(
144+
prov("inherit"),
145+
table_requirements(Vec::new(), Vec::new(), Some((Vec::new(), "use workspace"))),
146+
)],
147+
);
148+
149+
assert_eq!(findings.len(), 1);
150+
assert_eq!(mismatch_count_for_key(&findings, "[lints.rust]"), 1);
151+
}
152+
127153
#[test]
128154
fn exact_nonempty_reports_missing_and_extra_tables() {
129155
let findings = cargo_findings_with(

‎packages/file-types/toml/aqc-rust-toolchain-toml-engine/tests/behavior.rs‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,32 @@ fn reconcile_canonicalizes_components_and_targets() {
233233
);
234234
}
235235

236+
#[test]
237+
fn exact_settings_reports_and_removes_unknown_toolchain_fields() {
238+
let output = reconcile(
239+
"[toolchain]\nchannel = \"stable\"\nfuture-setting = true\n",
240+
RustToolchainTomlRequirements {
241+
channel: Some(ScalarAssertion::Equals(
242+
RustToolchainChannel::stable(),
243+
"channel".to_owned(),
244+
)),
245+
exact_settings: Some("exact settings".to_owned()),
246+
..RustToolchainTomlRequirements::default()
247+
},
248+
);
249+
let expected_bytes = first_bytes(&output);
250+
let expected = String::from_utf8_lossy(&expected_bytes);
251+
252+
assert!(!expected.contains("future-setting"));
253+
assert!(output.findings.iter().any(|finding| {
254+
matches!(
255+
finding,
256+
Finding::Mismatch { key, message, .. }
257+
if key == "toolchain.future-setting" && message == "exact settings"
258+
)
259+
}));
260+
}
261+
236262
fn baseline_req() -> RustToolchainTomlRequirements {
237263
RustToolchainTomlRequirements {
238264
channel: Some(ScalarAssertion::Equals(

‎specs/create-only-init-and-exact-items.spec.json‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@
167167
"verifier": ["builtin:content"],
168168
"files": [
169169
"packages/file-types/toml/aqc-toml-engine-core/Cargo.toml",
170-
"packages/file-types/toml/aqc-cargo-toml-engine/Cargo.toml",
171170
"packages/file-types/toml/aqc-clippy-toml-engine/Cargo.toml",
172171
"packages/file-types/toml/aqc-rustfmt-toml-engine/Cargo.toml",
173172
"packages/file-types/toml/aqc-rust-toolchain-toml-engine/Cargo.toml"
@@ -176,6 +175,13 @@
176175
"required": ["version = \"0.5.1\""],
177176
"forbidden": []
178177
},
178+
{
179+
"verifier": ["builtin:content"],
180+
"files": ["packages/file-types/toml/aqc-cargo-toml-engine/Cargo.toml"],
181+
"reason": "Adversarial fix: Cargo inline lint-table recognition patch release",
182+
"required": ["version = \"0.5.2\""],
183+
"forbidden": []
184+
},
179185
{
180186
"verifier": ["builtin:content"],
181187
"files": ["packages/file-types/text/aqc-text-engine-core/Cargo.toml"],

0 commit comments

Comments
 (0)