1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//! Internal FFI helpers shared across `ops/**`, `transforms/**`, etc.
//!
//! Hosts cross-module RAII guards and small Option-to-raw bridges that
//! were previously copied per call-site. Visibility is `pub(crate)` —
//! these are implementation details, not part of the public API.
//!
//! Centralises the duplicated helpers flagged by audit issue #259:
//! `VectorArrayGuard` (was duplicated 7×), `drain_vector` (3×), and
//! `opt_array` (2×).
use crate::;
/// RAII guard for an `mlx_vector_array` handle obtained from a fallible
/// mlx-c call. The handle is freed exactly once on drop via
/// `mlx_vector_array_free`, which is a defined no-op on a NULL ctx
/// (sentinel-handle pattern, see `mlxrs-sys/vendor/mlx-c/mlx/c/vector.cpp`).
///
/// Callers typically pair `VectorArrayGuard` with a separate read of the
/// vector via [`drain_vector`]; the guard owns the free, `drain_vector`
/// owns the read. Keeping the two concerns separate is what allows
/// borrow-style consumers (e.g. `transforms::closure::borrow_inputs`) to
/// read without freeing when the vector is mlx-c-owned.
pub mlx_vector_array);
/// Build a `Vec<Array>` from an `mlx_vector_array` by copying out each
/// handle (refcount bump on each via `mlx_array_set` inside the mlx-c
/// getter). PURE READ — does NOT free `vec`. Callers that own `vec`
/// must pair this with a [`VectorArrayGuard`] in their own scope;
/// callers reading mlx-c-owned vectors (trampoline inputs) must NOT.
pub
/// Map an optional `&Array` to `(raw_handle, ownership_anchor)` for FFI
/// calls that accept a nullable array argument. Returning
/// `(mlx_array, Option<Array>)` instead of `Option<&Array>` gives
/// callers a stable raw pointer that mlx-c sees as either NULL (when
/// `a` is `None`) or pointing at a live handle (when `a` is `Some`).
/// The `Option<Array>` in the return tuple keeps the freshly-allocated
/// anchor alive for the duration of the FFI call.
pub