Skip to content

Commit 638e9e2

Browse files
Syntax node children now passed by ref (#8044)
1 parent 7385afa commit 638e9e2

File tree

7 files changed

+17
-59
lines changed

7 files changed

+17
-59
lines changed

crates/cairo-lang-formatter/src/formatter_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ impl<'a> FormatterImpl<'a> {
12071207
fn format_terminal(&mut self, syntax_node: &SyntaxNode<'a>) {
12081208
// TODO(spapini): Introduce a Terminal and a Token enum in ast.rs to make this cleaner.
12091209
let children = syntax_node.get_children(self.db);
1210-
let [leading, token, trailing] = &children[..] else {
1210+
let [leading, token, trailing] = children else {
12111211
panic!("Terminal node should have 3 children.");
12121212
};
12131213
// The first newlines is the leading trivia correspond exactly to empty lines.

crates/cairo-lang-formatter/src/node_properties.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ impl<'a> SyntaxNodeFormat for SyntaxNode<'a> {
963963
);
964964
if (!is_expr_or_pattern_list || children.len() > 2)
965965
// Ensure that this node is the last element in the list.
966-
&& is_last(self, &children)
966+
&& is_last(self, children)
967967
{
968968
return true;
969969
}
@@ -978,7 +978,7 @@ impl<'a> SyntaxNodeFormat for SyntaxNode<'a> {
978978
let statements_node = statement_node.parent(db).unwrap();
979979
// Checking if not the last statement, as `;` may be there to prevent the block from
980980
// returning the value of the current block.
981-
let not_last = !is_last(&statement_node, &statements_node.get_children(db));
981+
let not_last = !is_last(&statement_node, statements_node.get_children(db));
982982
let children = statement_node.get_children(db);
983983
if not_last
984984
&& matches!(
@@ -999,7 +999,7 @@ impl<'a> SyntaxNodeFormat for SyntaxNode<'a> {
999999
{
10001000
let path_segment_node = self.parent(db).unwrap();
10011001
let path_node = path_segment_node.parent(db).unwrap();
1002-
if !is_last(&path_segment_node, &path_node.get_children(db)) {
1002+
if !is_last(&path_segment_node, path_node.get_children(db)) {
10031003
false
10041004
} else {
10051005
matches!(

crates/cairo-lang-parser/src/printer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ impl<'a> Printer<'a> {
210210
NodeKind::Struct { members: expected_children }
211211
| NodeKind::Terminal { members: expected_children, .. } => {
212212
self.print_internal_struct(
213-
&children,
213+
children,
214214
&expected_children,
215215
indent.as_str(),
216216
under_top_level,

crates/cairo-lang-syntax/src/node/db.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::sync::Arc;
2-
31
use cairo_lang_filesystem::db::FilesGroup;
42
use cairo_lang_utils::Upcast;
53

@@ -19,9 +17,11 @@ pub trait SyntaxGroup: FilesGroup + for<'a> Upcast<'a, dyn FilesGroup> {
1917
fn intern_syntax_node<'a>(&'a self, field: SyntaxNodeLongId<'a>) -> SyntaxNode<'a>;
2018

2119
/// Query for caching [SyntaxNode::get_children].
22-
fn get_children<'a>(&'a self, node: SyntaxNode<'a>) -> Arc<Vec<SyntaxNode<'a>>>;
20+
#[salsa::transparent]
21+
fn get_children<'a>(&'a self, node: SyntaxNode<'a>) -> &'a [SyntaxNode<'a>];
2322
}
2423

25-
fn get_children<'a>(db: &'a dyn SyntaxGroup, node: SyntaxNode<'a>) -> Arc<Vec<SyntaxNode<'a>>> {
26-
node.get_children_impl(db).into()
24+
#[salsa::tracked(returns(ref))]
25+
fn get_children<'a>(db: &'a dyn SyntaxGroup, node: SyntaxNode<'a>) -> Vec<SyntaxNode<'a>> {
26+
node.get_children_impl(db)
2727
}
Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::marker::PhantomData;
2-
use std::sync::Arc;
32

43
use super::SyntaxGroup;
54
use crate::node::{SyntaxNode, TypedSyntaxNode};
@@ -25,8 +24,7 @@ impl<'db, T: TypedSyntaxNode<'db>> ElementList<'db, T, 1> {
2524
&self,
2625
db: &'db dyn SyntaxGroup,
2726
) -> impl ExactSizeIterator<Item = T> + DoubleEndedIterator + 'db {
28-
ElementListRawIter::new(self.node.get_children(db).as_slice().into())
29-
.map(move |x| T::from_syntax_node(db, x))
27+
self.node.get_children(db).iter().copied().map(move |x| T::from_syntax_node(db, x))
3028
}
3129
pub fn has_tail(&self, _db: &dyn SyntaxGroup) -> bool {
3230
false
@@ -40,51 +38,14 @@ impl<'db, T: TypedSyntaxNode<'db>> ElementList<'db, T, 2> {
4038
&self,
4139
db: &'db dyn SyntaxGroup,
4240
) -> impl ExactSizeIterator<Item = T> + DoubleEndedIterator + 'db {
43-
ElementListRawIter::new(self.node.get_children(db).as_slice().into())
41+
self.node
42+
.get_children(db)
43+
.iter()
44+
.copied()
4445
.step_by(2)
4546
.map(move |x| T::from_syntax_node(db, x))
4647
}
4748
pub fn has_tail(&self, db: &dyn SyntaxGroup) -> bool {
4849
!self.node.get_children(db).len().is_multiple_of(2)
4950
}
5051
}
51-
52-
/// Iterator over the raw elements of an `ElementList`.
53-
struct ElementListRawIter<'a> {
54-
/// The `Arc` storing the actual node.
55-
_data: Arc<[SyntaxNode<'a>]>,
56-
/// Actual iterator over the elements.
57-
iter: std::slice::Iter<'a, SyntaxNode<'a>>,
58-
}
59-
60-
impl<'a> ElementListRawIter<'a> {
61-
fn new(data: Arc<[SyntaxNode<'a>]>) -> Self {
62-
// We leak the Arc to get a 'static reference, and keep the Arc in the struct to avoid
63-
// leaks.
64-
let ptr: *const [SyntaxNode<'_>] = Arc::as_ptr(&data);
65-
let slice: &'static [SyntaxNode<'_>] = unsafe { std::mem::transmute(&*ptr) };
66-
let iter = slice.iter();
67-
Self { _data: data, iter }
68-
}
69-
}
70-
71-
impl<'a> Iterator for ElementListRawIter<'a> {
72-
type Item = SyntaxNode<'a>;
73-
74-
fn next(&mut self) -> Option<Self::Item> {
75-
self.iter.next().copied()
76-
}
77-
fn size_hint(&self) -> (usize, Option<usize>) {
78-
self.iter.size_hint()
79-
}
80-
}
81-
impl ExactSizeIterator for ElementListRawIter<'_> {
82-
fn len(&self) -> usize {
83-
self.iter.len()
84-
}
85-
}
86-
impl DoubleEndedIterator for ElementListRawIter<'_> {
87-
fn next_back(&mut self) -> Option<Self::Item> {
88-
self.iter.next_back().copied()
89-
}
90-
}

crates/cairo-lang-syntax/src/node/iter.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::sync::Arc;
2-
31
use crate::node::SyntaxNode;
42
use crate::node::db::SyntaxGroup;
53

@@ -33,7 +31,7 @@ pub struct Preorder<'a> {
3331

3432
struct PreorderLayer<'a> {
3533
start: SyntaxNode<'a>,
36-
children: Option<(Arc<Vec<SyntaxNode<'a>>>, usize)>,
34+
children: Option<(&'a [SyntaxNode<'a>], usize)>,
3735
}
3836

3937
impl<'a> Preorder<'a> {

crates/cairo-lang-syntax/src/node/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use core::hash::Hash;
2-
use std::sync::Arc;
32

43
use cairo_lang_filesystem::ids::FileId;
54
use cairo_lang_filesystem::span::{TextOffset, TextPosition, TextSpan, TextWidth};
@@ -139,7 +138,7 @@ impl<'a> SyntaxNode<'a> {
139138
}
140139

141140
/// Gets the children syntax nodes of the current node.
142-
pub fn get_children(&self, db: &'a dyn SyntaxGroup) -> Arc<Vec<SyntaxNode<'a>>> {
141+
pub fn get_children(&self, db: &'a dyn SyntaxGroup) -> &'a [SyntaxNode<'a>] {
143142
db.get_children(*self)
144143
}
145144

0 commit comments

Comments
 (0)