fix(xatu): count bindings in empty let expressions

This commit is contained in:
2026-09-19 18:21:01 -04:00
parent acf9ef726f
commit 309c3689ee
5 changed files with 11 additions and 7 deletions

View File

@@ -96,6 +96,8 @@
- `rules_rust` `rust_test` targets cannot set both `crate` and `srcs`.
Use one input style per test target.
- Rust tests in this monorepo live in separate `*_test.rs` files, not inline `#[cfg(test)]` modules.
- `rnix::ast::HasEntry::entries()` includes assignments and `inherit` statements.
Use `attrpath_values()` when code needs only assignment entries.
- Ariadne Rust tests are declared in Bazel `BUILD` files; do not add `[[test]]` entries to
`src/ariadne/Cargo.toml` unless explicitly requested.
- In this monorepo, "dotfiles" refers to the dotfiles/NixOS configuration under `src/dotfiles/` and `configs/nixos/`.

View File

@@ -57,8 +57,7 @@ pub struct Select {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LetIn {
pub entry_count: usize,
pub inherit_count: usize,
pub binding_count: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]

View File

@@ -117,8 +117,11 @@ impl From<rnix::ast::LetIn> for ast::LetIn {
use rnix::ast::HasEntry;
Self {
entry_count: let_in.entries().count(),
inherit_count: let_in.inherits().count(),
binding_count: let_in.attrpath_values().count()
+ let_in
.inherits()
.map(|inherit| inherit.attrs().count())
.sum::<usize>(),
}
}
}

View File

@@ -15,7 +15,7 @@ impl NodeRule for EmptyLetIn {
}
fn check(node: &Self::Node) -> Option<&'static str> {
if node.entry_count == 0 && node.inherit_count == 0 {
if node.binding_count == 0 {
Some("let expression has no bindings")
} else {
None

View File

@@ -145,7 +145,7 @@ fn xatu_reports_commented_empty_let_in() -> googletest::Result<()> {
}
#[gtest]
fn empty_inherit_prevents_empty_let_in_finding() -> googletest::Result<()> {
fn xatu_reports_empty_let_with_empty_inherit() -> googletest::Result<()> {
let report =
xatu::future_sight(vec![fixture_source("testdata/lint_interactions.nix")?]).or_fail()?;
@@ -154,7 +154,7 @@ fn empty_inherit_prevents_empty_let_in_finding() -> googletest::Result<()> {
.iter()
.map(|diagnostic| diagnostic.finding.rule_id)
.collect::<Vec<_>>();
expect_that!(findings, eq(&vec!["empty_inherit"]));
expect_that!(findings, eq(&vec!["empty_let_in", "empty_inherit"]));
Ok(())
}