The problem is that you are mixing up the lifetime of &self
with the lifetime of all the names. The most straightforward solution is to add a lifetime parameter to the Matcher
trait, to indicate the name lifetime.
diff --git a/src/matcher.rs b/src/matcher.rs
index acb08ea..0e54f3c 100644
--- a/src/matcher.rs
+++ b/src/matcher.rs
@@ -27,2 +27,2 @@ pub enum Pattern<'a> {
- Matcher(&'a dyn Matcher),
- Func(&'a dyn Fn(&'a ParserContext) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>>),
+ Matcher(Box<dyn Matcher<'a>>),
+ Func(Box<dyn Fn(&ParserContext<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>>>),
@@ -31,3 +31,3 @@ pub enum Pattern<'a> {
-pub trait Matcher {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure>;
- fn get_name(&self) -> &str;
+pub trait Matcher<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>>;
+ fn get_name(&self) -> &'a str;
diff --git a/src/matchers/break.rs b/src/matchers/break.rs
index b577e60..63aa99b 100644
--- a/src/matchers/break.rs
+++ b/src/matchers/break.rs
@@ -14,2 +14,2 @@ impl<'a> BreakPattern<'a> {
-impl<'a> Matcher for BreakPattern<'a> {
- fn exec(&self, _: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for BreakPattern<'a> {
+ fn exec(&self, _: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -22 +22 @@ impl<'a> Matcher for BreakPattern<'a> {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/debug.rs b/src/matchers/debug.rs
index 6eb77a5..298bbd1 100644
--- a/src/matchers/debug.rs
+++ b/src/matchers/debug.rs
@@ -6,2 +6,2 @@ use std::rc::Rc;
-pub struct DebugPattern {
- matcher: Option<Rc<RefCell<Box<dyn Matcher>>>>,
+pub struct DebugPattern<'a> {
+ matcher: Option<Rc<RefCell<Box<dyn Matcher<'a>>>>>,
@@ -11,2 +11,2 @@ pub struct DebugPattern {
-impl DebugPattern {
- pub fn new(matcher: Option<Box<dyn Matcher>>) -> Self {
+impl<'a> DebugPattern<'a> {
+ pub fn new(matcher: Option<Box<dyn Matcher<'a>>>) -> Self {
@@ -22 +22 @@ impl DebugPattern {
- pub fn new_with_debug_mode(matcher: Option<Box<dyn Matcher>>, debug_mode: usize) -> Self {
+ pub fn new_with_debug_mode(matcher: Option<Box<dyn Matcher<'a>>>, debug_mode: usize) -> Self {
@@ -33,2 +33,2 @@ impl DebugPattern {
-impl Matcher for DebugPattern {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for DebugPattern<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -72 +72 @@ impl Matcher for DebugPattern {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/discard.rs b/src/matchers/discard.rs
index a5952de..8f91b45 100644
--- a/src/matchers/discard.rs
+++ b/src/matchers/discard.rs
@@ -6,2 +6,2 @@ use crate::token::{StandardToken, TokenRef};
-pub struct DiscardPattern {
- matcher: Box<dyn Matcher>,
+pub struct DiscardPattern<'a> {
+ matcher: Box<dyn Matcher<'a>>,
@@ -10,2 +10,2 @@ pub struct DiscardPattern {
-impl DiscardPattern {
- pub fn new(matcher: Box<dyn Matcher>) -> Self {
+impl<'a> DiscardPattern<'a> {
+ pub fn new(matcher: Box<dyn Matcher<'a>>) -> Self {
@@ -35,2 +35,2 @@ fn collect_errors<'a, 'b>(error_token: TokenRef<'a>, walk_token: TokenRef<'a>) {
-impl Matcher for DiscardPattern {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for DiscardPattern<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -71 +71 @@ impl Matcher for DiscardPattern {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/error.rs b/src/matchers/error.rs
index f426bed..46866fd 100644
--- a/src/matchers/error.rs
+++ b/src/matchers/error.rs
@@ -16,2 +16,2 @@ impl<'a> ErrorPattern<'a> {
-impl<'a> Matcher for ErrorPattern<'a> {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for ErrorPattern<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -30 +30 @@ impl<'a> Matcher for ErrorPattern<'a> {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/fatal.rs b/src/matchers/fatal.rs
index e4985ac..ddf081c 100644
--- a/src/matchers/fatal.rs
+++ b/src/matchers/fatal.rs
@@ -14,2 +14,2 @@ impl<'a> FatalPattern<'a> {
-impl<'a> Matcher for FatalPattern<'a> {
- fn exec(&self, _: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for FatalPattern<'a> {
+ fn exec(&self, _: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -19 +19 @@ impl<'a> Matcher for FatalPattern<'a> {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/flatten.rs b/src/matchers/flatten.rs
index a2b18fa..8bc7025 100644
--- a/src/matchers/flatten.rs
+++ b/src/matchers/flatten.rs
@@ -5 +5 @@ pub struct FlattenPattern<'a> {
- matcher: Box<dyn Matcher>,
+ matcher: Box<dyn Matcher<'a>>,
@@ -10 +10 @@ impl<'a> FlattenPattern<'a> {
- pub fn new(matcher: Box<dyn Matcher>) -> Self {
+ pub fn new(matcher: Box<dyn Matcher<'a>>) -> Self {
@@ -17 +17 @@ impl<'a> FlattenPattern<'a> {
- pub fn new_with_name(matcher: Box<dyn Matcher>, name: &'a str) -> Self {
+ pub fn new_with_name(matcher: Box<dyn Matcher<'a>>, name: &'a str) -> Self {
@@ -22,2 +22,2 @@ impl<'a> FlattenPattern<'a> {
-impl<'a> Matcher for FlattenPattern<'a> {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for FlattenPattern<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -48 +48 @@ impl<'a> Matcher for FlattenPattern<'a> {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/matches.rs b/src/matchers/matches.rs
index 8a15443..1183bc2 100644
--- a/src/matchers/matches.rs
+++ b/src/matchers/matches.rs
@@ -33,2 +33,2 @@ impl<'a> MatchesPattern<'a> {
-impl<'a> Matcher for MatchesPattern<'a> {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for MatchesPattern<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -63 +63 @@ impl<'a> Matcher for MatchesPattern<'a> {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/not.rs b/src/matchers/not.rs
index 2e72dbe..30d7db2 100644
--- a/src/matchers/not.rs
+++ b/src/matchers/not.rs
@@ -4,2 +4,2 @@ use crate::parser_context::ParserContextRef;
-pub struct NotPattern {
- matcher: Box<dyn Matcher>,
+pub struct NotPattern<'a> {
+ matcher: Box<dyn Matcher<'a>>,
@@ -8,2 +8,2 @@ pub struct NotPattern {
-impl NotPattern {
- pub fn new(matcher: Box<dyn Matcher>) -> Self {
+impl<'a> NotPattern<'a> {
+ pub fn new(matcher: Box<dyn Matcher<'a>>) -> Self {
@@ -14,2 +14,2 @@ impl NotPattern {
-impl Matcher for NotPattern {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for NotPattern<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -43 +43 @@ impl Matcher for NotPattern {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/optional.rs b/src/matchers/optional.rs
index fb26c27..f98a4d1 100644
--- a/src/matchers/optional.rs
+++ b/src/matchers/optional.rs
@@ -4,2 +4,2 @@ use crate::parser_context::ParserContextRef;
-pub struct OptionalPattern {
- matcher: Box<dyn Matcher>,
+pub struct OptionalPattern<'a> {
+ matcher: Box<dyn Matcher<'a>>,
@@ -8,2 +8,2 @@ pub struct OptionalPattern {
-impl OptionalPattern {
- pub fn new(matcher: Box<dyn Matcher>) -> Self {
+impl<'a> OptionalPattern<'a> {
+ pub fn new(matcher: Box<dyn Matcher<'a>>) -> Self {
@@ -14,2 +14,2 @@ impl OptionalPattern {
-impl Matcher for OptionalPattern {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for OptionalPattern<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -28 +28 @@ impl Matcher for OptionalPattern {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/program.rs b/src/matchers/program.rs
index f814ce6..62d21fa 100644
--- a/src/matchers/program.rs
+++ b/src/matchers/program.rs
@@ -32 +32 @@ pub struct ProgramPattern<'a> {
- patterns: Vec<Box<dyn Matcher>>,
+ patterns: Vec<Box<dyn Matcher<'a>>>,
@@ -65 +65 @@ impl<'a> ProgramPattern<'a> {
- pub fn new_program(patterns: Vec<Box<dyn Matcher>>, stop_on_first: MatchAction) -> Self {
+ pub fn new_program(patterns: Vec<Box<dyn Matcher<'a>>>, stop_on_first: MatchAction) -> Self {
@@ -79 +79 @@ impl<'a> ProgramPattern<'a> {
- pub fn new_loop<T>(patterns: Vec<Box<dyn Matcher>>, r: T) -> Self
+ pub fn new_loop<T>(patterns: Vec<Box<dyn Matcher<'a>>>, r: T) -> Self
@@ -92 +92 @@ impl<'a> ProgramPattern<'a> {
- patterns: Vec<Box<dyn Matcher>>,
+ patterns: Vec<Box<dyn Matcher<'a>>>,
@@ -105 +105 @@ impl<'a> ProgramPattern<'a> {
- patterns: Vec<Box<dyn Matcher>>,
+ patterns: Vec<Box<dyn Matcher<'a>>>,
@@ -120 +120 @@ impl<'a> ProgramPattern<'a> {
- pub fn add_pattern(&mut self, pattern: Box<dyn Matcher>) {
+ pub fn add_pattern(&mut self, pattern: Box<dyn Matcher<'a>>) {
@@ -219,2 +219,2 @@ fn add_token_to_children<'a>(
-impl<'a> Matcher for ProgramPattern<'a> {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for ProgramPattern<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -720 +720 @@ impl<'a> Matcher for ProgramPattern<'a> {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/matchers/sequence.rs b/src/matchers/sequence.rs
index ba16733..f115ca4 100644
--- a/src/matchers/sequence.rs
+++ b/src/matchers/sequence.rs
@@ -58,2 +58,2 @@ impl<'a> SequencePattern<'a> {
-impl<'a> Matcher for SequencePattern<'a> {
- fn exec(&self, context: ParserContextRef) -> Result<MatcherSuccess, MatcherFailure> {
+impl<'a> Matcher<'a> for SequencePattern<'a> {
+ fn exec(&self, context: ParserContextRef<'a>) -> Result<MatcherSuccess<'a>, MatcherFailure<'a>> {
@@ -126 +126 @@ impl<'a> Matcher for SequencePattern<'a> {
- fn get_name(&self) -> &str {
+ fn get_name(&self) -> &'a str {
diff --git a/src/parser_context.rs b/src/parser_context.rs
index 9c99552..3d5a9ac 100644
--- a/src/parser_context.rs
+++ b/src/parser_context.rs
@@ -10 +10 @@ pub struct ParserContext<'a> {
- matcher_reference_map: Rc<RefCell<HashMap<String, Box<dyn Matcher>>>>,
+ matcher_reference_map: Rc<RefCell<HashMap<String, Box<dyn Matcher<'a>>>>>,
@@ -23 +23 @@ impl<'a> Clone for ParserContext<'a> {
- name: self.name.clone(),
+ name: self.name,
@@ -57 +57 @@ impl<'a> ParserContext<'a> {
- pub fn clone_with_name<'b>(&'b self, name: &'b str) -> ParserContextRef<'b> {
+ pub fn clone_with_name(&self, name: &'a str) -> ParserContextRef<'a> {
Personally, I don't see the point of using &'a str
s everywhere for the names. In all use cases I can imagine, either the names are always string literals, in which case &'a str
should be replaced with &'static str
, or the names are dynamically generated, in which case it would be better to own them as String
s and copy them as necessary. Currently, it makes little sense to clone the entire source
string into the Parser
, then meticulously avoid copying any names.