From ecd5da5b0cae5b3af95f5b86a8157a1f57a944c5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 1 Aug 2018 11:58:19 +0300 Subject: Introduce drop-bomb --- src/parser_api.rs | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'src/parser_api.rs') diff --git a/src/parser_api.rs b/src/parser_api.rs index d12f773b2..3cad91976 100644 --- a/src/parser_api.rs +++ b/src/parser_api.rs @@ -1,6 +1,7 @@ use { parser_impl::ParserImpl, SyntaxKind::{self, ERROR}, + drop_bomb::DropBomb, }; #[derive(Clone, Copy)] @@ -76,7 +77,7 @@ impl<'t> Parser<'t> { /// consumed between the `start` and the corresponding `Marker::complete` /// belong to the same node. pub(crate) fn start(&mut self) -> Marker { - Marker(self.0.start()) + Marker::new(self.0.start()) } /// Advances the parser by one token. @@ -131,31 +132,31 @@ impl<'t> Parser<'t> { } /// See `Parser::start`. -pub(crate) struct Marker(u32); +pub(crate) struct Marker { + pos: u32, + bomb: DropBomb, +} impl Marker { + fn new(pos: u32) -> Marker { + Marker { + pos, + bomb: DropBomb::new("Marker must be either completed or abandoned") + } + } + /// Finishes the syntax tree node and assigns `kind` to it. - pub(crate) fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { - let pos = self.0; - ::std::mem::forget(self); - p.0.complete(pos, kind); - CompletedMarker(pos) + pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { + self.bomb.defuse(); + p.0.complete(self.pos, kind); + CompletedMarker(self.pos) } /// Abandons the syntax tree node. All its children /// are attached to its parent instead. - pub(crate) fn abandon(self, p: &mut Parser) { - let pos = self.0; - ::std::mem::forget(self); - p.0.abandon(pos); - } -} - -impl Drop for Marker { - fn drop(&mut self) { - if !::std::thread::panicking() { - panic!("Marker must be either completed or abandoned"); - } + pub(crate) fn abandon(mut self, p: &mut Parser) { + self.bomb.defuse(); + p.0.abandon(self.pos); } } @@ -170,6 +171,6 @@ impl CompletedMarker { /// `B` before starting `A`. `precede` allows to do exactly /// that. See also docs about `forward_parent` in `Event::Start`. pub(crate) fn precede(self, p: &mut Parser) -> Marker { - Marker(p.0.precede(self.0)) + Marker::new(p.0.precede(self.0)) } } -- cgit v1.2.3