diff --git a/ci/run_benchmark.sh b/ci/run_benchmark.sh
index bc7b80809073eeea27868187a099eb5f55b95534..703136dc6a2d8d655072fb85742add7d4e2ade68 100755
--- a/ci/run_benchmark.sh
+++ b/ci/run_benchmark.sh
@@ -30,15 +30,12 @@ for suite in ./target/criterion/*; do
 
     for test in $suite/*/*/change/estimates.json; do
         estimate=$(cat "$test" | jq -r "$JQ_FILTER" -c)
-        case "$estimate" in
-            -*);;
-            *)
-                inner="<failure message=\"Performance Regressed\" type=\"WARNING\">\
-                    Performance regressed by $estimate in $test\
-                </failure>"
-                worse=$((worse+1))
-            ;;
-        esac
+        if echo "$estimate" | grep -Eq '^[0-9]+\.?[0-9]*$'; then
+            inner="<failure message=\"Performance Regressed\" type=\"WARNING\">\
+                Performance regressed by $estimate in $test\
+            </failure>"
+            worse=$((worse+1))
+        fi
         testcases="$testcases<testcase id=\"$(echo "$test" | cut -d'/' -f 6)\" name=\"$(echo "$test" | cut -d'/' -f 6)\">$inner</testcase>"
         tests=$((tests+1))
     done
diff --git a/src/lib/parser/shell_expand/mod.rs b/src/lib/parser/shell_expand/mod.rs
index 7370379a4c5c186d8ee1cfff7bb25e726ac9aae9..97a177469494bee37612d1ea03e756f6c53e791a 100644
--- a/src/lib/parser/shell_expand/mod.rs
+++ b/src/lib/parser/shell_expand/mod.rs
@@ -56,7 +56,7 @@ pub(crate) trait Expander: Sized {
 fn expand_process<E: Expander>(
     current: &mut small::String,
     command: &str,
-    selection: Select,
+    selection: &Select,
     expander: &E,
     quoted: bool,
 ) {
@@ -66,7 +66,7 @@ fn expand_process<E: Expander>(
         } else if quoted {
             let output: &str =
                 if let Some(pos) = output.rfind(|x| x != '\n') { &output[..=pos] } else { &output };
-            slice(current, output, selection)
+            slice(current, output, &selection)
         } else {
             // The following code should produce the same result as
             // slice(current,
@@ -107,7 +107,7 @@ fn expand_process<E: Expander>(
                 slice(
                     current,
                     str::from_utf8_unchecked(&bytes[..left_mut_pos]).trim_end(),
-                    selection,
+                    &selection,
                 );
                 // `output` is not a valid utf8 string now.
                 // We drop it here to prevent accidental usage afterward.
@@ -130,11 +130,7 @@ fn expand_brace<E: Expander>(
         nodes.iter().flat_map(|node| expand_string_no_glob(node, expand_func, reverse_quoting))
     {
         match parse_range(&word) {
-            Some(elements) => {
-                for word in elements {
-                    temp.push(word)
-                }
-            }
+            Some(elements) => temp.extend(elements),
             None => temp.push(word),
         }
     }
@@ -153,13 +149,13 @@ fn expand_brace<E: Expander>(
 fn array_expand<E: Expander>(
     elements: &[&str],
     expand_func: &E,
-    selection: Select,
+    selection: &Select,
 ) -> types::Array {
     match selection {
         Select::None => types::Array::new(),
         Select::All => elements.iter().flat_map(|e| expand_string(e, expand_func, false)).collect(),
-        Select::Index(index) => array_nth(elements, expand_func, index).into_iter().collect(),
-        Select::Range(range) => array_range(elements, expand_func, range),
+        Select::Index(index) => array_nth(elements, expand_func, *index).into_iter().collect(),
+        Select::Range(range) => array_range(elements, expand_func, *range),
         Select::Key(_) => types::Array::new(),
     }
 }
@@ -177,27 +173,26 @@ fn array_range<E: Expander>(elements: &[&str], expand_func: &E, range: Range) ->
         .iter()
         .flat_map(|e| expand_string(e, expand_func, false))
         .collect::<types::Array>();
-    let len = expanded.len();
-    if let Some((start, length)) = range.bounds(len) {
+    if let Some((start, length)) = range.bounds(expanded.len()) {
         expanded.into_iter().skip(start).take(length).collect()
     } else {
         types::Array::new()
     }
 }
 
-fn slice<S: AsRef<str>>(output: &mut small::String, expanded: S, selection: Select) {
+fn slice<S: AsRef<str>>(output: &mut small::String, expanded: S, selection: &Select) {
     match selection {
-        Select::None => (),
         Select::All => output.push_str(expanded.as_ref()),
         Select::Index(Index::Forward(id)) => {
-            if let Some(character) = UnicodeSegmentation::graphemes(expanded.as_ref(), true).nth(id)
+            if let Some(character) =
+                UnicodeSegmentation::graphemes(expanded.as_ref(), true).nth(*id)
             {
                 output.push_str(character);
             }
         }
         Select::Index(Index::Backward(id)) => {
             if let Some(character) =
-                UnicodeSegmentation::graphemes(expanded.as_ref(), true).rev().nth(id)
+                UnicodeSegmentation::graphemes(expanded.as_ref(), true).rev().nth(*id)
             {
                 output.push_str(character);
             }
@@ -209,7 +204,7 @@ fn slice<S: AsRef<str>>(output: &mut small::String, expanded: S, selection: Sele
                 output.push_str(&substring);
             }
         }
-        Select::Key(_) => (),
+        Select::Key(_) | Select::None => (),
     }
 }
 
@@ -223,54 +218,44 @@ pub(crate) fn expand_string<E: Expander>(
 ) -> types::Array {
     let mut token_buffer = Vec::new();
     let mut contains_brace = false;
-    let mut word_iterator = WordIterator::new(original, expand_func, true);
-
-    loop {
-        match word_iterator.next() {
-            Some(word) => {
-                match word {
-                    WordToken::Brace(_) => {
-                        contains_brace = true;
-                        token_buffer.push(word);
-                    }
-                    WordToken::ArrayVariable(data, contains_quote, selection) => {
-                        if let Select::Key(key) = selection {
-                            if key.contains(' ') {
-                                for index in key.split(' ') {
-                                    let select = index.parse::<Select>().unwrap_or(Select::None);
-                                    token_buffer.push(WordToken::ArrayVariable(
-                                        data,
-                                        contains_quote,
-                                        select,
-                                    ));
-                                    token_buffer.push(WordToken::Whitespace(" "));
-                                }
-                                token_buffer.pop(); // Pop out the last unneeded whitespace token
-                            } else {
-                                token_buffer.push(WordToken::ArrayVariable(
-                                    data,
-                                    contains_quote,
-                                    Select::Key(key),
-                                ));
-                            }
-                        } else {
+
+    for word in WordIterator::new(original, expand_func, true) {
+        match word {
+            WordToken::Brace(_) => {
+                contains_brace = true;
+                token_buffer.push(word);
+            }
+            WordToken::ArrayVariable(data, contains_quote, selection) => {
+                if let Select::Key(key) = selection {
+                    if key.contains(' ') {
+                        for index in key.split(' ') {
+                            let select = index.parse::<Select>().unwrap_or(Select::None);
                             token_buffer.push(WordToken::ArrayVariable(
                                 data,
                                 contains_quote,
-                                selection,
+                                select,
                             ));
+                            token_buffer.push(WordToken::Whitespace(" "));
                         }
+                        token_buffer.pop(); // Pop out the last unneeded whitespace token
+                    } else {
+                        token_buffer.push(WordToken::ArrayVariable(
+                            data,
+                            contains_quote,
+                            Select::Key(key),
+                        ));
                     }
-                    _ => token_buffer.push(word),
+                } else {
+                    token_buffer.push(WordToken::ArrayVariable(data, contains_quote, selection));
                 }
             }
-            None if original.is_empty() => {
-                token_buffer.push(WordToken::Normal("".into(), true, false));
-                break;
-            }
-            None => break,
+            _ => token_buffer.push(word),
         }
     }
+
+    if original.is_empty() {
+        token_buffer.push(WordToken::Normal("".into(), true, false));
+    }
     expand_tokens(&token_buffer, expand_func, reverse_quoting, contains_brace)
 }
 
@@ -281,22 +266,15 @@ fn expand_string_no_glob<E: Expander>(
 ) -> types::Array {
     let mut token_buffer = Vec::new();
     let mut contains_brace = false;
-    let mut word_iterator = WordIterator::new(original, expand_func, false);
 
-    loop {
-        match word_iterator.next() {
-            Some(word) => {
-                if let WordToken::Brace(_) = word {
-                    contains_brace = true;
-                }
-                token_buffer.push(word);
-            }
-            None if original.is_empty() => {
-                token_buffer.push(WordToken::Normal("".into(), true, false));
-                break;
-            }
-            None => break,
+    for word in WordIterator::new(original, expand_func, false) {
+        if let WordToken::Brace(_) = word {
+            contains_brace = true;
         }
+        token_buffer.push(word);
+    }
+    if original.is_empty() {
+        token_buffer.push(WordToken::Normal("".into(), true, false));
     }
     expand_tokens(&token_buffer, expand_func, reverse_quoting, contains_brace)
 }
@@ -314,7 +292,7 @@ fn expand_braces<E: Expander>(
     for word in word_tokens {
         match *word {
             WordToken::Array(ref elements, ref index) => {
-                output.push_str(&array_expand(elements, expand_func, index.clone()).join(" "));
+                output.push_str(&array_expand(elements, expand_func, &index).join(" "));
             }
             WordToken::ArrayVariable(array, _, ref index) => {
                 if let Some(array) = expand_func.array(array, index.clone()) {
@@ -322,26 +300,25 @@ fn expand_braces<E: Expander>(
                 }
             }
             WordToken::ArrayProcess(command, _, ref index) => match *index {
-                Select::None => (),
                 Select::All => {
                     let mut temp = small::String::new();
-                    expand_process(&mut temp, command, Select::All, expand_func, false);
+                    expand_process(&mut temp, command, &Select::All, expand_func, false);
                     let temp = temp.split_whitespace().collect::<Vec<&str>>();
                     output.push_str(&temp.join(" "));
                 }
                 Select::Index(Index::Forward(id)) => {
                     let mut temp = small::String::new();
-                    expand_process(&mut temp, command, Select::All, expand_func, false);
+                    expand_process(&mut temp, command, &Select::All, expand_func, false);
                     output.push_str(temp.split_whitespace().nth(id).unwrap_or_default());
                 }
                 Select::Index(Index::Backward(id)) => {
                     let mut temp = small::String::new();
-                    expand_process(&mut temp, command, Select::All, expand_func, false);
+                    expand_process(&mut temp, command, &Select::All, expand_func, false);
                     output.push_str(temp.split_whitespace().rev().nth(id).unwrap_or_default());
                 }
                 Select::Range(range) => {
                     let mut temp = small::String::new();
-                    expand_process(&mut temp, command, Select::All, expand_func, false);
+                    expand_process(&mut temp, command, &Select::All, expand_func, false);
                     let len = temp.split_whitespace().count();
                     if let Some((start, length)) = range.bounds(len) {
                         let res =
@@ -349,7 +326,7 @@ fn expand_braces<E: Expander>(
                         output.push_str(&res.join(" "));
                     }
                 }
-                Select::Key(_) => (),
+                Select::Key(_) | Select::None => (),
             },
             WordToken::ArrayMethod(ref method) => {
                 method.handle(&mut output, expand_func);
@@ -368,7 +345,7 @@ fn expand_braces<E: Expander>(
             WordToken::Whitespace(whitespace) => output.push_str(whitespace),
             WordToken::Process(command, quoted, ref index) => {
                 let quoted = if reverse_quoting { !quoted } else { quoted };
-                expand_process(&mut output, command, index.clone(), expand_func, quoted);
+                expand_process(&mut output, command, &index, expand_func, quoted);
             }
             WordToken::Variable(text, quoted, ref index) => {
                 let quoted = if reverse_quoting { !quoted } else { quoted };
@@ -377,7 +354,7 @@ fn expand_braces<E: Expander>(
                     None => continue,
                 };
 
-                slice(&mut output, expanded, index.clone());
+                slice(&mut output, expanded, &index);
             }
             WordToken::Normal(ref text, _, tilde) => {
                 expand(&mut output, &mut expanded_words, expand_func, text.as_ref(), false, tilde);
@@ -436,7 +413,7 @@ fn expand_single_array_token<E: Expander>(
     let mut output = small::String::new();
     match *token {
         WordToken::Array(ref elements, ref index) => {
-            Some(array_expand(elements, expand_func, index.clone()))
+            Some(array_expand(elements, expand_func, &index))
         }
         WordToken::ArrayVariable(array, quoted, ref index) => {
             match expand_func.array(array, index.clone()) {
@@ -448,21 +425,20 @@ fn expand_single_array_token<E: Expander>(
             }
         }
         WordToken::ArrayProcess(command, _, ref index) => match *index {
-            Select::None => Some(types::Array::new()),
             Select::All => {
-                expand_process(&mut output, command, Select::All, expand_func, false);
+                expand_process(&mut output, command, &Select::All, expand_func, false);
                 Some(output.split_whitespace().map(From::from).collect::<types::Array>())
             }
             Select::Index(Index::Forward(id)) => {
-                expand_process(&mut output, command, Select::All, expand_func, false);
+                expand_process(&mut output, command, &Select::All, expand_func, false);
                 Some(output.split_whitespace().nth(id).map(Into::into).into_iter().collect())
             }
             Select::Index(Index::Backward(id)) => {
-                expand_process(&mut output, command, Select::All, expand_func, false);
+                expand_process(&mut output, command, &Select::All, expand_func, false);
                 Some(output.split_whitespace().rev().nth(id).map(Into::into).into_iter().collect())
             }
             Select::Range(range) => {
-                expand_process(&mut output, command, Select::All, expand_func, false);
+                expand_process(&mut output, command, &Select::All, expand_func, false);
                 if let Some((start, length)) = range.bounds(output.split_whitespace().count()) {
                     Some(
                         output
@@ -476,7 +452,7 @@ fn expand_single_array_token<E: Expander>(
                     Some(types::Array::new())
                 }
             }
-            Select::Key(_) => Some(types::Array::new()),
+            Select::Key(_) | Select::None => Some(types::Array::new()),
         },
         WordToken::ArrayMethod(ref array_method) => Some(array_method.handle_as_array(expand_func)),
         _ => None,
@@ -499,7 +475,7 @@ fn expand_single_string_token<E: Expander>(
         WordToken::Whitespace(text) => output.push_str(text),
         WordToken::Process(command, quoted, ref index) => {
             let quoted = if reverse_quoting { !quoted } else { quoted };
-            expand_process(&mut output, command, index.clone(), expand_func, quoted);
+            expand_process(&mut output, command, &index, expand_func, quoted);
         }
         WordToken::Variable(text, quoted, ref index) => {
             let quoted = if reverse_quoting { !quoted } else { quoted };
@@ -513,7 +489,7 @@ fn expand_single_string_token<E: Expander>(
                 }
             };
 
-            slice(&mut output, expanded, index.clone());
+            slice(&mut output, expanded, &index);
         }
         WordToken::Arithmetic(s) => expand_arithmetic(&mut output, s, expand_func),
         _ => unreachable!(),
@@ -608,7 +584,7 @@ pub(crate) fn expand_tokens<E: Expander>(
         for word in token_buffer {
             match *word {
                 WordToken::Array(ref elements, ref index) => {
-                    output.push_str(&array_expand(elements, expand_func, index.clone()).join(" "));
+                    output.push_str(&array_expand(elements, expand_func, &index).join(" "));
                 }
                 WordToken::ArrayVariable(array, _, ref index) => {
                     if let Some(array) = expand_func.array(array, index.clone()) {
@@ -616,26 +592,25 @@ pub(crate) fn expand_tokens<E: Expander>(
                     }
                 }
                 WordToken::ArrayProcess(command, _, ref index) => match index.clone() {
-                    Select::None => (),
                     Select::All => {
                         let mut temp = small::String::new();
-                        expand_process(&mut temp, command, Select::All, expand_func, false);
+                        expand_process(&mut temp, command, &Select::All, expand_func, false);
                         let temp = temp.split_whitespace().collect::<Vec<&str>>();
                         output.push_str(&temp.join(" "));
                     }
                     Select::Index(Index::Forward(id)) => {
                         let mut temp = small::String::new();
-                        expand_process(&mut temp, command, Select::All, expand_func, false);
+                        expand_process(&mut temp, command, &Select::All, expand_func, false);
                         output.push_str(temp.split_whitespace().nth(id).unwrap_or_default());
                     }
                     Select::Index(Index::Backward(id)) => {
                         let mut temp = small::String::new();
-                        expand_process(&mut temp, command, Select::All, expand_func, false);
+                        expand_process(&mut temp, command, &Select::All, expand_func, false);
                         output.push_str(temp.split_whitespace().rev().nth(id).unwrap_or_default());
                     }
                     Select::Range(range) => {
                         let mut temp = small::String::new();
-                        expand_process(&mut temp, command, Select::All, expand_func, false);
+                        expand_process(&mut temp, command, &Select::All, expand_func, false);
                         if let Some((start, length)) = range.bounds(temp.split_whitespace().count())
                         {
                             let temp = temp
@@ -646,7 +621,7 @@ pub(crate) fn expand_tokens<E: Expander>(
                             output.push_str(&temp.join(" "))
                         }
                     }
-                    Select::Key(_) => (),
+                    Select::Key(_) | Select::None => (),
                 },
                 WordToken::ArrayMethod(ref method) => {
                     method.handle(&mut output, expand_func);
@@ -670,7 +645,7 @@ pub(crate) fn expand_tokens<E: Expander>(
                 }
                 WordToken::Process(command, quoted, ref index) => {
                     let quoted = if reverse_quoting { !quoted } else { quoted };
-                    expand_process(&mut output, command, index.clone(), expand_func, quoted);
+                    expand_process(&mut output, command, &index, expand_func, quoted);
                 }
                 WordToken::Variable(text, quoted, ref index) => {
                     let quoted = if reverse_quoting { !quoted } else { quoted };
@@ -679,7 +654,7 @@ pub(crate) fn expand_tokens<E: Expander>(
                         None => continue,
                     };
 
-                    slice(&mut output, expanded, index.clone());
+                    slice(&mut output, expanded, &index);
                 }
                 WordToken::Arithmetic(s) => expand_arithmetic(&mut output, s, expand_func),
             }
@@ -769,7 +744,7 @@ mod test {
     fn expand_process_quoted() {
         let mut output = small::String::new();
         let line = " Mary   had\ta little  \n\t lamb\t";
-        expand_process(&mut output, line, Select::All, &CommandExpander, true);
+        expand_process(&mut output, line, &Select::All, &CommandExpander, true);
         assert_eq!(output.as_str(), line);
     }
 
@@ -777,7 +752,7 @@ mod test {
     fn expand_process_unquoted() {
         let mut output = small::String::new();
         let line = " Mary   had\ta\u{2009}little  \n\t lamb 😉😉\t";
-        expand_process(&mut output, line, Select::All, &CommandExpander, false);
+        expand_process(&mut output, line, &Select::All, &CommandExpander, false);
         assert_eq!(output.as_str(), "Mary had a little lamb 😉😉");
     }
 
diff --git a/src/lib/parser/shell_expand/words/methods/strings.rs b/src/lib/parser/shell_expand/words/methods/strings.rs
index d6b618a7d0683d357008c65da1615753a8bc2db3..81d42da5d5f8e34b450becfddd9d080c692774a1 100644
--- a/src/lib/parser/shell_expand/words/methods/strings.rs
+++ b/src/lib/parser/shell_expand/words/methods/strings.rs
@@ -228,12 +228,12 @@ impl<'a> StringMethod<'a> {
             "join" => {
                 let pattern = pattern.join(" ");
                 if let Some(array) = expand.array(variable, Select::All) {
-                    slice(output, array.join(&pattern), self.selection.clone());
+                    slice(output, array.join(&pattern), &self.selection);
                 } else if is_expression(variable) {
                     slice(
                         output,
                         expand_string(variable, expand, false).join(&pattern),
-                        self.selection.clone(),
+                        &self.selection,
                     );
                 }
             }
diff --git a/src/lib/parser/shell_expand/words/mod.rs b/src/lib/parser/shell_expand/words/mod.rs
index fb0ca34bb2ac2e34e23bd8fe9315076fbe9ad917..c6f8668fd6731dc66623502ab8ac5766d1c14526 100644
--- a/src/lib/parser/shell_expand/words/mod.rs
+++ b/src/lib/parser/shell_expand/words/mod.rs
@@ -678,115 +678,113 @@ impl<'a, E: Expander + 'a> Iterator for WordIterator<'a, E> {
         let mut tilde = false;
 
         loop {
-            if let Some(character) = iterator.next() {
-                match character {
-                    _ if self.flags.contains(Flags::BACKSL) => {
-                        self.read += 1;
-                        self.flags ^= Flags::BACKSL;
-                        break;
-                    }
-                    b'\\' => {
-                        if !self.flags.intersects(Flags::DQUOTE | Flags::SQUOTE) {
-                            start += 1;
-                        }
-                        self.read += 1;
-                        self.flags ^= Flags::BACKSL;
-                        break;
-                    }
-                    b'\'' if !self.flags.contains(Flags::DQUOTE) => {
-                        start += 1;
-                        self.read += 1;
-                        self.flags ^= Flags::SQUOTE;
-                        break;
-                    }
-                    b'"' if !self.flags.contains(Flags::SQUOTE) => {
+            match iterator.next()? {
+                _ if self.flags.contains(Flags::BACKSL) => {
+                    self.read += 1;
+                    self.flags ^= Flags::BACKSL;
+                    break;
+                }
+                b'\\' => {
+                    if !self.flags.intersects(Flags::DQUOTE | Flags::SQUOTE) {
                         start += 1;
-                        self.read += 1;
-                        if self.flags.contains(Flags::DQUOTE) {
-                            self.flags -= Flags::DQUOTE;
-                            return self.next();
-                        }
-                        self.flags |= Flags::DQUOTE;
-                        break;
-                    }
-                    b' ' if !self.flags.intersects(Flags::DQUOTE | Flags::SQUOTE) => {
-                        return Some(self.whitespaces(&mut iterator));
                     }
-                    b'~' if !self.flags.intersects(Flags::DQUOTE | Flags::SQUOTE) => {
-                        tilde = true;
-                        self.read += 1;
-                        break;
-                    }
-                    b'{' if !self.flags.intersects(Flags::DQUOTE | Flags::SQUOTE) => {
-                        self.read += 1;
-                        return Some(self.braces(&mut iterator));
+                    self.read += 1;
+                    self.flags ^= Flags::BACKSL;
+                    break;
+                }
+                b'\'' if !self.flags.contains(Flags::DQUOTE) => {
+                    start += 1;
+                    self.read += 1;
+                    self.flags ^= Flags::SQUOTE;
+                    break;
+                }
+                b'"' if !self.flags.contains(Flags::SQUOTE) => {
+                    start += 1;
+                    self.read += 1;
+                    if self.flags.contains(Flags::DQUOTE) {
+                        self.flags -= Flags::DQUOTE;
+                        return self.next();
                     }
-                    b'[' if !self.flags.intersects(Flags::SQUOTE | Flags::DQUOTE) => {
-                        if self.glob_check(&mut iterator) {
-                            glob = self.do_glob;
-                        } else {
-                            return Some(self.array(&mut iterator));
-                        }
+                    self.flags |= Flags::DQUOTE;
+                    break;
+                }
+                b' ' if !self.flags.intersects(Flags::DQUOTE | Flags::SQUOTE) => {
+                    return Some(self.whitespaces(&mut iterator));
+                }
+                b'~' if !self.flags.intersects(Flags::DQUOTE | Flags::SQUOTE) => {
+                    tilde = true;
+                    self.read += 1;
+                    break;
+                }
+                b'{' if !self.flags.intersects(Flags::DQUOTE | Flags::SQUOTE) => {
+                    self.read += 1;
+                    return Some(self.braces(&mut iterator));
+                }
+                b'[' if !self.flags.intersects(Flags::SQUOTE | Flags::DQUOTE) => {
+                    if self.glob_check(&mut iterator) {
+                        glob = self.do_glob;
+                    } else {
+                        return Some(self.array(&mut iterator));
                     }
-                    b'@' if !self.flags.contains(Flags::SQUOTE) => match iterator.next() {
+                }
+                b'@' if !self.flags.contains(Flags::SQUOTE) => {
+                    return match iterator.next() {
                         Some(b'(') => {
                             self.read += 2;
-                            return Some(self.array_process(&mut iterator));
+                            Some(self.array_process(&mut iterator))
                         }
                         Some(b'{') => {
                             self.read += 2;
-                            return Some(self.braced_array_variable(&mut iterator));
+                            Some(self.braced_array_variable(&mut iterator))
                         }
                         Some(b' ') | None => {
                             self.read += 1;
                             let output = &self.data[start..self.read];
-                            return Some(WordToken::Normal(output.into(), glob, tilde));
+                            Some(WordToken::Normal(output.into(), glob, tilde))
                         }
                         _ => {
                             self.read += 1;
-                            return Some(self.array_variable(&mut iterator));
+                            Some(self.array_variable(&mut iterator))
                         }
-                    },
-                    b'$' if !self.flags.contains(Flags::SQUOTE) => {
-                        match iterator.next() {
-                            Some(b'(') => {
-                                self.read += 2;
-                                return if self.data.as_bytes()[self.read] == b'(' {
-                                    // Pop the incoming left paren
-                                    let _ = iterator.next();
-                                    self.read += 1;
-                                    Some(self.arithmetic_expression(&mut iterator))
-                                } else {
-                                    Some(self.process(&mut iterator))
-                                };
-                            }
-                            Some(b'{') => {
-                                self.read += 2;
-                                return Some(self.braced_variable(&mut iterator));
-                            }
-                            Some(b' ') | None => {
-                                self.read += 1;
-                                let output = &self.data[start..self.read];
-                                return Some(WordToken::Normal(output.into(), glob, tilde));
-                            }
-                            _ => {
+                    }
+                }
+                b'$' if !self.flags.contains(Flags::SQUOTE) => {
+                    return match iterator.next() {
+                        Some(b'(') => {
+                            self.read += 2;
+                            if self.data.as_bytes()[self.read] == b'(' {
+                                // Pop the incoming left paren
+                                let _ = iterator.next();
                                 self.read += 1;
-                                return Some(self.variable(&mut iterator));
+                                Some(self.arithmetic_expression(&mut iterator))
+                            } else {
+                                Some(self.process(&mut iterator))
                             }
                         }
-                    }
-                    b'*' | b'?' => {
-                        self.read += 1;
-                        glob = self.do_glob;
-                        break;
-                    }
-                    _ => {
-                        self.read += 1;
-                        break;
-                    }
+                        Some(b'{') => {
+                            self.read += 2;
+                            Some(self.braced_variable(&mut iterator))
+                        }
+                        Some(b' ') | None => {
+                            self.read += 1;
+                            let output = &self.data[start..self.read];
+                            Some(WordToken::Normal(output.into(), glob, tilde))
+                        }
+                        _ => {
+                            self.read += 1;
+                            Some(self.variable(&mut iterator))
+                        }
+                    };
+                }
+                b'*' | b'?' => {
+                    self.read += 1;
+                    glob = self.do_glob;
+                    break;
+                }
+                _ => {
+                    self.read += 1;
+                    break;
                 }
-            } else {
-                return None;
             }
         }
         while let Some(character) = iterator.next() {
@@ -849,8 +847,8 @@ impl<'a, E: Expander + 'a> Iterator for WordIterator<'a, E> {
                             return Some(WordToken::Normal(output.into(), glob, tilde));
                         }
                     }
-                    let output = &self.data[start..self.read];
-                    if output != "" {
+                    if self.read != start {
+                        let output = &self.data[start..self.read];
                         return Some(WordToken::Normal(unescape(output), glob, tilde));
                     } else {
                         return self.next();
diff --git a/src/lib/parser/statement/case.rs b/src/lib/parser/statement/case.rs
index e0daf2f6c1fe3565c00da073e1118d664b60575f..e45248780a285ab9b37abefe0e5b3317a659daad 100644
--- a/src/lib/parser/statement/case.rs
+++ b/src/lib/parser/statement/case.rs
@@ -67,20 +67,15 @@ pub(crate) fn parse_case(
                 }
                 conditional = Some(string);
             }
-            Some(inner) => {
-                if argument.is_none() {
-                    argument = Some(inner);
-                    continue;
-                } else {
-                    return Err(CaseError::ExtraVar(inner));
-                }
+            Some(inner) if argument.is_none() => {
+                argument = Some(inner);
+                continue;
             }
+            Some(inner) => return Err(CaseError::ExtraVar(inner)),
             None => (),
         }
-        break;
+        return Ok((argument, binding, conditional));
     }
-
-    Ok((argument, binding, conditional))
 }
 
 #[cfg(test)]
diff --git a/src/lib/parser/statement/parse.rs b/src/lib/parser/statement/parse.rs
index 9ac851a1ce490460328f69cd7d856d9e51424b44..221ac8131505c8fd5078d1bc58b3d7b048a971af 100644
--- a/src/lib/parser/statement/parse.rs
+++ b/src/lib/parser/statement/parse.rs
@@ -199,12 +199,8 @@ pub(crate) fn parse(code: &str) -> Statement {
         _ if cmd.starts_with("time ") => {
             // Ignore embedded time calls
             let mut timed = cmd[4..].trim_start();
-            loop {
-                if timed.starts_with("time ") {
-                    timed = timed[4..].trim_start();
-                    continue;
-                }
-                break;
+            while timed.starts_with("time ") {
+                timed = timed[4..].trim_start();
             }
             Statement::Time(Box::new(parse(timed)))
         }
diff --git a/src/lib/shell/assignments.rs b/src/lib/shell/assignments.rs
index ab108096df79b5a37cb470dc24c8b094a5de5c4c..a3b65645be6c6b86fca9aa6a42485259ca58a5dc 100644
--- a/src/lib/shell/assignments.rs
+++ b/src/lib/shell/assignments.rs
@@ -168,7 +168,7 @@ impl VariableStore for Shell {
                             }
                         }
                     } else {
-                        self.overwrite(key, operator, rhs)
+                        self.overwrite(&key, operator, rhs)
                     }
                 })?;
         }
@@ -185,7 +185,7 @@ impl VariableStore for Shell {
                 let actions = AssignmentActions::new(keys, op, vals);
                 if let Err(why) = self.calculate(actions).and_then(|apply| {
                     for (key, value) in apply {
-                        self.assign(key, value)?
+                        self.assign(&key, value)?
                     }
                     Ok(())
                 }) {
diff --git a/src/lib/shell/flow.rs b/src/lib/shell/flow.rs
index 35eb6bb4ea578a2b16c5308b63b2979e4b774fe4..c0fc0e71c0060992da008bc4650f34540d0086f3 100644
--- a/src/lib/shell/flow.rs
+++ b/src/lib/shell/flow.rs
@@ -2,6 +2,7 @@ use super::{
     flags::*,
     flow_control::{insert_statement, Case, ElseIf, Function, Statement},
     job_control::JobControl,
+    signals,
     status::*,
     Shell,
 };
@@ -158,22 +159,18 @@ impl FlowLogic for Shell {
         statements: Vec<Statement>,
     ) -> Condition {
         loop {
-            let expression = {
-                self.execute_statements(expression.clone());
-                self.previous_status == 0
-            };
-            if expression {
-                // Cloning is needed so the statement can be re-iterated again if needed.
-                match self.execute_statements(statements.clone()) {
-                    Condition::Break => break,
-                    Condition::SigInt => return Condition::SigInt,
-                    _ => (),
-                }
-            } else {
-                break;
+            self.execute_statements(expression.clone());
+            if self.previous_status != 0 {
+                return Condition::NoOp;
+            }
+
+            // Cloning is needed so the statement can be re-iterated again if needed.
+            match self.execute_statements(statements.clone()) {
+                Condition::Break => return Condition::NoOp,
+                Condition::SigInt => return Condition::SigInt,
+                _ => (),
             }
         }
-        Condition::NoOp
     }
 
     fn execute_statement(&mut self, statement: Statement) -> Condition {
@@ -310,7 +307,7 @@ impl FlowLogic for Shell {
             },
             _ => {}
         }
-        if let Some(signal) = self.next_signal() {
+        if let Some(signal) = signals::SignalHandler.next() {
             if self.handle_signal(signal) {
                 self.exit(get_signal_code(signal));
             }
diff --git a/src/lib/shell/fork.rs b/src/lib/shell/fork.rs
index abc39ca2c96f5ef336c445c938d94b4c2416de25..7dd42fd8a8087941d21bcaf3ca61bc36922b57ac 100644
--- a/src/lib/shell/fork.rs
+++ b/src/lib/shell/fork.rs
@@ -7,10 +7,8 @@ use std::{
 };
 
 pub fn wait_for_child(pid: u32) -> io::Result<u8> {
-    let mut status;
-
     loop {
-        status = 0;
+        let mut status = 0;
         if let Err(errno) = sys::waitpid(pid as i32, &mut status, sys::WUNTRACED) {
             break if errno == sys::ECHILD {
                 Ok(sys::wexitstatus(status) as u8)
diff --git a/src/lib/shell/job.rs b/src/lib/shell/job.rs
index 5a27a64ed36ec60970f1a6aad636f7927324e7d9..e0d1dda79a475936e87b4375cf26e98cff597bf2 100644
--- a/src/lib/shell/job.rs
+++ b/src/lib/shell/job.rs
@@ -121,14 +121,7 @@ impl TeeItem {
                     return Ok(());
                 }
                 for file in sinks.iter_mut() {
-                    let mut total = 0;
-                    loop {
-                        let wrote = file.write(&buf[total..len])?;
-                        total += wrote;
-                        if total == len {
-                            break;
-                        }
-                    }
+                    file.write_all(&buf[..len])?;
                 }
             }
         }
diff --git a/src/lib/shell/mod.rs b/src/lib/shell/mod.rs
index d5aa809a72ebe2688752606a9df449dce6274798..a3a3ad5ebb98c08c3132e777f480ad131cc59dea 100644
--- a/src/lib/shell/mod.rs
+++ b/src/lib/shell/mod.rs
@@ -380,16 +380,6 @@ impl Shell {
         }
     }
 
-    pub(crate) fn next_signal(&self) -> Option<i32> {
-        match signals::PENDING.swap(0, Ordering::SeqCst) as u8 {
-            0 => None,
-            signals::SIGINT => Some(sys::SIGINT),
-            signals::SIGHUP => Some(sys::SIGHUP),
-            signals::SIGTERM => Some(sys::SIGTERM),
-            _ => unreachable!(),
-        }
-    }
-
     pub(crate) fn new(is_library: bool) -> Shell {
         let mut shell = Shell {
             builtins: BUILTINS,
@@ -412,7 +402,7 @@ impl Shell {
         shell
     }
 
-    pub fn assign(&mut self, key: Key, value: Value) -> Result<(), String> {
+    pub fn assign(&mut self, key: &Key, value: Value) -> Result<(), String> {
         match (&key.kind, &value) {
             (Primitive::Indexed(ref index_name, ref index_kind), Value::Str(_)) => {
                 let index = value_check(self, index_name, index_kind)
@@ -466,7 +456,7 @@ impl Shell {
         }
     }
 
-    pub fn overwrite(&mut self, key: Key, operator: Operator, rhs: Value) -> Result<(), String> {
+    pub fn overwrite(&mut self, key: &Key, operator: Operator, rhs: Value) -> Result<(), String> {
         let lhs = self
             .variables
             .get_mut(key.name)
diff --git a/src/lib/shell/pipe_exec/job_control.rs b/src/lib/shell/pipe_exec/job_control.rs
index cffb80ffd9b122f162704630e0688b18f7330671..3f7764b2bc424bc6d2d992f19f5214807baa8726 100644
--- a/src/lib/shell/pipe_exec/job_control.rs
+++ b/src/lib/shell/pipe_exec/job_control.rs
@@ -151,10 +151,9 @@ impl JobControl for Shell {
     fn watch_foreground(&mut self, pid: i32, command: &str) -> i32 {
         let mut signaled = 0;
         let mut exit_status = 0;
-        let mut status;
 
         loop {
-            status = 0;
+            let mut status = 0;
             match waitpid(pid, &mut status, WUNTRACED) {
                 Err(errno) => match errno {
                     ECHILD if signaled == 0 => break exit_status,
@@ -204,24 +203,13 @@ impl JobControl for Shell {
     /// Waits until all running background tasks have completed, and listens for signals in the
     /// event that a signal is sent to kill the running tasks.
     fn wait_for_background(&mut self) {
-        let sigcode;
-        'event: loop {
-            for process in self.background.lock().unwrap().iter() {
-                if let ProcessState::Running = process.state {
-                    while let Some(signal) = self.next_signal() {
-                        if signal != sys::SIGTSTP {
-                            self.background_send(signal);
-                            sigcode = get_signal_code(signal);
-                            break 'event;
-                        }
-                    }
-                    sleep(Duration::from_millis(100));
-                    continue 'event;
-                }
+        while self.background.lock().unwrap().iter().any(|p| p.state == ProcessState::Running) {
+            if let Some(signal) = signals::SignalHandler.find(|&s| s != sys::SIGTSTP) {
+                self.background_send(signal);
+                self.exit(get_signal_code(signal));
             }
-            return;
+            sleep(Duration::from_millis(100));
         }
-        self.exit(sigcode);
     }
 
     fn set_bg_task_in_foreground(&self, pid: u32, cont: bool) -> i32 {
diff --git a/src/lib/shell/pipe_exec/mod.rs b/src/lib/shell/pipe_exec/mod.rs
index f399c4565f71238562a7bac66270be596c6a6e71..060c143f804d0b4513364110d3df734686ce772a 100644
--- a/src/lib/shell/pipe_exec/mod.rs
+++ b/src/lib/shell/pipe_exec/mod.rs
@@ -498,27 +498,10 @@ impl PipelineExecution for Shell {
             redir(file.as_raw_fd(), sys::STDOUT_FILENO)
         }
 
-        fn read_and_write<R: io::Read>(src: &mut R, stdout: &mut io::StdoutLock) -> io::Result<()> {
-            let mut buf = [0; 4096];
-            loop {
-                let len = src.read(&mut buf)?;
-                if len == 0 {
-                    return Ok(());
-                };
-                let mut total = 0;
-                loop {
-                    let wrote = stdout.write(&buf[total..len])?;
-                    total += wrote;
-                    if total == len {
-                        break;
-                    }
-                }
-            }
-        };
         let stdout = io::stdout();
         let mut stdout = stdout.lock();
         for file in stdin.iter_mut().chain(sources) {
-            if let Err(why) = read_and_write(file, &mut stdout) {
+            if let Err(why) = std::io::copy(file, &mut stdout) {
                 eprintln!("ion: error in multiple input redirect process: {:?}", why);
                 return FAILURE;
             }
@@ -981,13 +964,11 @@ fn set_process_group(pgid: &mut u32, pid: u32) -> bool {
 }
 
 pub fn wait_for_interrupt(pid: u32) -> io::Result<()> {
-    let mut status;
-
     loop {
-        status = 0;
+        let mut status = 0;
         match sys::waitpid(pid as i32, &mut status, sys::WUNTRACED) {
             Ok(_) => break Ok(()),
-            Err(errno) if errno == sys::EINTR => continue,
+            Err(sys::EINTR) => continue,
             Err(errno) => break Err(io::Error::from_raw_os_error(errno)),
         }
     }
diff --git a/src/lib/shell/signals.rs b/src/lib/shell/signals.rs
index e3a444ab89ce87844080bf57ca77145503ef4dd9..611f12a6340f6195ebabdb0ef3a3c3b0271fc4a1 100644
--- a/src/lib/shell/signals.rs
+++ b/src/lib/shell/signals.rs
@@ -4,7 +4,7 @@
 //! children of the shell.
 
 // use std::sync::atomic::{ATOMIC_U8_INIT, AtomicU8};
-use std::sync::atomic::AtomicUsize;
+use std::sync::atomic::{AtomicUsize, Ordering};
 
 use crate::sys;
 
@@ -35,3 +35,17 @@ impl SignalHandler {
 impl Drop for SignalHandler {
     fn drop(&mut self) { unblock(); }
 }
+
+impl Iterator for SignalHandler {
+    type Item = i32;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match PENDING.swap(0, Ordering::SeqCst) as u8 {
+            0 => None,
+            SIGINT => Some(sys::SIGINT),
+            SIGHUP => Some(sys::SIGHUP),
+            SIGTERM => Some(sys::SIGTERM),
+            _ => unreachable!(),
+        }
+    }
+}
diff --git a/src/lib/shell/variables/mod.rs b/src/lib/shell/variables/mod.rs
index dbe659c7bdbef6f59875a372fe5ec3934bcbc057..09395c5114085f9a7a765fa82125f7f1564d15c8 100644
--- a/src/lib/shell/variables/mod.rs
+++ b/src/lib/shell/variables/mod.rs
@@ -176,7 +176,7 @@ impl Default for Variables {
             Value::Array(array!["no_such_command", "whitespace", "duplicates"]),
         );
 
-        map.insert("CDPATH".into(), Value::Array(array![]));
+        map.insert("CDPATH".into(), Value::Array(Array::new()));
 
         // Initialize the HOME variable
         sys_env::home_dir().map_or_else(