Skip to content

Commit 0fed125

Browse files
cijiugechuanonrig
authored andcommitted
fix: tie rust export borrows to analysis lifetime
1 parent c22b35c commit 0fed125

File tree

2 files changed

+27
-29
lines changed

2 files changed

+27
-29
lines changed

rust/src/ffi.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,6 @@ pub struct merve_string {
1414
pub length: usize,
1515
}
1616

17-
impl merve_string {
18-
/// Convert to a Rust `&str` with an arbitrary lifetime.
19-
///
20-
/// Returns `""` when `length` is 0 (which includes the case where `data` is null).
21-
///
22-
/// # Safety
23-
/// The caller must ensure that the backing data outlives `'a` and is valid UTF-8.
24-
/// The `merve_string` itself is a temporary POD value; the data it points to
25-
/// lives in the original source buffer or the analysis handle.
26-
#[must_use]
27-
pub unsafe fn as_str<'a>(&self) -> &'a str {
28-
if self.length == 0 {
29-
return "";
30-
}
31-
unsafe {
32-
let slice = core::slice::from_raw_parts(self.data.cast(), self.length);
33-
core::str::from_utf8_unchecked(slice)
34-
}
35-
}
36-
}
37-
3817
/// Opaque handle to a CommonJS parse result.
3918
pub type merve_analysis = *mut c_void;
4019

rust/src/lib.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,17 @@ unsafe impl Send for Analysis<'_> {}
136136
unsafe impl Sync for Analysis<'_> {}
137137

138138
impl<'a> Analysis<'a> {
139+
#[inline]
140+
fn str_from_ffi(&self, s: ffi::merve_string) -> &str {
141+
if s.length == 0 {
142+
return "";
143+
}
144+
unsafe {
145+
let slice = core::slice::from_raw_parts(s.data.cast(), s.length);
146+
core::str::from_utf8_unchecked(slice)
147+
}
148+
}
149+
139150
/// Number of named exports found.
140151
#[must_use]
141152
pub fn exports_count(&self) -> usize {
@@ -152,12 +163,12 @@ impl<'a> Analysis<'a> {
152163
///
153164
/// Returns `None` if `index` is out of bounds.
154165
#[must_use]
155-
pub fn export_name(&self, index: usize) -> Option<&'a str> {
166+
pub fn export_name(&self, index: usize) -> Option<&str> {
156167
if index >= self.exports_count() {
157168
return None;
158169
}
159170
let s = unsafe { ffi::merve_get_export_name(self.handle, index) };
160-
Some(unsafe { s.as_str() })
171+
Some(self.str_from_ffi(s))
161172
}
162173

163174
/// Get the 1-based source line number of the export at `index`.
@@ -169,19 +180,23 @@ impl<'a> Analysis<'a> {
169180
return None;
170181
}
171182
let line = unsafe { ffi::merve_get_export_line(self.handle, index) };
172-
if line == 0 { None } else { Some(line) }
183+
if line == 0 {
184+
None
185+
} else {
186+
Some(line)
187+
}
173188
}
174189

175190
/// Get the module specifier of the re-export at `index`.
176191
///
177192
/// Returns `None` if `index` is out of bounds.
178193
#[must_use]
179-
pub fn reexport_name(&self, index: usize) -> Option<&'a str> {
194+
pub fn reexport_name(&self, index: usize) -> Option<&str> {
180195
if index >= self.reexports_count() {
181196
return None;
182197
}
183198
let s = unsafe { ffi::merve_get_reexport_name(self.handle, index) };
184-
Some(unsafe { s.as_str() })
199+
Some(self.str_from_ffi(s))
185200
}
186201

187202
/// Get the 1-based source line number of the re-export at `index`.
@@ -193,7 +208,11 @@ impl<'a> Analysis<'a> {
193208
return None;
194209
}
195210
let line = unsafe { ffi::merve_get_reexport_line(self.handle, index) };
196-
if line == 0 { None } else { Some(line) }
211+
if line == 0 {
212+
None
213+
} else {
214+
Some(line)
215+
}
197216
}
198217

199218
/// Iterate over all named exports.
@@ -260,8 +279,8 @@ pub struct ExportIter<'a, 'b> {
260279
count: usize,
261280
}
262281

263-
impl<'a> Iterator for ExportIter<'a, '_> {
264-
type Item = Export<'a>;
282+
impl<'a, 'b> Iterator for ExportIter<'a, 'b> {
283+
type Item = Export<'b>;
265284

266285
fn next(&mut self) -> Option<Self::Item> {
267286
if self.index >= self.count {

0 commit comments

Comments
 (0)