about summary refs log tree commit diff
path: root/tvix/eval/src
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2023-01-05T13·16+0300
committertazjin <tazjin@tvl.su>2023-01-06T12·23+0000
commit87c80895cd7eb9fa7c09a343352f16b471f57fce (patch)
tree0fbff9ba4159ca964c3a1ab8dd842f960a73c633 /tvix/eval/src
parentaadf71a6ed18855a1fa8b4d5a76508300f463966 (diff)
feat(tvix/eval): skip & warn for useless parenthesis r/5607
Change-Id: I567ca0682012b9d09f1217e57a104ac5671f8d82
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7771
Tested-by: BuildkiteCI
Reviewed-by: raitobezarius <tvl@lahfa.xyz>
Reviewed-by: flokli <flokli@flokli.de>
Diffstat (limited to 'tvix/eval/src')
-rw-r--r--tvix/eval/src/compiler/optimiser.rs26
-rw-r--r--tvix/eval/src/warnings.rs6
2 files changed, 32 insertions, 0 deletions
diff --git a/tvix/eval/src/compiler/optimiser.rs b/tvix/eval/src/compiler/optimiser.rs
index 615de32357e6..af0ad2256e68 100644
--- a/tvix/eval/src/compiler/optimiser.rs
+++ b/tvix/eval/src/compiler/optimiser.rs
@@ -9,6 +9,7 @@ use ast::Expr;
 pub(super) fn optimise_expr(c: &mut Compiler, slot: LocalIdx, expr: ast::Expr) -> ast::Expr {
     match expr {
         Expr::BinOp(_) => optimise_bin_op(c, slot, expr),
+        Expr::Paren(_) => optimise_paren(c, expr),
         _ => expr.to_owned(),
     }
 }
@@ -123,3 +124,28 @@ fn optimise_bin_op(c: &mut Compiler, slot: LocalIdx, expr: ast::Expr) -> ast::Ex
 
     expr
 }
+
+/// Detect useless parenthesis around primitive expressions.
+fn optimise_paren(c: &mut Compiler, expr: ast::Expr) -> ast::Expr {
+    if let Expr::Paren(inner) = &expr {
+        let inner = inner.expr().unwrap();
+
+        if let Expr::Paren(_) = &inner {
+            c.emit_warning(&expr, WarningKind::UselessParens);
+            return optimise_paren(c, inner);
+        }
+
+        if let Expr::Literal(_)
+        | Expr::Str(_)
+        | Expr::Select(_)
+        | Expr::List(_)
+        | Expr::AttrSet(_)
+        | Expr::Ident(_) = &inner
+        {
+            c.emit_warning(&expr, WarningKind::UselessParens);
+            return inner;
+        }
+    }
+
+    expr
+}
diff --git a/tvix/eval/src/warnings.rs b/tvix/eval/src/warnings.rs
index cfe5044a8cbe..26efd24d1ed2 100644
--- a/tvix/eval/src/warnings.rs
+++ b/tvix/eval/src/warnings.rs
@@ -17,6 +17,7 @@ pub enum WarningKind {
     DeadCode,
     EmptyInherit,
     EmptyLet,
+    UselessParens,
 
     /// Tvix internal warning for features triggered by users that are
     /// not actually implemented yet, but do not cause runtime failures.
@@ -105,6 +106,10 @@ impl EvalWarning {
                 format!("this `let`-expression contains no bindings")
             }
 
+            WarningKind::UselessParens => {
+                format!("these parenthesis can be removed")
+            }
+
             WarningKind::NotImplemented(what) => {
                 format!("feature not yet implemented in tvix: {}", what)
             }
@@ -125,6 +130,7 @@ impl EvalWarning {
             WarningKind::DeadCode => "W008",
             WarningKind::EmptyInherit => "W009",
             WarningKind::EmptyLet => "W010",
+            WarningKind::UselessParens => "W011",
 
             WarningKind::NotImplemented(_) => "W999",
         }