Skip to content

Commit b9b6d4a

Browse files
committed
Add lifetimes
1 parent 79f2d3a commit b9b6d4a

2 files changed

Lines changed: 56 additions & 31 deletions

File tree

rust/ruby-rbs/build.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ fn write_node_field_accessor(
119119
if field.optional {
120120
writeln!(
121121
file,
122-
" pub fn {}(&self) -> Option<{rust_type}> {{",
122+
" pub fn {}(&self) -> Option<{rust_type}<'a>> {{",
123123
field.name,
124124
)?;
125125
writeln!(
@@ -132,14 +132,18 @@ fn write_node_field_accessor(
132132
writeln!(file, " }} else {{")?;
133133
writeln!(
134134
file,
135-
" Some({rust_type} {{ parser: self.parser, pointer: ptr }})"
135+
" Some({rust_type} {{ parser: self.parser, pointer: ptr, marker: PhantomData }})"
136136
)?;
137137
writeln!(file, " }}")?;
138138
} else {
139-
writeln!(file, " pub fn {}(&self) -> {rust_type} {{", field.name)?;
140139
writeln!(
141140
file,
142-
" {rust_type} {{ parser: self.parser, pointer: unsafe {{ (*self.pointer).{} }} }}",
141+
" pub fn {}(&self) -> {rust_type}<'a> {{",
142+
field.name
143+
)?;
144+
writeln!(
145+
file,
146+
" {rust_type} {{ parser: self.parser, pointer: unsafe {{ (*self.pointer).{} }}, marker: PhantomData }}",
143147
field.c_name()
144148
)?;
145149
}
@@ -334,19 +338,24 @@ fn generate(config: &Config) -> Result<(), Box<dyn Error>> {
334338
for node in &config.nodes {
335339
writeln!(file, "#[allow(dead_code)]")?; // TODO: Remove this once all nodes that need parser are implemented
336340
writeln!(file, "#[derive(Debug)]")?;
337-
writeln!(file, "pub struct {} {{", node.rust_name)?;
341+
writeln!(file, "pub struct {}<'a> {{", node.rust_name)?;
338342
writeln!(file, " parser: *mut rbs_parser_t,")?;
339343
writeln!(
340344
file,
341345
" pointer: *mut {},",
342346
convert_name(&node.name, CIdentifier::Type)
343347
)?;
348+
writeln!(
349+
file,
350+
" marker: PhantomData<&'a mut {}>",
351+
convert_name(&node.name, CIdentifier::Type)
352+
)?;
344353
writeln!(file, "}}\n")?;
345354

346-
writeln!(file, "impl {} {{", node.rust_name)?;
355+
writeln!(file, "impl<'a> {}<'a> {{", node.rust_name)?;
347356
writeln!(file, " /// Converts this node to a generic node.")?;
348357
writeln!(file, " #[must_use]")?;
349-
writeln!(file, " pub fn as_node(self) -> Node {{")?;
358+
writeln!(file, " pub fn as_node(self) -> Node<'a> {{")?;
350359
writeln!(file, " Node::{}(self)", node.variant_name())?;
351360
writeln!(file, " }}")?;
352361
writeln!(file)?;
@@ -461,7 +470,7 @@ fn generate(config: &Config) -> Result<(), Box<dyn Error>> {
461470
field.name.as_str()
462471
};
463472
if field.optional {
464-
writeln!(file, " pub fn {name}(&self) -> Option<Node> {{")?;
473+
writeln!(file, " pub fn {name}(&self) -> Option<Node<'a>> {{")?;
465474
writeln!(
466475
file,
467476
" let ptr = unsafe {{ (*self.pointer).{} }};",
@@ -472,7 +481,7 @@ fn generate(config: &Config) -> Result<(), Box<dyn Error>> {
472481
" if ptr.is_null() {{ None }} else {{ Some(Node::new(self.parser, ptr)) }}"
473482
)?;
474483
} else {
475-
writeln!(file, " pub fn {name}(&self) -> Node {{")?;
484+
writeln!(file, " pub fn {name}(&self) -> Node<'a> {{")?;
476485
writeln!(
477486
file,
478487
" unsafe {{ Node::new(self.parser, (*self.pointer).{}) }}",
@@ -501,18 +510,18 @@ fn generate(config: &Config) -> Result<(), Box<dyn Error>> {
501510

502511
// Generate the Node enum to wrap all of the structs
503512
writeln!(file, "#[derive(Debug)]")?;
504-
writeln!(file, "pub enum Node {{")?;
513+
writeln!(file, "pub enum Node<'a> {{")?;
505514
for node in &config.nodes {
506515
let variant_name = node
507516
.rust_name
508517
.strip_suffix("Node")
509518
.unwrap_or(&node.rust_name);
510519

511-
writeln!(file, " {variant_name}({}),", node.rust_name)?;
520+
writeln!(file, " {variant_name}({}<'a>),", node.rust_name)?;
512521
}
513522
writeln!(file, "}}")?;
514523

515-
writeln!(file, "impl Node {{")?;
524+
writeln!(file, "impl Node<'_> {{")?;
516525
writeln!(file, " #[allow(clippy::missing_safety_doc)]")?;
517526
writeln!(
518527
file,
@@ -525,7 +534,7 @@ fn generate(config: &Config) -> Result<(), Box<dyn Error>> {
525534

526535
writeln!(
527536
file,
528-
" rbs_node_type::{enum_name} => Self::{}({} {{ parser, pointer: node.cast::<{c_type}>() }}),",
537+
" rbs_node_type::{enum_name} => Self::{}({} {{ parser, pointer: node.cast::<{c_type}>(), marker: PhantomData }}),",
529538
node.variant_name(),
530539
node.rust_name,
531540
)?;

rust/ruby-rbs/src/lib.rs

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
22
use rbs_encoding_type_t::RBS_ENCODING_UTF_8;
33
use ruby_rbs_sys::bindings::*;
4+
use std::marker::PhantomData;
45
use std::sync::Once;
56

67
static INIT: Once = Once::new();
@@ -13,7 +14,7 @@ static INIT: Once = Once::new();
1314
/// let signature = parse(rbs_code.as_bytes());
1415
/// assert!(signature.is_ok(), "Failed to parse RBS signature");
1516
/// ```
16-
pub fn parse(rbs_code: &[u8]) -> Result<SignatureNode, String> {
17+
pub fn parse(rbs_code: &[u8]) -> Result<SignatureNode<'_>, String> {
1718
unsafe {
1819
INIT.call_once(|| {
1920
rbs_constant_pool_init(RBS_GLOBAL_CONSTANT_POOL, 26);
@@ -33,6 +34,7 @@ pub fn parse(rbs_code: &[u8]) -> Result<SignatureNode, String> {
3334
let signature_node = SignatureNode {
3435
parser,
3536
pointer: signature,
37+
marker: PhantomData,
3638
};
3739

3840
if result {
@@ -43,15 +45,15 @@ pub fn parse(rbs_code: &[u8]) -> Result<SignatureNode, String> {
4345
}
4446
}
4547

46-
impl Drop for SignatureNode {
48+
impl Drop for SignatureNode<'_> {
4749
fn drop(&mut self) {
4850
unsafe {
4951
rbs_parser_free(self.parser);
5052
}
5153
}
5254
}
5355

54-
impl KeywordNode {
56+
impl KeywordNode<'_> {
5557
pub fn name(&self) -> &[u8] {
5658
unsafe {
5759
let constant_ptr = rbs_constant_pool_id_to_constant(
@@ -68,33 +70,40 @@ impl KeywordNode {
6870
}
6971
}
7072

71-
pub struct NodeList {
73+
pub struct NodeList<'a> {
7274
parser: *mut rbs_parser_t,
7375
pointer: *mut rbs_node_list_t,
76+
marker: PhantomData<&'a mut rbs_node_list_t>,
7477
}
7578

76-
impl NodeList {
79+
impl<'a> NodeList<'a> {
7780
pub fn new(parser: *mut rbs_parser_t, pointer: *mut rbs_node_list_t) -> Self {
78-
Self { parser, pointer }
81+
Self {
82+
parser,
83+
pointer,
84+
marker: PhantomData,
85+
}
7986
}
8087

8188
/// Returns an iterator over the nodes.
8289
#[must_use]
83-
pub fn iter(&self) -> NodeListIter {
90+
pub fn iter(&self) -> NodeListIter<'a> {
8491
NodeListIter {
8592
parser: self.parser,
8693
current: unsafe { (*self.pointer).head },
94+
marker: PhantomData,
8795
}
8896
}
8997
}
9098

91-
pub struct NodeListIter {
99+
pub struct NodeListIter<'a> {
92100
parser: *mut rbs_parser_t,
93101
current: *mut rbs_node_list_node_t,
102+
marker: PhantomData<&'a mut rbs_node_list_node_t>,
94103
}
95104

96-
impl Iterator for NodeListIter {
97-
type Item = Node;
105+
impl<'a> Iterator for NodeListIter<'a> {
106+
type Item = Node<'a>;
98107

99108
fn next(&mut self) -> Option<Self::Item> {
100109
if self.current.is_null() {
@@ -108,33 +117,40 @@ impl Iterator for NodeListIter {
108117
}
109118
}
110119

111-
pub struct RBSHash {
120+
pub struct RBSHash<'a> {
112121
parser: *mut rbs_parser_t,
113122
pointer: *mut rbs_hash,
123+
marker: PhantomData<&'a mut rbs_hash>,
114124
}
115125

116-
impl RBSHash {
126+
impl<'a> RBSHash<'a> {
117127
pub fn new(parser: *mut rbs_parser_t, pointer: *mut rbs_hash) -> Self {
118-
Self { parser, pointer }
128+
Self {
129+
parser,
130+
pointer,
131+
marker: PhantomData,
132+
}
119133
}
120134

121135
/// Returns an iterator over the key-value pairs.
122136
#[must_use]
123-
pub fn iter(&self) -> RBSHashIter {
137+
pub fn iter(&self) -> RBSHashIter<'a> {
124138
RBSHashIter {
125139
parser: self.parser,
126140
current: unsafe { (*self.pointer).head },
141+
marker: PhantomData,
127142
}
128143
}
129144
}
130145

131-
pub struct RBSHashIter {
146+
pub struct RBSHashIter<'a> {
132147
parser: *mut rbs_parser_t,
133148
current: *mut rbs_hash_node_t,
149+
marker: PhantomData<&'a mut rbs_hash_node_t>,
134150
}
135151

136-
impl Iterator for RBSHashIter {
137-
type Item = (Node, Node);
152+
impl<'a> Iterator for RBSHashIter<'a> {
153+
type Item = (Node<'a>, Node<'a>);
138154

139155
fn next(&mut self) -> Option<Self::Item> {
140156
if self.current.is_null() {
@@ -222,7 +238,7 @@ impl RBSString {
222238
}
223239
}
224240

225-
impl SymbolNode {
241+
impl SymbolNode<'_> {
226242
pub fn name(&self) -> &[u8] {
227243
unsafe {
228244
let constant_ptr = rbs_constant_pool_id_to_constant(

0 commit comments

Comments
 (0)