]> git.lizzy.rs Git - rust.git/commitdiff
`!(a == b)` --> `a != b`
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Tue, 29 Mar 2016 15:18:47 +0000 (17:18 +0200)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Tue, 29 Mar 2016 15:18:47 +0000 (17:18 +0200)
src/booleans.rs
tests/compile-fail/booleans.rs

index 0cfab9a53571fb56aa0d448257a015438c7b7621..74a10faa070cd16279eb3a884941ab50c6e48553 100644 (file)
@@ -129,18 +129,10 @@ fn run(&mut self, e: &'v Expr) -> Result<Bool, String> {
     }
 }
 
-macro_rules! brackets {
-    ($val:expr => $($name:ident),*) => {
-        match $val {
-            $($name(_) => true,)*
-            _ => false,
-        }
-    }
-}
-
 fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
     fn recurse(brackets: bool, cx: &LateContext, suggestion: &Bool, terminals: &[&Expr], mut s: String) -> String {
         use quine_mc_cluskey::Bool::*;
+        let snip = |e: &Expr| snippet_opt(cx, e.span).expect("don't try to improve booleans created by macros");
         match *suggestion {
             True => {
                 s.push_str("true");
@@ -151,17 +143,59 @@ fn recurse(brackets: bool, cx: &LateContext, suggestion: &Bool, terminals: &[&Ex
                 s
             },
             Not(ref inner) => {
-                s.push('!');
-                recurse(brackets!(**inner => And, Or, Term), cx, inner, terminals, s)
+                match **inner {
+                    And(_) | Or(_) => {
+                        s.push('!');
+                        recurse(true, cx, inner, terminals, s)
+                    },
+                    Term(n) => {
+                        match terminals[n as usize].node {
+                            ExprBinary(binop, ref lhs, ref rhs) => {
+                                let op = match binop.node {
+                                    BiEq => " != ",
+                                    BiNe => " == ",
+                                    BiLt => " >= ",
+                                    BiGt => " <= ",
+                                    BiLe => " > ",
+                                    BiGe => " < ",
+                                    _ => {
+                                        s.push('!');
+                                        return recurse(true, cx, inner, terminals, s)
+                                    },
+                                };
+                                s.push_str(&snip(lhs));
+                                s.push_str(op);
+                                s.push_str(&snip(rhs));
+                                s
+                            },
+                            _ => {
+                                s.push('!');
+                                recurse(false, cx, inner, terminals, s)
+                            },
+                        }
+                    },
+                    _ => {
+                        s.push('!');
+                        recurse(false, cx, inner, terminals, s)
+                    },
+                }
             },
             And(ref v) => {
                 if brackets {
                     s.push('(');
                 }
-                s = recurse(brackets!(v[0] => Or), cx, &v[0], terminals, s);
+                if let Or(_) = v[0] {
+                    s = recurse(true, cx, &v[0], terminals, s);
+                } else {
+                    s = recurse(false, cx, &v[0], terminals, s);
+                }
                 for inner in &v[1..] {
                     s.push_str(" && ");
-                    s = recurse(brackets!(*inner => Or), cx, inner, terminals, s);
+                    if let Or(_) = *inner {
+                        s = recurse(true, cx, inner, terminals, s);
+                    } else {
+                        s = recurse(false, cx, inner, terminals, s);
+                    }
                 }
                 if brackets {
                     s.push(')');
@@ -188,7 +222,7 @@ fn recurse(brackets: bool, cx: &LateContext, suggestion: &Bool, terminals: &[&Ex
                         s.push('(');
                     }
                 }
-                s.push_str(&snippet_opt(cx, terminals[n as usize].span).expect("don't try to improve booleans created by macros"));
+                s.push_str(&snip(&terminals[n as usize]));
                 if brackets {
                     if let ExprBinary(..) = terminals[n as usize].node {
                         s.push(')');
index f4760a6fd46566627106a3cb89f6735fd5bab475..aba55f0b8b486f3dc73edf5aae1075a6030e1016 100644 (file)
@@ -66,7 +66,7 @@ fn equality_stuff() {
     //~| HELP for further information visit
     //~| SUGGESTION let _ = a == b && c == 5;
     //~| HELP try
-    //~| SUGGESTION let _ = !(!(c == 5) || !(a == b));
+    //~| SUGGESTION let _ = !(c != 5 || a != b);
     let _ = a < b && a >= b; //~ ERROR this boolean expression contains a logic bug
     //~| HELP for further information visit
     //~| HELP this expression can be optimized out
@@ -81,7 +81,7 @@ fn equality_stuff() {
 
     let _ = a != b || !(a != b || c == d); //~ ERROR this boolean expression can be simplified
     //~| HELP for further information visit
-    //~| SUGGESTION let _ = !(c == d) || a != b;
+    //~| SUGGESTION let _ = c != d || a != b;
     //~| HELP try
-    //~| SUGGESTION let _ = !(!(a != b) && c == d);
+    //~| SUGGESTION let _ = !(a == b && c == d);
 }