diff options
author | Daniel Thwaites <[email protected]> | 2021-10-28 14:46:34 +0100 |
---|---|---|
committer | Akshay <[email protected]> | 2021-10-29 14:14:14 +0100 |
commit | d510714ed5a1eae0f6e5e435e4cff4875b06751d (patch) | |
tree | f5d5d6419aaeda1bf484f784632366ca3aaed23e | |
parent | c3cede18c9440d05385f0a7fd7ae2ef628ce74aa (diff) |
filter out invalid eta-reductions
if the remaining expression after eta-reduction still contains the
removed function argument, eta-reduction is not possible.
-rw-r--r-- | lib/src/lints/eta_reduction.rs | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/lib/src/lints/eta_reduction.rs b/lib/src/lints/eta_reduction.rs index 8c34205..79a5101 100644 --- a/lib/src/lints/eta_reduction.rs +++ b/lib/src/lints/eta_reduction.rs | |||
@@ -3,8 +3,8 @@ use crate::{Lint, Metadata, Report, Rule, Suggestion}; | |||
3 | use if_chain::if_chain; | 3 | use if_chain::if_chain; |
4 | use macros::lint; | 4 | use macros::lint; |
5 | use rnix::{ | 5 | use rnix::{ |
6 | types::{Lambda, Ident, Apply, TypedNode, TokenWrapper}, | 6 | types::{Apply, Ident, Lambda, TokenWrapper, TypedNode}, |
7 | NodeOrToken, SyntaxElement, SyntaxKind, | 7 | NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | #[lint( | 10 | #[lint( |
@@ -32,10 +32,13 @@ impl Rule for EtaReduction { | |||
32 | 32 | ||
33 | if arg.as_str() == value.as_str() ; | 33 | if arg.as_str() == value.as_str() ; |
34 | 34 | ||
35 | if let Some(lambda_node) = body.lambda(); | ||
36 | if !mentions_ident(&arg, &lambda_node); | ||
37 | |||
35 | then { | 38 | then { |
36 | let at = node.text_range(); | 39 | let at = node.text_range(); |
37 | let replacement = body.lambda()?; | 40 | let replacement = body.lambda()?; |
38 | let message = | 41 | let message = |
39 | format!( | 42 | format!( |
40 | "Found eta-reduction: `{}`", | 43 | "Found eta-reduction: `{}`", |
41 | replacement.text().to_string() | 44 | replacement.text().to_string() |
@@ -48,4 +51,10 @@ impl Rule for EtaReduction { | |||
48 | } | 51 | } |
49 | } | 52 | } |
50 | 53 | ||
51 | 54 | fn mentions_ident(ident: &Ident, node: &SyntaxNode) -> bool { | |
55 | if let Some(node_ident) = Ident::cast(node.clone()) { | ||
56 | node_ident.as_str() == ident.as_str() | ||
57 | } else { | ||
58 | node.children().any(|child| mentions_ident(&ident, &child)) | ||
59 | } | ||
60 | } | ||