diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 4ca723a4d..e0e786b3a 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -166,16 +166,26 @@ impl AstNode { { let mut out = Vec::with_capacity(operands.len()); let mut operands = operands.iter(); - // check the first value before `|`, stop evaluate and return directly if it is true. - // push dummy to pass the check of `len() == 2` - if op_type == "|" { - if let Some(value) = operands.next() { - let value = value.evaluate()?; - out.push(value.clone()); - if value_as_bool(&value) { - out.push(String::from("dummy")); - return Ok(out); + + if let Some(value) = operands.next() { + let value = value.evaluate()?; + out.push(value.clone()); + // short-circuit evaluation for `|` and `&` + // push dummy to pass `assert!(values.len() == 2);` + match op_type.as_ref() { + "|" => { + if value_as_bool(&value) { + out.push(String::from("dummy")); + return Ok(out); + } } + "&" => { + if !value_as_bool(&value) { + out.push(String::from("dummy")); + return Ok(out); + } + } + _ => {} } }