don't try to reiterate deadness through inherit from clauses

it is too aggressive. to achieve that we'll have check that every attr
is dead.

Fixes Github issue #58
This commit is contained in:
Astro 2023-04-29 02:03:11 +02:00
parent ac71fa6a9c
commit d3ec79ea26
3 changed files with 90 additions and 9 deletions

View File

@ -17,7 +17,9 @@ const PRAGMA_SKIP: &str = "deadnix: skip";
#[derive(Debug, Clone)]
pub struct Binding {
pub name: Ident,
/// syntax node of body depending on declaration
pub body_node: SyntaxNode<NixLanguage>,
/// syntax node of declaration itself
pub decl_node: SyntaxNode<NixLanguage>,
mortal: bool,
}

View File

@ -62,17 +62,19 @@ impl Settings {
continue;
}
// TODO: combine bindinges and bodies so that
// bodies of dead bindings can be marked as dead
if binding.is_mortal()
&& ! scope.bodies().any(|body|
// exclude this binding's own node
body != binding.body_node
body != binding.decl_node
// excluding already unused results
&& dead.get(&body).is_none()
&& ! dead.contains(&body)
// find if used anywhere
&& usage::find(&binding.name, &body)
)
&& ! binding.has_pragma_skip() {
dead.insert(binding.body_node.clone());
dead.insert(binding.decl_node.clone());
results.insert(
binding.decl_node.clone(),
DeadCode {

View File

@ -92,17 +92,22 @@ fn let_in_inherit_dead_multi() {
fn let_in_inherit_dead_recursive_multi() {
let results =
run("let inherit (grave) dead1; inherit (dead1) dead2; inherit (dead2) dead3; in false");
assert_eq!(3, results.len());
assert_eq!(results[0].binding.name.to_string(), "dead1");
assert_eq!(results[1].binding.name.to_string(), "dead2");
assert_eq!(results[2].binding.name.to_string(), "dead3");
assert_eq!(1, results.len());
assert_eq!(results[0].binding.name.to_string(), "dead3");
// assert_eq!(3, results.len());
// assert_eq!(results[0].binding.name.to_string(), "dead1");
// assert_eq!(results[1].binding.name.to_string(), "dead2");
// assert_eq!(results[2].binding.name.to_string(), "dead3");
}
#[test]
fn let_in_inherit_shadowed() {
let results = run("let inherit (dead) dead; in let inherit (alive) dead; in dead");
let nix = "let inherit (dead) x; in let inherit (alive) x; in x";
let results = run(nix);
assert_eq!(1, results.len());
assert_eq!(results[0].binding.name.to_string(), "dead");
assert_eq!(results[0].binding.name.to_string(), "x");
// let first_pos = nix.find("x").unwrap();
// assert_eq!(usize::from(results[0].binding.name.syntax().text_range().start()), first_pos);
}
#[test]
@ -336,4 +341,76 @@ in shadowed
assert_eq!(results[0].binding.name.to_string(), "shadowed");
let first_pos = nix.find("shadowed").unwrap();
assert_eq!(usize::from(results[0].binding.name.syntax().text_range().start()), first_pos);
let first_pos = nix.find("shadowed").unwrap();
assert_eq!(usize::from(results[0].binding.name.syntax().text_range().start()), first_pos);
}
#[test]
fn let_multi() {
let results = run("
let
src = {};
dead = src.dead;
alive = src.alive;
in
alive
");
assert_eq!(1, results.len());
assert_eq!(results[0].binding.name.to_string(), "dead");
}
#[test]
fn let_inherit_multi() {
let results = run("
let
src = {};
inherit (src) dead alive;
in
alive
");
assert_eq!(1, results.len());
assert_eq!(results[0].binding.name.to_string(), "dead");
}
#[test]
fn let_inherit_complex() {
let results = run("
let
src = {};
inherit (get src) dead;
in
alive
");
assert_eq!(1, results.len());
assert_eq!(results[0].binding.name.to_string(), "dead");
// assert_eq!(2, results.len());
// assert_eq!(results[0].binding.name.to_string(), "dead");
// assert_eq!(results[1].binding.name.to_string(), "src");
}
#[test]
fn let_inherit_multi_complex() {
let results = run("
let
get = x: x;
src = {};
inherit (get src) dead alive;
in
alive
");
assert_eq!(1, results.len());
assert_eq!(results[0].binding.name.to_string(), "dead");
}
#[test]
fn let_nested_attrset() {
let results = run("
let
foo.alive = true;
foo.dead = false;
in
foo.alive
");
// No evaluation
assert_eq!(0, results.len());
}