Skip to content

Commit

Permalink
Change a RefCell in Vertex to UnsafeCell
Browse files Browse the repository at this point in the history
  • Loading branch information
QuarticCat committed Sep 30, 2022
1 parent 1631eb2 commit 9c551ab
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
9 changes: 4 additions & 5 deletions src/diff/dijkstra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn shortest_vertex_path<'a, 'b>(

set_neighbours(current, vertex_arena, &mut seen);

if let Some(neighbors) = &*current.neighbours.borrow() {
if let Some(neighbors) = unsafe { &*current.neighbours.get() } {
for &(edge, next) in neighbors {
let distance_to_next = distance + edge.cost();

Expand Down Expand Up @@ -110,7 +110,7 @@ fn shortest_path<'a, 'b>(
size_hint: usize,
graph_limit: usize,
) -> Result<Vec<(Edge, &'b Vertex<'a, 'b>)>, ExceededGraphLimit> {
let start: &'b Vertex<'a, 'b> = vertex_arena.alloc(start.clone());
let start: &'b Vertex<'a, 'b> = vertex_arena.alloc(start);
let vertex_path = shortest_vertex_path(start, vertex_arena, size_hint, graph_limit)?;
Ok(shortest_path_with_edges(&vertex_path))
}
Expand All @@ -119,9 +119,8 @@ fn edge_between<'a, 'b>(before: &Vertex<'a, 'b>, after: &Vertex<'a, 'b>) -> Edge
assert_ne!(before, after);

let mut shortest_edge: Option<Edge> = None;
if let Some(neighbours) = &*before.neighbours.borrow() {
for neighbour in neighbours {
let (edge, next) = *neighbour;
if let Some(neighbours) = unsafe { &*before.neighbours.get() } {
for &(edge, next) in neighbours {
// If there are multiple edges that can take us to `next`,
// prefer the shortest.
if *next == *after {
Expand Down
23 changes: 13 additions & 10 deletions src/diff/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use bumpalo::Bump;
use rustc_hash::FxHashMap;
use std::{
cell::{Cell, RefCell},
cell::{Cell, UnsafeCell},
cmp::min,
fmt,
hash::{Hash, Hasher},
Expand Down Expand Up @@ -62,7 +62,7 @@ impl<'a> From<&'a Syntax<'a>> for SyntaxRefOrId<'a> {
}
}

impl<'a> From<Option<SyntaxId>> for SyntaxRefOrId<'a> {
impl From<Option<SyntaxId>> for SyntaxRefOrId<'_> {
fn from(s: Option<SyntaxId>) -> Self {
Self {
data: s.map_or(0, |n| n.get() as usize) * 2 + 1,
Expand Down Expand Up @@ -111,9 +111,10 @@ fn next_child_syntax<'a>(syntax: &'a Syntax<'a>, children: &[&'a Syntax<'a>]) ->
/// LHS: X A RHS: A
/// ^ ^
/// ```
#[derive(Debug, Clone, Eq)]
#[derive(Debug)]
pub struct Vertex<'a, 'b> {
pub neighbours: RefCell<Option<Vec<(Edge, &'b Vertex<'a, 'b>)>>>,
// TODO: how to design the boundary of unsafe?
pub neighbours: UnsafeCell<Option<Vec<(Edge, &'b Vertex<'a, 'b>)>>>,
pub shortest_distance: Cell<u64>,
pub predecessor: Cell<Option<&'b Vertex<'a, 'b>>>,
pub lhs_syntax: SyntaxRefOrId<'a>,
Expand All @@ -129,7 +130,7 @@ impl<'a, 'b> Vertex<'a, 'b> {
pub fn new(lhs_syntax: Option<&'a Syntax<'a>>, rhs_syntax: Option<&'a Syntax<'a>>) -> Self {
let parents = Stack::new();
Vertex {
neighbours: RefCell::new(None),
neighbours: UnsafeCell::new(None),
shortest_distance: Cell::new(u64::MAX),
predecessor: Cell::new(None),
lhs_syntax: lhs_syntax.map_or(None.into(), |s| s.into()),
Expand All @@ -139,7 +140,7 @@ impl<'a, 'b> Vertex<'a, 'b> {
}
}

impl<'a, 'b> PartialEq for Vertex<'a, 'b> {
impl PartialEq for Vertex<'_, '_> {
fn eq(&self, other: &Self) -> bool {
// Strictly speaking, we should compare the whole
// EnteredDelimiter stack, not just the immediate
Expand Down Expand Up @@ -170,15 +171,17 @@ impl<'a, 'b> PartialEq for Vertex<'a, 'b> {
}
}

impl<'a, 'b> Hash for Vertex<'a, 'b> {
impl Eq for Vertex<'_, '_> {}

impl Hash for Vertex<'_, '_> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.lhs_syntax.hash(state);
self.rhs_syntax.hash(state);
can_pop_either_parent(&self.parents).hash(state);
}
}

impl<'a, 'b> Default for Vertex<'a, 'b> {
impl Default for Vertex<'_, '_> {
fn default() -> Self {
Self::new(None, None)
}
Expand Down Expand Up @@ -474,7 +477,7 @@ pub fn set_neighbours<'syn, 'b>(
alloc: &'b Bump,
seen: &mut FxHashMap<&Vertex<'syn, 'b>, Vec<&'b Vertex<'syn, 'b>>>,
) {
if v.neighbours.borrow().is_some() {
if unsafe { (&*v.neighbours.get()).is_some() } {
return;
}

Expand Down Expand Up @@ -735,7 +738,7 @@ pub fn set_neighbours<'syn, 'b>(
"Must always find some next steps if node is not the end"
);

v.neighbours.replace(Some(res));
unsafe { *v.neighbours.get() = Some(res) };
}

pub fn populate_change_map<'a, 'b>(
Expand Down

0 comments on commit 9c551ab

Please sign in to comment.