about summary refs log tree commit diff
path: root/crates/parser/src/parser.rs
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-02-03 17:18:48 +0100
committerLukas Wirth <lukastw97@gmail.com>2023-02-03 17:18:48 +0100
commit6fa6efe90fc8a79395cacb5c71315f0e2b32e623 (patch)
treeeae05eee4e4201e3034869dbcab01f394f07b9b3 /crates/parser/src/parser.rs
parentdab685dd87ba99f6c0f005f2ce7b0a3c10dada22 (diff)
downloadrust-6fa6efe90fc8a79395cacb5c71315f0e2b32e623.tar.gz
rust-6fa6efe90fc8a79395cacb5c71315f0e2b32e623.zip
fix: Fix parsing of nested tuple field accesses in a cursed way
Diffstat (limited to 'crates/parser/src/parser.rs')
-rw-r--r--crates/parser/src/parser.rs32
1 files changed, 32 insertions, 0 deletions
diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs
index 48aecb35be1..0f4fa602291 100644
--- a/crates/parser/src/parser.rs
+++ b/crates/parser/src/parser.rs
@@ -181,6 +181,38 @@ impl<'t> Parser<'t> {
         self.do_bump(kind, 1);
     }
 
+    /// Advances the parser by one token
+    pub(crate) fn split_float(&mut self, marker: Marker) -> (bool, Marker) {
+        assert!(self.at(SyntaxKind::FLOAT_NUMBER));
+        // we have parse `<something>.`
+        // `<something>`.0.1
+        // here we need to insert an extra event
+        //
+        // `<something>`. 0. 1;
+        // here we need to change the follow up parse, the return value will cause us to emulate a dot
+        // the actual splitting happens later
+        let has_pseudo_dot = !self.inp.is_joint(self.pos);
+        let marker = if !has_pseudo_dot {
+            let new_pos = self.start();
+            let idx = marker.pos as usize;
+            match &mut self.events[idx] {
+                Event::Start { forward_parent, kind } => {
+                    *kind = SyntaxKind::FIELD_EXPR;
+                    *forward_parent = Some(new_pos.pos - marker.pos);
+                }
+                _ => unreachable!(),
+            }
+            // NOTE: This brings the start / finish pairs out of balance!
+            std::mem::forget(marker);
+            new_pos
+        } else {
+            marker
+        };
+        self.pos += 1 as usize;
+        self.push_event(Event::FloatSplitHack { has_pseudo_dot });
+        (has_pseudo_dot, marker)
+    }
+
     /// Advances the parser by one token, remapping its kind.
     /// This is useful to create contextual keywords from
     /// identifiers. For example, the lexer creates a `union`