Repository: pest-parser/pest
Pull request #921 (2023-08-29 07:36:21)

small cargo clippy fixes + dependency bumps
memchr now supports aarch64, so it's made default: https://github.com/BurntSushi/memchr/pull/129
cargo lib (used in the not-bootstrap-in-src feature) did not respect umask: https://github.com/advisories/GHSA-j3xp-wfr4-hx87
(probably not an issue here)


Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d239dbb..7263d30 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -23,7 +23,7 @@ jobs:
         uses: ./.github/actions/setup
         with:
           kind: check
-          toolchain: 1.64.0
+          toolchain: 1.70.0
       - name: cargo check
         run: cargo check --all --features pretty-print,const_prec_climber,memchr,grammar-extras --all-targets
 
@@ -40,7 +40,7 @@ jobs:
         with:
           kind: check
           components: clippy, rustfmt
-          toolchain: 1.64.0
+          toolchain: 1.70.0
       - name: cargo fmt
         run: cargo fmt --all -- --check
       - name: cargo clippy
@@ -62,7 +62,7 @@ jobs:
         id: setup
         with:
           kind: check
-          toolchain: 1.64.0
+          toolchain: 1.70.0
       - name: cargo doc
         run: cargo doc --all --features pretty-print,const_prec_climber,memchr,grammar-extras
 
@@ -123,7 +123,7 @@ jobs:
         id: setup
         with:
           kind: check
-          toolchain: 1.64.0
+          toolchain: 1.70.0
       - name: Check feature powerset
         run: cargo hack check --feature-powerset --optional-deps --exclude-all-features --skip not-bootstrap-in-src,cargo --keep-going --lib --tests --ignore-private
 
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 7141048..f8d171e 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -15,7 +15,7 @@ jobs:
       - name: Install jq
         run: sudo apt-get update && sudo apt-get install -y jq
       - name: Install toolchain
-        uses: dtolnay/rust-toolchain@1.63.0 # needed for pest_debugger (linux-raw-sys v0.4.3 requires it)
+        uses: dtolnay/rust-toolchain@1.70.0 # needed for pest_debugger (clap_builder v4.4.1 requires it)
       - name: Bootstraping Grammars - Building
         run: cargo build --package pest_bootstrap
       - name: Bootstraping Grammars - Executing
diff --git a/Cargo.toml b/Cargo.toml
index 8b3e894..e581766 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,4 +1,5 @@
 [workspace]
+resolver = "2"
 members = [
     "bootstrap",
     "debugger",
diff --git a/debugger/Cargo.toml b/debugger/Cargo.toml
index e11f0a2..2a8695e 100644
--- a/debugger/Cargo.toml
+++ b/debugger/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "pest_debugger"
 description = "pest grammar debugger"
-version = "2.7.2"
+version = "2.7.3"
 edition = "2021"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>", "Tomas Tauber <me@tomtau.be>"]
 homepage = "https://pest.rs/"
@@ -14,9 +14,9 @@ readme = "_README.md"
 rust-version = "1.60"
 
 [dependencies]
-pest = { path = "../pest", version = "2.7.2" }
-pest_meta = { path = "../meta", version = "2.7.2" }
-pest_vm = { path = "../vm", version = "2.7.2" }
+pest = { path = "../pest", version = "2.7.3" }
+pest_meta = { path = "../meta", version = "2.7.3" }
+pest_vm = { path = "../vm", version = "2.7.3" }
 reqwest = { version = "= 0.11.13", default-features = false, features = ["blocking", "json", "default-tls"] }
 rustyline = "10"
 serde_json = "1"
diff --git a/derive/Cargo.toml b/derive/Cargo.toml
index 8de0f14..b9486c6 100644
--- a/derive/Cargo.toml
+++ b/derive/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "pest_derive"
 description = "pest's derive macro"
-version = "2.7.2"
+version = "2.7.3"
 edition = "2021"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest.rs/"
@@ -25,5 +25,5 @@ grammar-extras = ["pest_generator/grammar-extras"]
 
 [dependencies]
 # for tests, included transitively anyway
-pest = { path = "../pest", version = "2.7.2", default-features = false }
-pest_generator = { path = "../generator", version = "2.7.2", default-features = false }
+pest = { path = "../pest", version = "2.7.3", default-features = false }
+pest_generator = { path = "../generator", version = "2.7.3", default-features = false }
diff --git a/generator/Cargo.toml b/generator/Cargo.toml
index 1763657..c329ff8 100644
--- a/generator/Cargo.toml
+++ b/generator/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "pest_generator"
 description = "pest code generator"
-version = "2.7.2"
+version = "2.7.3"
 edition = "2021"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest.rs/"
@@ -20,8 +20,8 @@ not-bootstrap-in-src = ["pest_meta/not-bootstrap-in-src"]
 grammar-extras = ["pest_meta/grammar-extras"]
 
 [dependencies]
-pest = { path = "../pest", version = "2.7.2", default-features = false }
-pest_meta = { path = "../meta", version = "2.7.2" }
+pest = { path = "../pest", version = "2.7.3", default-features = false }
+pest_meta = { path = "../meta", version = "2.7.3" }
 proc-macro2 = "1.0"
 quote = "1.0"
 syn = "2.0"
diff --git a/grammars/Cargo.toml b/grammars/Cargo.toml
index 9cc543b..3d774ed 100644
--- a/grammars/Cargo.toml
+++ b/grammars/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "pest_grammars"
 description = "pest popular grammar implementations"
-version = "2.7.2"
+version = "2.7.3"
 edition = "2021"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest.rs/"
@@ -14,8 +14,8 @@ readme = "_README.md"
 rust-version = "1.60"
 
 [dependencies]
-pest = { path = "../pest", version = "2.7.2" }
-pest_derive = { path = "../derive", version = "2.7.2" }
+pest = { path = "../pest", version = "2.7.3" }
+pest_derive = { path = "../derive", version = "2.7.3" }
 
 [dev-dependencies]
 criterion = "0.5"
diff --git a/meta/Cargo.toml b/meta/Cargo.toml
index 5aa93d1..d43e94b 100644
--- a/meta/Cargo.toml
+++ b/meta/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "pest_meta"
 description = "pest meta language parser and validator"
-version = "2.7.2"
+version = "2.7.3"
 edition = "2021"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest.rs/"
@@ -16,12 +16,12 @@ include = ["Cargo.toml", "src/**/*", "src/grammar.rs", "_README.md", "LICENSE-*"
 rust-version = "1.60"
 
 [dependencies]
-pest = { path = "../pest", version = "2.7.2" }
+pest = { path = "../pest", version = "2.7.3" }
 once_cell = "1.8.0"
 
 [build-dependencies]
 sha2 = { version = "0.10", default-features = false }
-cargo = { version = "0.70", optional = true }
+cargo = { version = "0.72.2", optional = true }
 
 [features]
 default = []
diff --git a/meta/src/parser.rs b/meta/src/parser.rs
index a4e8d1b..c1768e3 100644
--- a/meta/src/parser.rs
+++ b/meta/src/parser.rs
@@ -453,187 +453,182 @@ fn consume_expr<'i>(
                     x => unreachable!("other rule: {:?}", x),
                 };
 
-                pairs.fold(
-                    Ok(node),
-                    |node: Result<ParserNode<'i>, Vec<Error<Rule>>>, pair| {
-                        let node = node?;
-
-                        let node = match pair.as_rule() {
-                            Rule::optional_operator => {
-                                let start = node.span.start_pos();
-                                ParserNode {
-                                    expr: ParserExpr::Opt(Box::new(node)),
-                                    span: start.span(&pair.as_span().end_pos()),
-                                }
+                pairs.try_fold(node, |node: ParserNode<'i>, pair: Pair<'i, Rule>| {
+                    let node = match pair.as_rule() {
+                        Rule::optional_operator => {
+                            let start = node.span.start_pos();
+                            ParserNode {
+                                expr: ParserExpr::Opt(Box::new(node)),
+                                span: start.span(&pair.as_span().end_pos()),
                             }
-                            Rule::repeat_operator => {
-                                let start = node.span.start_pos();
-                                ParserNode {
-                                    expr: ParserExpr::Rep(Box::new(node)),
-                                    span: start.span(&pair.as_span().end_pos()),
-                                }
+                        }
+                        Rule::repeat_operator => {
+                            let start = node.span.start_pos();
+                            ParserNode {
+                                expr: ParserExpr::Rep(Box::new(node)),
+                                span: start.span(&pair.as_span().end_pos()),
                             }
-                            Rule::repeat_once_operator => {
-                                let start = node.span.start_pos();
-                                ParserNode {
-                                    expr: ParserExpr::RepOnce(Box::new(node)),
-                                    span: start.span(&pair.as_span().end_pos()),
-                                }
+                        }
+                        Rule::repeat_once_operator => {
+                            let start = node.span.start_pos();
+                            ParserNode {
+                                expr: ParserExpr::RepOnce(Box::new(node)),
+                                span: start.span(&pair.as_span().end_pos()),
                             }
-                            Rule::repeat_exact => {
-                                let mut inner = pair.clone().into_inner();
-
-                                inner.next().unwrap(); // opening_brace
-
-                                let number = inner.next().unwrap();
-                                let num = if let Ok(num) = number.as_str().parse::<u32>() {
-                                    num
-                                } else {
-                                    return Err(vec![Error::new_from_span(
-                                        ErrorVariant::CustomError {
-                                            message: "number cannot overflow u32".to_owned(),
-                                        },
-                                        number.as_span(),
-                                    )]);
-                                };
-
-                                if num == 0 {
-                                    let error: Error<Rule> = Error::new_from_span(
-                                        ErrorVariant::CustomError {
-                                            message: "cannot repeat 0 times".to_owned(),
-                                        },
-                                        number.as_span(),
-                                    );
-
-                                    return Err(vec![error]);
-                                }
-
-                                let start = node.span.start_pos();
-                                ParserNode {
-                                    expr: ParserExpr::RepExact(Box::new(node), num),
-                                    span: start.span(&pair.as_span().end_pos()),
-                                }
+                        }
+                        Rule::repeat_exact => {
+                            let mut inner = pair.clone().into_inner();
+
+                            inner.next().unwrap(); // opening_brace
+
+                            let number = inner.next().unwrap();
+                            let num = if let Ok(num) = number.as_str().parse::<u32>() {
+                                num
+                            } else {
+                                return Err(vec![Error::new_from_span(
+                                    ErrorVariant::CustomError {
+                                        message: "number cannot overflow u32".to_owned(),
+                                    },
+                                    number.as_span(),
+                                )]);
+                            };
+
+                            if num == 0 {
+                                let error: Error<Rule> = Error::new_from_span(
+                                    ErrorVariant::CustomError {
+                                        message: "cannot repeat 0 times".to_owned(),
+                                    },
+                                    number.as_span(),
+                                );
+
+                                return Err(vec![error]);
                             }
-                            Rule::repeat_min => {
-                                let mut inner = pair.clone().into_inner();
-
-                                inner.next().unwrap(); // opening_brace
-
-                                let min_number = inner.next().unwrap();
-                                let min = if let Ok(min) = min_number.as_str().parse::<u32>() {
-                                    min
-                                } else {
-                                    return Err(vec![Error::new_from_span(
-                                        ErrorVariant::CustomError {
-                                            message: "number cannot overflow u32".to_owned(),
-                                        },
-                                        min_number.as_span(),
-                                    )]);
-                                };
-
-                                let start = node.span.start_pos();
-                                ParserNode {
-                                    expr: ParserExpr::RepMin(Box::new(node), min),
-                                    span: start.span(&pair.as_span().end_pos()),
-                                }
+
+                            let start = node.span.start_pos();
+                            ParserNode {
+                                expr: ParserExpr::RepExact(Box::new(node), num),
+                                span: start.span(&pair.as_span().end_pos()),
                             }
-                            Rule::repeat_max => {
-                                let mut inner = pair.clone().into_inner();
-
-                                inner.next().unwrap(); // opening_brace
-                                inner.next().unwrap(); // comma
-
-                                let max_number = inner.next().unwrap();
-                                let max = if let Ok(max) = max_number.as_str().parse::<u32>() {
-                                    max
-                                } else {
-                                    return Err(vec![Error::new_from_span(
-                                        ErrorVariant::CustomError {
-                                            message: "number cannot overflow u32".to_owned(),
-                                        },
-                                        max_number.as_span(),
-                                    )]);
-                                };
-
-                                if max == 0 {
-                                    let error: Error<Rule> = Error::new_from_span(
-                                        ErrorVariant::CustomError {
-                                            message: "cannot repeat 0 times".to_owned(),
-                                        },
-                                        max_number.as_span(),
-                                    );
-
-                                    return Err(vec![error]);
-                                }
-
-                                let start = node.span.start_pos();
-                                ParserNode {
-                                    expr: ParserExpr::RepMax(Box::new(node), max),
-                                    span: start.span(&pair.as_span().end_pos()),
-                                }
+                        }
+                        Rule::repeat_min => {
+                            let mut inner = pair.clone().into_inner();
+
+                            inner.next().unwrap(); // opening_brace
+
+                            let min_number = inner.next().unwrap();
+                            let min = if let Ok(min) = min_number.as_str().parse::<u32>() {
+                                min
+                            } else {
+                                return Err(vec![Error::new_from_span(
+                                    ErrorVariant::CustomError {
+                                        message: "number cannot overflow u32".to_owned(),
+                                    },
+                                    min_number.as_span(),
+                                )]);
+                            };
+
+                            let start = node.span.start_pos();
+                            ParserNode {
+                                expr: ParserExpr::RepMin(Box::new(node), min),
+                                span: start.span(&pair.as_span().end_pos()),
                             }
-                            Rule::repeat_min_max => {
-                                let mut inner = pair.clone().into_inner();
-
-                                inner.next().unwrap(); // opening_brace
-
-                                let min_number = inner.next().unwrap();
-                                let min = if let Ok(min) = min_number.as_str().parse::<u32>() {
-                                    min
-                                } else {
-                                    return Err(vec![Error::new_from_span(
-                                        ErrorVariant::CustomError {
-                                            message: "number cannot overflow u32".to_owned(),
-                                        },
-                                        min_number.as_span(),
-                                    )]);
-                                };
-
-                                inner.next().unwrap(); // comma
-
-                                let max_number = inner.next().unwrap();
-                                let max = if let Ok(max) = max_number.as_str().parse::<u32>() {
-                                    max
-                                } else {
-                                    return Err(vec![Error::new_from_span(
-                                        ErrorVariant::CustomError {
-                                            message: "number cannot overflow u32".to_owned(),
-                                        },
-                                        max_number.as_span(),
-                                    )]);
-                                };
-
-                                if max == 0 {
-                                    let error: Error<Rule> = Error::new_from_span(
-                                        ErrorVariant::CustomError {
-                                            message: "cannot repeat 0 times".to_owned(),
-                                        },
-                                        max_number.as_span(),
-                                    );
-
-                                    return Err(vec![error]);
-                                }
-
-                                let start = node.span.start_pos();
-                                ParserNode {
-                                    expr: ParserExpr::RepMinMax(Box::new(node), min, max),
-                                    span: start.span(&pair.as_span().end_pos()),
-                                }
+                        }
+                        Rule::repeat_max => {
+                            let mut inner = pair.clone().into_inner();
+
+                            inner.next().unwrap(); // opening_brace
+                            inner.next().unwrap(); // comma
+
+                            let max_number = inner.next().unwrap();
+                            let max = if let Ok(max) = max_number.as_str().parse::<u32>() {
+                                max
+                            } else {
+                                return Err(vec![Error::new_from_span(
+                                    ErrorVariant::CustomError {
+                                        message: "number cannot overflow u32".to_owned(),
+                                    },
+                                    max_number.as_span(),
+                                )]);
+                            };
+
+                            if max == 0 {
+                                let error: Error<Rule> = Error::new_from_span(
+                                    ErrorVariant::CustomError {
+                                        message: "cannot repeat 0 times".to_owned(),
+                                    },
+                                    max_number.as_span(),
+                                );
+
+                                return Err(vec![error]);
                             }
-                            Rule::closing_paren => {
-                                let start = node.span.start_pos();
 
-                                ParserNode {
-                                    expr: node.expr,
-                                    span: start.span(&pair.as_span().end_pos()),
-                                }
+                            let start = node.span.start_pos();
+                            ParserNode {
+                                expr: ParserExpr::RepMax(Box::new(node), max),
+                                span: start.span(&pair.as_span().end_pos()),
+                            }
+                        }
+                        Rule::repeat_min_max => {
+                            let mut inner = pair.clone().into_inner();
+
+                            inner.next().unwrap(); // opening_brace
+
+                            let min_number = inner.next().unwrap();
+                            let min = if let Ok(min) = min_number.as_str().parse::<u32>() {
+                                min
+                            } else {
+                                return Err(vec![Error::new_from_span(
+                                    ErrorVariant::CustomError {
+                                        message: "number cannot overflow u32".to_owned(),
+                                    },
+                                    min_number.as_span(),
+                                )]);
+                            };
+
+                            inner.next().unwrap(); // comma
+
+                            let max_number = inner.next().unwrap();
+                            let max = if let Ok(max) = max_number.as_str().parse::<u32>() {
+                                max
+                            } else {
+                                return Err(vec![Error::new_from_span(
+                                    ErrorVariant::CustomError {
+                                        message: "number cannot overflow u32".to_owned(),
+                                    },
+                                    max_number.as_span(),
+                                )]);
+                            };
+
+                            if max == 0 {
+                                let error: Error<Rule> = Error::new_from_span(
+                                    ErrorVariant::CustomError {
+                                        message: "cannot repeat 0 times".to_owned(),
+                                    },
+                                    max_number.as_span(),
+                                );
+
+                                return Err(vec![error]);
                             }
-                            rule => unreachable!("node: {:?}", rule),
-                        };
 
-                        Ok(node)
-                    },
-                )?
+                            let start = node.span.start_pos();
+                            ParserNode {
+                                expr: ParserExpr::RepMinMax(Box::new(node), min, max),
+                                span: start.span(&pair.as_span().end_pos()),
+                            }
+                        }
+                        Rule::closing_paren => {
+                            let start = node.span.start_pos();
+
+                            ParserNode {
+                                expr: node.expr,
+                                span: start.span(&pair.as_span().end_pos()),
+                            }
+                        }
+                        rule => unreachable!("node: {:?}", rule),
+                    };
+
+                    Ok(node)
+                })?
             }
         };
         #[cfg(feature = "grammar-extras")]
@@ -1471,11 +1466,11 @@ mod tests {
 
     #[test]
     fn ast() {
-        let input = r##"
+        let input = r#"
         /// This is line comment
         /// This is rule
         rule = _{ a{1} ~ "a"{3,} ~ b{, 2} ~ "b"{1, 2} | !(^"c" | PUSH('d'..'e'))?* }
-        "##;
+        "#;
 
         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
         let ast = consume_rules_with_spans(pairs).unwrap();
diff --git a/pest/Cargo.toml b/pest/Cargo.toml
index aa3e131..023c576 100644
--- a/pest/Cargo.toml
+++ b/pest/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "pest"
 description = "The Elegant Parser"
-version = "2.7.2"
+version = "2.7.3"
 edition = "2021"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest.rs/"
@@ -14,7 +14,7 @@ readme = "_README.md"
 rust-version = "1.60"
 
 [features]
-default = ["std"]
+default = ["std", "memchr"]
 # Implements `std::error::Error` for the `Error` type
 std = ["ucd-trie/std", "dep:thiserror"]
 # Enables the `to_json` function for `Pair` and `Pairs`
diff --git a/pest/src/error.rs b/pest/src/error.rs
index df3f544..dfd89f6 100644
--- a/pest/src/error.rs
+++ b/pest/src/error.rs
@@ -570,13 +570,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 2:2",
                 "  |",
                 "2 | cd",
                 "  |  ^---",
                 "  |",
-                "  = unexpected 4, 5, or 6; expected 1, 2, or 3",
+                "  = unexpected 4, 5, or 6; expected 1, 2, or 3"
             ]
             .join("\n")
         );
@@ -596,13 +596,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 2:2",
                 "  |",
                 "2 | cd",
                 "  |  ^---",
                 "  |",
-                "  = expected 1 or 2",
+                "  = expected 1 or 2"
             ]
             .join("\n")
         );
@@ -622,13 +622,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 2:2",
                 "  |",
                 "2 | cd",
                 "  |  ^---",
                 "  |",
-                "  = unexpected 4, 5, or 6",
+                "  = unexpected 4, 5, or 6"
             ]
             .join("\n")
         );
@@ -648,13 +648,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 2:2",
                 "  |",
                 "2 | cd",
                 "  |  ^---",
                 "  |",
-                "  = unknown parsing error",
+                "  = unknown parsing error"
             ]
             .join("\n")
         );
@@ -673,13 +673,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 2:2",
                 "  |",
                 "2 | cd",
                 "  |  ^---",
                 "  |",
-                "  = error: big one",
+                "  = error: big one"
             ]
             .join("\n")
         );
@@ -699,14 +699,14 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 2:2",
                 "  |",
                 "2 | cd",
                 "3 | efgh",
                 "  |  ^^",
                 "  |",
-                "  = error: big one",
+                "  = error: big one"
             ]
             .join("\n")
         );
@@ -726,7 +726,7 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 1:2",
                 "  |",
                 "1 | ab",
@@ -734,7 +734,7 @@ mod tests {
                 "3 | efgh",
                 "  |  ^^",
                 "  |",
-                "  = error: big one",
+                "  = error: big one"
             ]
             .join("\n")
         );
@@ -754,14 +754,14 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 1:6",
                 "  |",
                 "1 | abcdef",
                 "2 | gh",
                 "  | ^----^",
                 "  |",
-                "  = error: big one",
+                "  = error: big one"
             ]
             .join("\n")
         );
@@ -784,13 +784,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 1:1",
                 "  |",
                 "1 | abcdef␊",
                 "  | ^-----^",
                 "  |",
-                "  = error: big one",
+                "  = error: big one"
             ]
             .join("\n")
         );
@@ -813,13 +813,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 1:1",
                 "  |",
                 "1 | ",
                 "  | ^",
                 "  |",
-                "  = error: empty",
+                "  = error: empty"
             ]
             .join("\n")
         );
@@ -840,13 +840,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> 2:2",
                 "  |",
                 "2 | cd",
                 "  |  ^---",
                 "  |",
-                "  = unexpected 5, 6, or 7; expected 2, 3, or 4",
+                "  = unexpected 5, 6, or 7; expected 2, 3, or 4"
             ]
             .join("\n")
         );
@@ -867,13 +867,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> file.rs:2:2",
                 "  |",
                 "2 | cd",
                 "  |  ^---",
                 "  |",
-                "  = unexpected 4, 5, or 6; expected 1, 2, or 3",
+                "  = unexpected 4, 5, or 6; expected 1, 2, or 3"
             ]
             .join("\n")
         );
@@ -894,13 +894,13 @@ mod tests {
 
         assert_eq!(
             format!("{}", error),
-            vec![
+            [
                 " --> file.rs:1:3",
                 "  |",
                 "1 | a	xbc",
                 "  |  	^---",
                 "  |",
-                "  = unexpected 4, 5, or 6; expected 1, 2, or 3",
+                "  = unexpected 4, 5, or 6; expected 1, 2, or 3"
             ]
             .join("\n")
         );
diff --git a/pest/src/iterators/pairs.rs b/pest/src/iterators/pairs.rs
index 44023f2..73c49b7 100644
--- a/pest/src/iterators/pairs.rs
+++ b/pest/src/iterators/pairs.rs
@@ -661,6 +661,8 @@ mod tests {
     }
 
     #[test]
+    // false positive: pest uses `..` as a complete range (historically)
+    #[allow(clippy::almost_complete_range)]
     fn test_tag_node_branch() {
         use crate::{state, ParseResult, ParserState};
         #[allow(non_camel_case_types)]
diff --git a/vm/Cargo.toml b/vm/Cargo.toml
index 2ce176b..9261eef 100644
--- a/vm/Cargo.toml
+++ b/vm/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "pest_vm"
 description = "pest grammar virtual machine"
-version = "2.7.2"
+version = "2.7.3"
 edition = "2021"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest.rs/"
@@ -14,8 +14,8 @@ readme = "_README.md"
 rust-version = "1.60"
 
 [dependencies]
-pest = { path = "../pest", version = "2.7.2" }
-pest_meta = { path = "../meta", version = "2.7.2" }
+pest = { path = "../pest", version = "2.7.3" }
+pest_meta = { path = "../meta", version = "2.7.3" }
 
 [features]
 grammar-extras = ["pest_meta/grammar-extras"]
\ No newline at end of file


Test patch:
diff --git a/pest/tests/calculator.rs b/pest/tests/calculator.rs
index c527055..e667133 100644
--- a/pest/tests/calculator.rs
+++ b/pest/tests/calculator.rs
@@ -32,6 +32,8 @@ enum Rule {
 struct CalculatorParser;
 
 impl Parser<Rule> for CalculatorParser {
+    // false positive: pest uses `..` as a complete range (historically)
+    #[allow(clippy::almost_complete_range)]
     fn parse(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
         fn expression(
             state: Box<ParserState<'_, Rule>>,
diff --git a/pest/tests/json.rs b/pest/tests/json.rs
index b66f39d..be64057 100644
--- a/pest/tests/json.rs
+++ b/pest/tests/json.rs
@@ -38,6 +38,8 @@ enum Rule {
 struct JsonParser;
 
 impl Parser<Rule> for JsonParser {
+    // false positive: pest uses `..` as a complete range (historically)
+    #[allow(clippy::almost_complete_range)]
     fn parse(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
         fn json(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
             value(state)