From 4e79073e3872df718eb189dd5301ffc000f87d58 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Jul 2018 02:23:01 +0300 Subject: Use raw pointers --- src/yellow/mod.rs | 31 ------------------------------- src/yellow/red.rs | 10 +++++----- src/yellow/syntax.rs | 19 ++++++++++--------- 3 files changed, 15 insertions(+), 45 deletions(-) diff --git a/src/yellow/mod.rs b/src/yellow/mod.rs index 9a6203cc1..4fd0d24d7 100644 --- a/src/yellow/mod.rs +++ b/src/yellow/mod.rs @@ -3,10 +3,6 @@ mod red; mod syntax; mod builder; -use std::{ - sync::{Arc, Weak}, - mem -}; pub(crate) use self::{ green::{GreenNode, GreenNodeBuilder}, red::RedNode, @@ -14,30 +10,3 @@ pub(crate) use self::{ builder::GreenBuilder, }; pub use self::syntax::SyntaxNode; - -// This could be just `*const T`, but we use `Weak` for additional checks -#[derive(Debug)] -pub(crate) struct Ptr(Weak); - -impl Clone for Ptr { - fn clone(&self) -> Self { - Ptr(self.0.clone()) - } -} - -impl Ptr { - fn clone(self_: &Ptr) -> Ptr { - Ptr(Weak::clone(&self_.0)) - } - - fn new(arc: &Arc) -> Ptr { - Ptr(Arc::downgrade(arc)) - } - - unsafe fn get(&self) -> &T { - let t = self.0.upgrade() - .expect("caller must guarantee that Ptr is not null"); - let t: &T = &*t; - mem::transmute(t) - } -} diff --git a/src/yellow/red.rs b/src/yellow/red.rs index e2dbceeae..3fdbfe0c5 100644 --- a/src/yellow/red.rs +++ b/src/yellow/red.rs @@ -1,7 +1,7 @@ use std::sync::{Arc, RwLock}; use { TextUnit, - yellow::{Ptr, GreenNode}, + yellow::GreenNode, }; #[derive(Debug)] @@ -13,7 +13,7 @@ pub(crate) struct RedNode { #[derive(Debug)] struct ParentData { - parent: Ptr, + parent: *const RedNode, start_offset: TextUnit, index_in_parent: usize, } @@ -27,7 +27,7 @@ impl RedNode { fn new_child( green: GreenNode, - parent: Ptr, + parent: *const RedNode, start_offset: TextUnit, index_in_parent: usize, ) -> RedNode { @@ -62,7 +62,7 @@ impl RedNode { self.green.children().len() } - pub(crate) fn nth_child(&self, me: Ptr, idx: usize) -> Arc { + pub(crate) fn nth_child(&self, idx: usize) -> Arc { match &self.children.read().unwrap()[idx] { Some(child) => return child.clone(), None => (), @@ -72,7 +72,7 @@ impl RedNode { let green_children = self.green.children(); let start_offset = self.start_offset() + green_children[..idx].iter().map(|x| x.text_len()).sum::(); - let child = RedNode::new_child(green_children[idx].clone(), me, start_offset, idx); + let child = RedNode::new_child(green_children[idx].clone(), self, start_offset, idx); children[idx] = Some(Arc::new(child)) } children[idx].as_ref().unwrap().clone() diff --git a/src/yellow/syntax.rs b/src/yellow/syntax.rs index 53d8c82b9..fa51e8d13 100644 --- a/src/yellow/syntax.rs +++ b/src/yellow/syntax.rs @@ -1,18 +1,20 @@ use std::{ fmt, sync::Arc, + ptr }; use { TextRange, TextUnit, SyntaxKind::{self, *}, - yellow::{Ptr, RedNode, GreenNode}, + yellow::{RedNode, GreenNode}, }; #[derive(Clone)] pub struct SyntaxNode { pub(crate) root: SyntaxRoot, - red: Ptr, + // guaranteed to be alive bc SyntaxRoot holds a strong ref + red: ptr::NonNull, } #[derive(Clone)] @@ -29,10 +31,10 @@ pub(crate) struct SyntaxError { impl SyntaxNode { pub(crate) fn new(root: GreenNode, errors: Vec) -> SyntaxNode { - let root = Arc::new(RedNode::new_root(root)); - let red = Ptr::new(&root); - let root = SyntaxRoot { red: root, errors: Arc::new(errors) }; - SyntaxNode { root, red } + let red = Arc::new(RedNode::new_root(root)); + let red_weak: ptr::NonNull = (&*red).into(); + let root = SyntaxRoot { red, errors: Arc::new(errors) }; + SyntaxNode { root, red: red_weak } } pub fn kind(&self) -> SyntaxKind { @@ -58,15 +60,14 @@ impl SyntaxNode { for i in 0..n_children { res.push(SyntaxNode { root: self.root.clone(), - red: Ptr::new(&red.nth_child(Ptr::clone(&self.red), i)), + red: (&*red.nth_child(i)).into(), }); } res } fn red(&self) -> &RedNode { - // Safe b/c root ptr keeps red alive - unsafe { self.red.get() } + unsafe { self.red.as_ref() } } } -- cgit v1.2.3