Repository: pest-parser/pest (language: rust)

Issue:
Migrate to 2018 edition
We should probably migrate a bit before it is released on stable.


Discussion / hints:
Any update on this?
I did a quick look into what might need to happen to migrate to the 2018 edition (literally by just trying to build the project with edition = "2018"). I found the errors mostly looked to boil down to differences in how use statements work.

The next steps look to be to work through the compiler errors and identify any roadblocks along the way.

I noticed that the majority of the tests fail in the master branch in its current state which makes completing this sort of change more difficult. It may be worth investigating that first before jumping into this change.


Fix patch:
diff --git a/bootstrap/Cargo.toml b/bootstrap/Cargo.toml
index a5d32611..90932fff 100644
--- a/bootstrap/Cargo.toml
+++ b/bootstrap/Cargo.toml
@@ -2,6 +2,7 @@
 name = "pest_bootstrap"
 description = "pest bootstrap script"
 version = "0.0.0"
+edition = "2018"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest-parser.github.io/"
 repository = "https://github.com/pest-parser/pest"
diff --git a/derive/Cargo.toml b/derive/Cargo.toml
index d672460b..c6d4602e 100644
--- a/derive/Cargo.toml
+++ b/derive/Cargo.toml
@@ -2,6 +2,7 @@
 name = "pest_derive"
 description = "pest's derive macro"
 version = "2.1.0"
+edition = "2018"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest-parser.github.io/"
 repository = "https://github.com/pest-parser/pest"
diff --git a/generator/Cargo.toml b/generator/Cargo.toml
index 8b7aa730..2aca50a2 100644
--- a/generator/Cargo.toml
+++ b/generator/Cargo.toml
@@ -2,6 +2,7 @@
 name = "pest_generator"
 description = "pest code generator"
 version = "2.1.4"
+edition = "2018"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest-parser.github.io/"
 repository = "https://github.com/pest-parser/pest"
diff --git a/grammars/Cargo.toml b/grammars/Cargo.toml
index 628ec8aa..6a745b73 100644
--- a/grammars/Cargo.toml
+++ b/grammars/Cargo.toml
@@ -2,6 +2,7 @@
 name = "pest_grammars"
 description = "pest popular grammar implementations"
 version = "2.1.0"
+edition = "2018"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest-parser.github.io/"
 repository = "https://github.com/pest-parser/pest"
@@ -14,3 +15,10 @@ readme = "_README.md"
 [dependencies]
 pest = { path = "../pest", version = "2.1.0" }
 pest_derive = { path = "../derive", version = "2.1.0" }
+
+[dev-dependencies]
+bencher = "0.1"
+
+[[bench]]
+name = "json"
+harness = false
\ No newline at end of file
diff --git a/grammars/benches/json.rs b/grammars/benches/json.rs
index c138bc42..c45eff05 100644
--- a/grammars/benches/json.rs
+++ b/grammars/benches/json.rs
@@ -7,22 +7,18 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-#![feature(test)]
-
+extern crate bencher;
 extern crate pest;
 extern crate pest_grammars;
-extern crate test;
+use bencher::{benchmark_group, benchmark_main, Bencher};
 
 use std::fs::File;
 use std::io::Read;
 
-use test::Bencher;
-
 use pest::Parser;
 
 use pest_grammars::json::*;
 
-#[bench]
 fn data(b: &mut Bencher) {
     let mut file = File::open("benches/data.json").unwrap();
     let mut data = String::new();
@@ -31,3 +27,6 @@ fn data(b: &mut Bencher) {
 
     b.iter(|| JsonParser::parse(Rule::json, &data).unwrap());
 }
+
+benchmark_group!(benches, data);
+benchmark_main!(benches);
diff --git a/meta/Cargo.toml b/meta/Cargo.toml
index ab6cdc36..de414fde 100644
--- a/meta/Cargo.toml
+++ b/meta/Cargo.toml
@@ -2,6 +2,7 @@
 name = "pest_meta"
 description = "pest meta language parser and validator"
 version = "2.1.3"
+edition = "2018"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest-parser.github.io/"
 repository = "https://github.com/pest-parser/pest"
diff --git a/meta/src/optimizer/concatenator.rs b/meta/src/optimizer/concatenator.rs
index 8ff7590c..31d3aa53 100644
--- a/meta/src/optimizer/concatenator.rs
+++ b/meta/src/optimizer/concatenator.rs
@@ -7,7 +7,7 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-use ast::*;
+use crate::ast::*;
 
 pub fn concatenate(rule: Rule) -> Rule {
     let Rule { name, ty, expr } = rule;
diff --git a/meta/src/optimizer/factorizer.rs b/meta/src/optimizer/factorizer.rs
index 573f566f..5481870b 100644
--- a/meta/src/optimizer/factorizer.rs
+++ b/meta/src/optimizer/factorizer.rs
@@ -7,7 +7,7 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-use ast::*;
+use crate::ast::*;
 
 pub fn factor(rule: Rule) -> Rule {
     let Rule { name, ty, expr } = rule;
diff --git a/meta/src/optimizer/lister.rs b/meta/src/optimizer/lister.rs
index 4ca2830a..e1988503 100644
--- a/meta/src/optimizer/lister.rs
+++ b/meta/src/optimizer/lister.rs
@@ -7,7 +7,7 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-use ast::*;
+use crate::ast::*;
 
 pub fn list(rule: Rule) -> Rule {
     let Rule { name, ty, expr } = rule;
diff --git a/meta/src/optimizer/mod.rs b/meta/src/optimizer/mod.rs
index 0712fbec..e0cbdb0d 100644
--- a/meta/src/optimizer/mod.rs
+++ b/meta/src/optimizer/mod.rs
@@ -7,7 +7,7 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-use ast::*;
+use crate::ast::*;
 use std::collections::HashMap;
 
 #[cfg(test)]
@@ -281,7 +281,7 @@ mod tests {
     #[test]
     fn rotate() {
         let rules = {
-            use ast::Expr::*;
+            use crate::ast::Expr::*;
             vec![Rule {
                 name: "rule".to_owned(),
                 ty: RuleType::Normal,
@@ -295,7 +295,7 @@ mod tests {
             }]
         };
         let rotated = {
-            use optimizer::OptimizedExpr::*;
+            use crate::optimizer::OptimizedExpr::*;
             vec![OptimizedRule {
                 name: "rule".to_owned(),
                 ty: RuleType::Normal,
@@ -315,7 +315,7 @@ mod tests {
     #[test]
     fn skip() {
         let rules = {
-            use ast::Expr::*;
+            use crate::ast::Expr::*;
             vec![Rule {
                 name: "rule".to_owned(),
                 ty: RuleType::Atomic,
@@ -337,7 +337,7 @@ mod tests {
     #[test]
     fn concat_strings() {
         let rules = {
-            use ast::Expr::*;
+            use crate::ast::Expr::*;
             vec![Rule {
                 name: "rule".to_owned(),
                 ty: RuleType::Atomic,
@@ -364,7 +364,7 @@ mod tests {
             expr: Expr::RepExact(Box::new(Expr::Ident(String::from("a"))), 3),
         }];
         let unrolled = {
-            use optimizer::OptimizedExpr::*;
+            use crate::optimizer::OptimizedExpr::*;
             vec![OptimizedRule {
                 name: "rule".to_owned(),
                 ty: RuleType::Atomic,
@@ -386,7 +386,7 @@ mod tests {
             expr: Expr::RepMax(Box::new(Expr::Str("a".to_owned())), 3),
         }];
         let unrolled = {
-            use optimizer::OptimizedExpr::*;
+            use crate::optimizer::OptimizedExpr::*;
             vec![OptimizedRule {
                 name: "rule".to_owned(),
                 ty: RuleType::Atomic,
@@ -408,7 +408,7 @@ mod tests {
             expr: Expr::RepMin(Box::new(Expr::Str("a".to_owned())), 2),
         }];
         let unrolled = {
-            use optimizer::OptimizedExpr::*;
+            use crate::optimizer::OptimizedExpr::*;
             vec![OptimizedRule {
                 name: "rule".to_owned(),
                 ty: RuleType::Atomic,
@@ -430,7 +430,7 @@ mod tests {
             expr: Expr::RepMinMax(Box::new(Expr::Str("a".to_owned())), 2, 3),
         }];
         let unrolled = {
-            use optimizer::OptimizedExpr::*;
+            use crate::optimizer::OptimizedExpr::*;
             vec![OptimizedRule {
                 name: "rule".to_owned(),
                 ty: RuleType::Atomic,
@@ -454,7 +454,7 @@ mod tests {
     #[test]
     fn concat_insensitive_strings() {
         let rules = {
-            use ast::Expr::*;
+            use crate::ast::Expr::*;
             vec![Rule {
                 name: "rule".to_owned(),
                 ty: RuleType::Atomic,
@@ -476,7 +476,7 @@ mod tests {
     #[test]
     fn long_common_sequence() {
         let rules = {
-            use ast::Expr::*;
+            use crate::ast::Expr::*;
             vec![Rule {
                 name: "rule".to_owned(),
                 ty: RuleType::Silent,
@@ -493,7 +493,7 @@ mod tests {
             }]
         };
         let optimized = {
-            use optimizer::OptimizedExpr::*;
+            use crate::optimizer::OptimizedExpr::*;
             vec![OptimizedRule {
                 name: "rule".to_owned(),
                 ty: RuleType::Silent,
@@ -513,7 +513,7 @@ mod tests {
     #[test]
     fn short_common_sequence() {
         let rules = {
-            use ast::Expr::*;
+            use crate::ast::Expr::*;
             vec![Rule {
                 name: "rule".to_owned(),
                 ty: RuleType::Silent,
@@ -524,7 +524,7 @@ mod tests {
             }]
         };
         let optimized = {
-            use optimizer::OptimizedExpr::*;
+            use crate::optimizer::OptimizedExpr::*;
             vec![OptimizedRule {
                 name: "rule".to_owned(),
                 ty: RuleType::Silent,
@@ -538,7 +538,7 @@ mod tests {
     #[test]
     fn impossible_common_sequence() {
         let rules = {
-            use ast::Expr::*;
+            use crate::ast::Expr::*;
             vec![Rule {
                 name: "rule".to_owned(),
                 ty: RuleType::Silent,
@@ -549,7 +549,7 @@ mod tests {
             }]
         };
         let optimized = {
-            use optimizer::OptimizedExpr::*;
+            use crate::optimizer::OptimizedExpr::*;
             vec![OptimizedRule {
                 name: "rule".to_owned(),
                 ty: RuleType::Silent,
@@ -563,7 +563,7 @@ mod tests {
     #[test]
     fn lister() {
         let rules = {
-            use ast::Expr::*;
+            use crate::ast::Expr::*;
             vec![Rule {
                 name: "rule".to_owned(),
                 ty: RuleType::Silent,
@@ -574,7 +574,7 @@ mod tests {
             }]
         };
         let optimized = {
-            use optimizer::OptimizedExpr::*;
+            use crate::optimizer::OptimizedExpr::*;
             vec![OptimizedRule {
                 name: "rule".to_owned(),
                 ty: RuleType::Silent,
diff --git a/meta/src/optimizer/restorer.rs b/meta/src/optimizer/restorer.rs
index fd67790e..e128e03f 100644
--- a/meta/src/optimizer/restorer.rs
+++ b/meta/src/optimizer/restorer.rs
@@ -8,7 +8,7 @@
 // modified, or distributed except according to those terms.
 use std::collections::HashMap;
 
-use optimizer::*;
+use crate::optimizer::*;
 
 pub fn restore_on_err(
     rule: OptimizedRule,
@@ -92,7 +92,7 @@ fn child_modifies_state(
 #[cfg(test)]
 mod tests {
     use super::*;
-    use optimizer::OptimizedExpr::*;
+    use crate::optimizer::OptimizedExpr::*;
 
     #[test]
     fn restore_no_stack_children() {
diff --git a/meta/src/optimizer/rotater.rs b/meta/src/optimizer/rotater.rs
index f313ae06..7a7d8fba 100644
--- a/meta/src/optimizer/rotater.rs
+++ b/meta/src/optimizer/rotater.rs
@@ -7,7 +7,7 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-use ast::*;
+use crate::ast::*;
 
 pub fn rotate(rule: Rule) -> Rule {
     fn rotate_internal(expr: Expr) -> Expr {
diff --git a/meta/src/optimizer/skipper.rs b/meta/src/optimizer/skipper.rs
index cad31246..40bc5a16 100644
--- a/meta/src/optimizer/skipper.rs
+++ b/meta/src/optimizer/skipper.rs
@@ -7,7 +7,7 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-use ast::*;
+use crate::ast::*;
 
 pub fn skip(rule: Rule) -> Rule {
     fn populate_choices(expr: Expr, mut choices: Vec<String>) -> Option<Expr> {
diff --git a/meta/src/optimizer/unroller.rs b/meta/src/optimizer/unroller.rs
index b1e84e40..e3c360d9 100644
--- a/meta/src/optimizer/unroller.rs
+++ b/meta/src/optimizer/unroller.rs
@@ -7,7 +7,7 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-use ast::*;
+use crate::ast::*;
 
 pub fn unroll(rule: Rule) -> Rule {
     let Rule { name, ty, expr } = rule;
diff --git a/meta/src/parser.rs b/meta/src/parser.rs
index 8d8abbf0..3d75b95a 100644
--- a/meta/src/parser.rs
+++ b/meta/src/parser.rs
@@ -15,8 +15,8 @@ use pest::iterators::{Pair, Pairs};
 use pest::prec_climber::{Assoc, Operator, PrecClimber};
 use pest::{Parser, Span};
 
-use ast::{Expr, Rule as AstRule, RuleType};
-use validator;
+use crate::ast::{Expr, Rule as AstRule, RuleType};
+use crate::validator;
 
 mod grammar {
     #![allow(unknown_lints, clippy::all)]
diff --git a/meta/src/validator.rs b/meta/src/validator.rs
index 0a6535b3..5b8e8698 100644
--- a/meta/src/validator.rs
+++ b/meta/src/validator.rs
@@ -13,8 +13,8 @@ use pest::error::{Error, ErrorVariant, InputLocation};
 use pest::iterators::Pairs;
 use pest::Span;
 
-use parser::{ParserExpr, ParserNode, ParserRule, Rule};
-use UNICODE_PROPERTY_NAMES;
+use crate::parser::{ParserExpr, ParserNode, ParserRule, Rule};
+use crate::UNICODE_PROPERTY_NAMES;
 
 #[allow(clippy::needless_pass_by_value)]
 pub fn validate_pairs(pairs: Pairs<Rule>) -> Result<Vec<&str>, Vec<Error<Rule>>> {
diff --git a/pest/Cargo.toml b/pest/Cargo.toml
index 9d4a2ae3..d5b52e09 100644
--- a/pest/Cargo.toml
+++ b/pest/Cargo.toml
@@ -2,6 +2,7 @@
 name = "pest"
 description = "The Elegant Parser"
 version = "2.1.3"
+edition = "2018"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest-parser.github.io/"
 repository = "https://github.com/pest-parser/pest"
diff --git a/pest/src/error.rs b/pest/src/error.rs
index 312768b4..c208e6d3 100644
--- a/pest/src/error.rs
+++ b/pest/src/error.rs
@@ -19,9 +19,9 @@ use core::cmp;
 use core::fmt;
 use core::mem;
 
-use position::Position;
-use span::Span;
-use RuleType;
+use crate::position::Position;
+use crate::span::Span;
+use crate::RuleType;
 
 /// Parse-related error type.
 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
diff --git a/pest/src/iterators/flat_pairs.rs b/pest/src/iterators/flat_pairs.rs
index 3af60124..85171a3b 100644
--- a/pest/src/iterators/flat_pairs.rs
+++ b/pest/src/iterators/flat_pairs.rs
@@ -14,7 +14,7 @@ use core::fmt;
 use super::pair::{self, Pair};
 use super::queueable_token::QueueableToken;
 use super::tokens::{self, Tokens};
-use RuleType;
+use crate::RuleType;
 
 /// An iterator over [`Pair`]s. It is created by [`Pairs::flatten`].
 ///
diff --git a/pest/src/iterators/pair.rs b/pest/src/iterators/pair.rs
index 2794c63c..0a8f735a 100644
--- a/pest/src/iterators/pair.rs
+++ b/pest/src/iterators/pair.rs
@@ -23,8 +23,8 @@ use serde::ser::SerializeStruct;
 use super::pairs::{self, Pairs};
 use super::queueable_token::QueueableToken;
 use super::tokens::{self, Tokens};
-use span::{self, Span};
-use RuleType;
+use crate::span::{self, Span};
+use crate::RuleType;
 
 /// A matching pair of [`Token`]s and everything between them.
 ///
@@ -347,8 +347,8 @@ impl<'i, R: RuleType> ::serde::Serialize for Pair<'i, R> {
 
 #[cfg(test)]
 mod tests {
-    use macros::tests::*;
-    use parser::Parser;
+    use crate::macros::tests::*;
+    use crate::parser::Parser;
 
     #[test]
     #[cfg(feature = "pretty-print")]
diff --git a/pest/src/iterators/pairs.rs b/pest/src/iterators/pairs.rs
index 8e164973..654b7dad 100644
--- a/pest/src/iterators/pairs.rs
+++ b/pest/src/iterators/pairs.rs
@@ -23,7 +23,7 @@ use super::flat_pairs::{self, FlatPairs};
 use super::pair::{self, Pair};
 use super::queueable_token::QueueableToken;
 use super::tokens::{self, Tokens};
-use RuleType;
+use crate::RuleType;
 
 /// An iterator over [`Pair`]s. It is created by [`pest::state`] and [`Pair::into_inner`].
 ///
diff --git a/pest/src/iterators/tokens.rs b/pest/src/iterators/tokens.rs
index 2cb73e1f..f21cf072 100644
--- a/pest/src/iterators/tokens.rs
+++ b/pest/src/iterators/tokens.rs
@@ -13,9 +13,9 @@ use core::fmt;
 use core::str;
 
 use super::queueable_token::QueueableToken;
-use position;
-use token::Token;
-use RuleType;
+use crate::position;
+use crate::token::Token;
+use crate::RuleType;
 
 /// An iterator over [`Token`]s. It is created by [`Pair::tokens`] and [`Pairs::tokens`].
 ///
diff --git a/pest/src/lib.rs b/pest/src/lib.rs
index 4506221b..00bdd4bc 100644
--- a/pest/src/lib.rs
+++ b/pest/src/lib.rs
@@ -75,13 +75,13 @@ extern crate serde;
 #[cfg(feature = "pretty-print")]
 extern crate serde_json;
 
+pub use crate::parser::Parser;
+pub use crate::parser_state::{state, Atomicity, Lookahead, MatchDir, ParseResult, ParserState};
+pub use crate::position::Position;
+pub use crate::span::{Lines, Span};
+pub use crate::token::Token;
 use core::fmt::Debug;
 use core::hash::Hash;
-pub use parser::Parser;
-pub use parser_state::{state, Atomicity, Lookahead, MatchDir, ParseResult, ParserState};
-pub use position::Position;
-pub use span::{Lines, Span};
-pub use token::Token;
 
 pub mod error;
 pub mod iterators;
diff --git a/pest/src/parser.rs b/pest/src/parser.rs
index a8792d15..8dd38141 100644
--- a/pest/src/parser.rs
+++ b/pest/src/parser.rs
@@ -7,9 +7,9 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-use error::Error;
-use iterators::Pairs;
-use RuleType;
+use crate::error::Error;
+use crate::iterators::Pairs;
+use crate::RuleType;
 
 /// A trait with a single method that parses strings.
 pub trait Parser<R: RuleType> {
diff --git a/pest/src/parser_state.rs b/pest/src/parser_state.rs
index ead92cac..2e214b56 100644
--- a/pest/src/parser_state.rs
+++ b/pest/src/parser_state.rs
@@ -13,12 +13,12 @@ use alloc::vec;
 use alloc::vec::Vec;
 use core::ops::Range;
 
-use error::{Error, ErrorVariant};
-use iterators::{pairs, QueueableToken};
-use position::{self, Position};
-use span::Span;
-use stack::Stack;
-use RuleType;
+use crate::error::{Error, ErrorVariant};
+use crate::iterators::{pairs, QueueableToken};
+use crate::position::{self, Position};
+use crate::span::Span;
+use crate::stack::Stack;
+use crate::RuleType;
 
 /// The current lookahead status of a [`ParserState`].
 ///
diff --git a/pest/src/position.rs b/pest/src/position.rs
index e634da5c..35edd78f 100644
--- a/pest/src/position.rs
+++ b/pest/src/position.rs
@@ -14,7 +14,7 @@ use core::ops::Range;
 use core::ptr;
 use core::str;
 
-use span;
+use crate::span;
 
 /// A cursor position in a `&str` which provides useful methods to manually parse that string.
 #[derive(Clone, Copy)]
diff --git a/pest/src/prec_climber.rs b/pest/src/prec_climber.rs
index e6237a95..d35bd52d 100644
--- a/pest/src/prec_climber.rs
+++ b/pest/src/prec_climber.rs
@@ -15,8 +15,8 @@ use alloc::vec::Vec;
 use core::iter::Peekable;
 use core::ops::BitOr;
 
-use iterators::Pair;
-use RuleType;
+use crate::iterators::Pair;
+use crate::RuleType;
 
 /// Macro for more convenient const fn definition of `prec_climber::PrecClimber`.
 ///
diff --git a/pest/src/span.rs b/pest/src/span.rs
index cd4f05e2..784626e5 100644
--- a/pest/src/span.rs
+++ b/pest/src/span.rs
@@ -12,7 +12,7 @@ use core::hash::{Hash, Hasher};
 use core::ptr;
 use core::str;
 
-use position;
+use crate::position;
 
 /// A span over a `&str`. It is created from either [two `Position`s] or from a [`Pair`].
 ///
@@ -265,6 +265,16 @@ mod tests {
     use alloc::borrow::ToOwned;
     use alloc::vec::Vec;
 
+    #[test]
+    fn span_comp() {
+        let input = "abc\ndef\nghi";
+        let span = Span::new(input, 1, 7).unwrap();
+        let span2 = Span::new(input, 50, 51);
+        assert!(span2.is_none());
+        let span3 = Span::new(input, 0, 8).unwrap();
+        assert!(span != span3);
+    }
+
     #[test]
     fn split() {
         let input = "a";
@@ -294,6 +304,7 @@ mod tests {
         let input = "abc\ndef\nghi";
         let span = Span::new(input, 5, 11).unwrap();
         assert!(span.end_pos().at_end());
+        assert_eq!(span.end(), 11);
         let lines: Vec<_> = span.lines().collect();
         //println!("{:?}", lines);
         assert_eq!(lines.len(), 2);
diff --git a/pest/src/token.rs b/pest/src/token.rs
index fbe544ab..68cb1a6e 100644
--- a/pest/src/token.rs
+++ b/pest/src/token.rs
@@ -7,7 +7,7 @@
 // option. All files in the project carrying such notice may not be copied,
 // modified, or distributed except according to those terms.
 
-use position::Position;
+use crate::position::Position;
 
 /// A token generated by a `Parser`.
 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
diff --git a/vm/Cargo.toml b/vm/Cargo.toml
index 33a6f2a5..92b3955a 100644
--- a/vm/Cargo.toml
+++ b/vm/Cargo.toml
@@ -2,6 +2,7 @@
 name = "pest_vm"
 description = "pest grammar virtual machine"
 version = "2.1.0"
+edition = "2018"
 authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
 homepage = "https://pest-parser.github.io/"
 repository = "https://github.com/pest-parser/pest"


Test patch: