Coverage Report

Created: 2024-10-16 07:58

/rust/registry/src/index.crates.io-6f17d22bba15001f/self_cell-1.0.4/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//! # Overview
2
//!
3
//! `self_cell` provides one macro-rules macro: [`self_cell`]. With this macro
4
//! you can create self-referential structs that are safe-to-use in stable Rust,
5
//! without leaking the struct internal lifetime.
6
//!
7
//! In a nutshell, the API looks *roughly* like this:
8
//!
9
//! ```ignore
10
//! // User code:
11
//!
12
//! self_cell!(
13
//!     struct NewStructName {
14
//!         owner: Owner,
15
//!
16
//!         #[covariant]
17
//!         dependent: Dependent,
18
//!     }
19
//!
20
//!     impl {Debug}
21
//! );
22
//!
23
//! // Generated by macro:
24
//!
25
//! struct NewStructName(...);
26
//!
27
//! impl NewStructName {
28
//!     fn new(
29
//!         owner: Owner,
30
//!         dependent_builder: impl for<'a> ::core::ops::FnOnce(&'a Owner) -> Dependent<'a>
31
//!     ) -> NewStructName { ... }
32
//!     fn borrow_owner<'a>(&'a self) -> &'a Owner { ... }
33
//!     fn borrow_dependent<'a>(&'a self) -> &'a Dependent<'a> { ... }
34
//!     [...]
35
//!     // See the macro level documentation for a list of all generated functions,
36
//!     // section "Generated API".
37
//! }
38
//!
39
//! impl Debug for NewStructName { ... }
40
//! ```
41
//!
42
//! Self-referential structs are currently not supported with safe vanilla Rust.
43
//! The only reasonable safe alternative is to have the user juggle 2 separate
44
//! data structures which is a mess. The library solution ouroboros is really
45
//! expensive to compile due to its use of procedural macros.
46
//!
47
//! This alternative is `no_std`, uses no proc-macros, some self contained
48
//! unsafe and works on stable Rust, and is miri tested. With a total of less
49
//! than 300 lines of implementation code, which consists mostly of type and
50
//! trait implementations, this crate aims to be a good minimal solution to the
51
//! problem of self-referential structs.
52
//!
53
//! It has undergone [community code
54
//! review](https://users.rust-lang.org/t/experimental-safe-to-use-proc-macro-free-self-referential-structs-in-stable-rust/52775)
55
//! from experienced Rust users.
56
//!
57
//! ### Fast compile times
58
//!
59
//! ```txt
60
//! $ rm -rf target && cargo +nightly build -Z timings
61
//!
62
//! Compiling self_cell v0.7.0
63
//! Completed self_cell v0.7.0 in 0.2s
64
//! ```
65
//!
66
//! Because it does **not** use proc-macros, and has 0 dependencies
67
//! compile-times are fast.
68
//!
69
//! Measurements done on a slow laptop.
70
//!
71
//! ### A motivating use case
72
//!
73
//! ```rust
74
//! use self_cell::self_cell;
75
//!
76
//! #[derive(Debug, Eq, PartialEq)]
77
//! struct Ast<'a>(pub Vec<&'a str>);
78
//!
79
//! self_cell!(
80
//!     struct AstCell {
81
//!         owner: String,
82
//!
83
//!         #[covariant]
84
//!         dependent: Ast,
85
//!     }
86
//!
87
//!     impl {Debug, Eq, PartialEq}
88
//! );
89
//!
90
//! fn build_ast_cell(code: &str) -> AstCell {
91
//!     // Create owning String on stack.
92
//!     let pre_processed_code = code.trim().to_string();
93
//!
94
//!     // Move String into AstCell, then build Ast inplace.
95
//!     AstCell::new(
96
//!        pre_processed_code,
97
//!        |code| Ast(code.split(' ').filter(|word| word.len() > 1).collect())
98
//!     )
99
//! }
100
//!
101
//! fn main() {
102
//!     let ast_cell = build_ast_cell("fox = cat + dog");
103
//!
104
//!     println!("ast_cell -> {:?}", &ast_cell);
105
//!     println!("ast_cell.borrow_owner() -> {:?}", ast_cell.borrow_owner());
106
//!     println!("ast_cell.borrow_dependent().0[1] -> {:?}", ast_cell.borrow_dependent().0[1]);
107
//! }
108
//! ```
109
//!
110
//! ```txt
111
//! $ cargo run
112
//!
113
//! ast_cell -> AstCell { owner: "fox = cat + dog", dependent: Ast(["fox", "cat", "dog"]) }
114
//! ast_cell.borrow_owner() -> "fox = cat + dog"
115
//! ast_cell.borrow_dependent().0[1] -> "cat"
116
//! ```
117
//!
118
//! There is no way in safe Rust to have an API like `build_ast_cell`, as soon
119
//! as `Ast` depends on stack variables like `pre_processed_code` you can't
120
//! return the value out of the function anymore. You could move the
121
//! pre-processing into the caller but that gets ugly quickly because you can't
122
//! encapsulate things anymore. Note this is a somewhat niche use case,
123
//! self-referential structs should only be used when there is no good
124
//! alternative.
125
//!
126
//! Under the hood, it heap allocates a struct which it initializes first by
127
//! moving the owner value to it and then using the reference to this now
128
//! Pin/Immovable owner to construct the dependent inplace next to it. This
129
//! makes it safe to move the generated SelfCell but you have to pay for the
130
//! heap allocation.
131
//!
132
//! See the documentation for [`self_cell`] to dive further into the details.
133
//!
134
//! Or take a look at the advanced examples:
135
//! - [Example how to handle dependent construction that can
136
//!   fail](https://github.com/Voultapher/self_cell/tree/main/examples/fallible_dependent_construction)
137
//!
138
//! - [How to build a lazy AST with
139
//!   self_cell](https://github.com/Voultapher/self_cell/tree/main/examples/lazy_ast)
140
//!
141
//! - [How to use an owner type with
142
//!     lifetime](https://github.com/Voultapher/self_cell/tree/main/examples/owner_with_lifetime)
143
//!
144
//! ### Min required rustc version
145
//!
146
//! By default the minimum required rustc version is 1.51.
147
//!
148
//! There is an optional feature you can enable called "old_rust" that enables
149
//! support down to rustc version 1.36. However this requires polyfilling std
150
//! library functionality for older rustc with technically UB versions. Testing
151
//! does not show older rustc versions (ab)using this. Use at your own risk.
152
//!
153
//! The minimum versions are a best effor and may change with any new major
154
//! release.
155
156
#![no_std]
157
158
#[doc(hidden)]
159
pub extern crate alloc;
160
161
#[doc(hidden)]
162
pub mod unsafe_self_cell;
163
164
/// This macro declares a new struct of `$StructName` and implements traits
165
/// based on `$AutomaticDerive`.
166
///
167
/// ### Example:
168
///
169
/// ```rust
170
/// use self_cell::self_cell;
171
///
172
/// #[derive(Debug, Eq, PartialEq)]
173
/// struct Ast<'a>(Vec<&'a str>);
174
///
175
/// self_cell!(
176
///     #[doc(hidden)]
177
///     struct PackedAstCell {
178
///         owner: String,
179
///
180
///         #[covariant]
181
///         dependent: Ast,
182
///     }
183
///
184
///     impl {Debug, PartialEq, Eq, Hash}
185
/// );
186
/// ```
187
///
188
/// See the crate overview to get a get an overview and a motivating example.
189
///
190
/// ### Generated API:
191
///
192
/// The macro implements these constructors:
193
///
194
/// ```ignore
195
/// fn new(
196
///     owner: $Owner,
197
///     dependent_builder: impl for<'a> ::core::ops::FnOnce(&'a $Owner) -> $Dependent<'a>
198
/// ) -> Self
199
/// ```
200
///
201
/// ```ignore
202
/// fn try_new<Err>(
203
///     owner: $Owner,
204
///     dependent_builder: impl for<'a> ::core::ops::FnOnce(&'a $Owner) -> Result<$Dependent<'a>, Err>
205
/// ) -> Result<Self, Err>
206
/// ```
207
///
208
/// ```ignore
209
/// fn try_new_or_recover<Err>(
210
///     owner: $Owner,
211
///     dependent_builder: impl for<'a> ::core::ops::FnOnce(&'a $Owner) -> Result<$Dependent<'a>, Err>
212
/// ) -> Result<Self, ($Owner, Err)>
213
/// ```
214
///
215
/// The macro implements these methods:
216
///
217
/// ```ignore
218
/// fn borrow_owner<'a>(&'a self) -> &'a $Owner
219
/// ```
220
///
221
/// ```ignore
222
/// // Only available if dependent is covariant.
223
/// fn borrow_dependent<'a>(&'a self) -> &'a $Dependent<'a>
224
/// ```
225
///
226
/// ```ignore
227
/// fn with_dependent<'outer_fn, Ret>(
228
///     &'outer_fn self,
229
///     func: impl for<'a> ::core::ops::FnOnce(&'a $Owner, &'outer_fn $Dependent<'a>
230
/// ) -> Ret) -> Ret
231
/// ```
232
///
233
/// ```ignore
234
/// fn with_dependent_mut<'outer_fn, Ret>(
235
///     &'outer_fn mut self,
236
///     func: impl for<'a> ::core::ops::FnOnce(&'a $Owner, &'outer_fn mut $Dependent<'a>) -> Ret
237
/// ) -> Ret
238
/// ```
239
///
240
/// ```ignore
241
/// fn into_owner(self) -> $Owner
242
/// ```
243
///
244
///
245
/// ### Parameters:
246
///
247
/// - `$Vis:vis struct $StructName:ident` Name of the struct that will be
248
///   declared, this needs to be unique for the relevant scope. Example: `struct
249
///   AstCell` or `pub struct AstCell`. `$Vis` can be used to mark the struct
250
///   and all functions implemented by the macro as public.
251
///
252
///   `$(#[$StructMeta:meta])*` allows you specify further meta items for this
253
///   struct, eg. `#[doc(hidden)] struct AstCell`.
254
///
255
/// - `$Owner:ty` Type of owner. This has to have a `'static` lifetime. Example:
256
///   `String`.
257
///
258
/// - `$Dependent:ident` Name of the dependent type without specified lifetime.
259
///   This can't be a nested type name. As workaround either create a type alias
260
///   `type Dep<'a> = Option<Vec<&'a str>>;` or create a new-type `struct
261
///   Dep<'a>(Option<Vec<&'a str>>);`. Example: `Ast`.
262
///
263
///   `$Covariance:ident` Marker declaring if `$Dependent` is
264
///   [covariant](https://doc.rust-lang.org/nightly/nomicon/subtyping.html).
265
///   Possible Values:
266
///
267
///   * **covariant**: This generates the direct reference accessor function
268
///     `borrow_dependent`. This is only safe to do if this compiles `fn
269
///     _assert_covariance<'x: 'y, 'y>(x: &'y $Dependent<'x>) -> &'y $Dependent<'y>
270
///     {x}`. Otherwise you could choose a lifetime that is too short for types
271
///     with interior mutability like `Cell`, which can lead to UB in safe code.
272
///     Which would violate the promise of this library that it is safe-to-use.
273
///     If you accidentally mark a type that is not covariant as covariant, you
274
///     will get a compile time error.
275
///
276
///   * **not_covariant**: This generates no additional code but you can use the
277
///     `with_dependent` function. See [How to build a lazy AST with
278
///     self_cell](https://github.com/Voultapher/self_cell/tree/main/examples/lazy_ast)
279
///     for a usage example.
280
///
281
///   In both cases you can use the `with_dependent_mut` function to mutate the
282
///   dependent value. This is safe to do because notionally you are replacing
283
///   pointers to a value not the other way around.
284
///
285
/// - `impl {$($AutomaticDerive:ident),*},` Optional comma separated list of
286
///   optional automatic trait implementations. Possible Values:
287
///
288
///   * **Debug**: Prints the debug representation of owner and dependent.
289
///     Example: `AstCell { owner: "fox = cat + dog", dependent: Ast(["fox",
290
///     "cat", "dog"]) }`
291
///
292
///   * **PartialEq**: Logic `*self.borrow_owner() == *other.borrow_owner()`,
293
///     this assumes that `Dependent<'a>::From<&'a Owner>` is deterministic, so
294
///     that only comparing owner is enough.
295
///
296
///   * **Eq**: Will implement the trait marker `Eq` for `$StructName`. Beware
297
///     if you select this `Eq` will be implemented regardless if `$Owner`
298
///     implements `Eq`, that's an unfortunate technical limitation.
299
///
300
///   * **Hash**: Logic `self.borrow_owner().hash(state);`, this assumes that
301
///     `Dependent<'a>::From<&'a Owner>` is deterministic, so that only hashing
302
///     owner is enough.
303
///
304
///   All `AutomaticDerive` are optional and you can implement you own version
305
///   of these traits. The declared struct is part of your module and you are
306
///   free to implement any trait in any way you want. Access to the unsafe
307
///   internals is only possible via unsafe functions, so you can't accidentally
308
///   use them in safe code.
309
///
310
///   There is limited nested cell support. Eg, having an owner with non static
311
///   references. Eg `struct ChildCell<'a> { owner: &'a String, ...`. You can
312
///   use any lifetime name you want, except `_q` and only a single lifetime is
313
///   supported, and can only be used in the owner. Due to macro_rules
314
///   limitations, no `AutomaticDerive` are supported if an owner lifetime is
315
///   provided.
316
///
317
#[macro_export]
318
macro_rules! self_cell {
319
(
320
    $(#[$StructMeta:meta])*
321
    $Vis:vis struct $StructName:ident $(<$OwnerLifetime:lifetime>)? {
322
        owner: $Owner:ty,
323
324
        #[$Covariance:ident]
325
        dependent: $Dependent:ident,
326
    }
327
328
    $(impl {$($AutomaticDerive:ident),*})?
329
) => {
330
    #[repr(transparent)]
331
    $(#[$StructMeta])*
332
    $Vis struct $StructName $(<$OwnerLifetime>)? {
333
        unsafe_self_cell: $crate::unsafe_self_cell::UnsafeSelfCell<
334
            $StructName$(<$OwnerLifetime>)?,
335
            $Owner,
336
            $Dependent<'static>
337
        >,
338
339
        $(owner_marker: $crate::_covariant_owner_marker!($Covariance, $OwnerLifetime) ,)?
340
    }
341
342
    impl $(<$OwnerLifetime>)? $StructName $(<$OwnerLifetime>)? {
343
        /// Constructs a new self-referential struct.
344
        ///
345
        /// The provided `owner` will be moved into a heap allocated box.
346
        /// Followed by construction of the dependent value, by calling
347
        /// `dependent_builder` with a shared reference to the owner that
348
        /// remains valid for the lifetime of the constructed struct.
349
0
        $Vis fn new(
350
0
            owner: $Owner,
351
0
            dependent_builder: impl for<'_q> ::core::ops::FnOnce(&'_q $Owner) -> $Dependent<'_q>
352
0
        ) -> Self {
353
0
            use ::core::ptr::NonNull;
354
0
355
0
            unsafe {
356
0
                // All this has to happen here, because there is not good way
357
0
                // of passing the appropriate logic into UnsafeSelfCell::new
358
0
                // short of assuming Dependent<'static> is the same as
359
0
                // Dependent<'_q>, which I'm not confident is safe.
360
0
361
0
                // For this API to be safe there has to be no safe way to
362
0
                // capture additional references in `dependent_builder` and then
363
0
                // return them as part of Dependent. Eg. it should be impossible
364
0
                // to express: '_q should outlive 'x here `fn
365
0
                // bad<'_q>(outside_ref: &'_q String) -> impl for<'x> ::core::ops::FnOnce(&'x
366
0
                // Owner) -> Dependent<'x>`.
367
0
368
0
                type JoinedCell<'_q $(, $OwnerLifetime)?> =
369
0
                    $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'_q>>;
370
0
371
0
                let layout = $crate::alloc::alloc::Layout::new::<JoinedCell>();
372
0
                assert!(layout.size() != 0);
373
374
0
                let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap();
375
0
376
0
                let mut joined_ptr = joined_void_ptr.cast::<JoinedCell>();
377
0
378
0
                let (owner_ptr, dependent_ptr) = JoinedCell::_field_pointers(joined_ptr.as_ptr());
379
0
380
0
                // Move owner into newly allocated space.
381
0
                owner_ptr.write(owner);
382
0
383
0
                // Drop guard that cleans up should building the dependent panic.
384
0
                let drop_guard =
385
0
                    $crate::unsafe_self_cell::OwnerAndCellDropGuard::new(joined_ptr);
386
0
387
0
                // Initialize dependent with owner reference in final place.
388
0
                dependent_ptr.write(dependent_builder(&*owner_ptr));
389
0
                ::core::mem::forget(drop_guard);
390
0
391
0
                Self {
392
0
                    unsafe_self_cell: $crate::unsafe_self_cell::UnsafeSelfCell::new(
393
0
                        joined_void_ptr,
394
0
                    ),
395
0
                    $(owner_marker: $crate::_covariant_owner_marker_ctor!($OwnerLifetime) ,)?
396
0
                }
397
0
            }
398
0
        }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::new::<_>
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::new::<_>
399
400
        /// Tries to create a new structure with a given dependent builder.
401
        ///
402
        /// Consumes owner on error.
403
0
        $Vis fn try_new<Err>(
404
0
            owner: $Owner,
405
0
            dependent_builder:
406
0
                impl for<'_q> ::core::ops::FnOnce(&'_q $Owner) -> ::core::result::Result<$Dependent<'_q>, Err>
407
0
        ) -> ::core::result::Result<Self, Err> {
408
0
            use ::core::ptr::NonNull;
409
0
410
0
            unsafe {
411
0
                // See fn new for more explanation.
412
0
413
0
                type JoinedCell<'_q $(, $OwnerLifetime)?> =
414
0
                    $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'_q>>;
415
0
416
0
                let layout = $crate::alloc::alloc::Layout::new::<JoinedCell>();
417
0
                assert!(layout.size() != 0);
418
419
0
                let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap();
420
0
421
0
                let mut joined_ptr = joined_void_ptr.cast::<JoinedCell>();
422
0
423
0
                let (owner_ptr, dependent_ptr) = JoinedCell::_field_pointers(joined_ptr.as_ptr());
424
0
425
0
                // Move owner into newly allocated space.
426
0
                owner_ptr.write(owner);
427
0
428
0
                // Drop guard that cleans up should building the dependent panic.
429
0
                let mut drop_guard =
430
0
                    $crate::unsafe_self_cell::OwnerAndCellDropGuard::new(joined_ptr);
431
0
432
0
                match dependent_builder(&*owner_ptr) {
433
0
                    ::core::result::Result::Ok(dependent) => {
434
0
                        dependent_ptr.write(dependent);
435
0
                        ::core::mem::forget(drop_guard);
436
0
437
0
                        ::core::result::Result::Ok(Self {
438
0
                            unsafe_self_cell: $crate::unsafe_self_cell::UnsafeSelfCell::new(
439
0
                                joined_void_ptr,
440
0
                            ),
441
0
                            $(owner_marker: $crate::_covariant_owner_marker_ctor!($OwnerLifetime) ,)?
442
0
                        })
443
                    }
444
0
                    ::core::result::Result::Err(err) => ::core::result::Result::Err(err)
445
                }
446
            }
447
0
        }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::try_new::<wasmer_types::error::DeserializeError, <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchive>::try_new<<wasmer_compiler::engine::artifact::Artifact>::deserialize::{closure#0}>::{closure#0}>
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::try_new::<wasmer_types::error::DeserializeError, <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchive>::try_new<<wasmer_compiler::engine::artifact::Artifact>::deserialize_unchecked::{closure#0}>::{closure#0}>
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::try_new::<wasmer_types::error::DeserializeError, <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchive>::try_new<<wasmer_compiler::engine::artifact::Artifact>::deserialize::{closure#0}>::{closure#0}>
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::try_new::<wasmer_types::error::DeserializeError, <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchive>::try_new<<wasmer_compiler::engine::artifact::Artifact>::deserialize_unchecked::{closure#0}>::{closure#0}>
448
0
449
0
        /// Tries to create a new structure with a given dependent builder.
450
0
        ///
451
0
        /// Returns owner on error.
452
0
        $Vis fn try_new_or_recover<Err>(
453
0
            owner: $Owner,
454
0
            dependent_builder:
455
0
                impl for<'_q> ::core::ops::FnOnce(&'_q $Owner) -> ::core::result::Result<$Dependent<'_q>, Err>
456
0
        ) -> ::core::result::Result<Self, ($Owner, Err)> {
457
0
            use ::core::ptr::NonNull;
458
0
459
0
            unsafe {
460
0
                // See fn new for more explanation.
461
0
462
0
                type JoinedCell<'_q $(, $OwnerLifetime)?> =
463
0
                    $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'_q>>;
464
0
465
0
                let layout = $crate::alloc::alloc::Layout::new::<JoinedCell>();
466
0
                assert!(layout.size() != 0);
467
468
0
                let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap();
469
0
470
0
                let mut joined_ptr = joined_void_ptr.cast::<JoinedCell>();
471
0
472
0
                let (owner_ptr, dependent_ptr) = JoinedCell::_field_pointers(joined_ptr.as_ptr());
473
0
474
0
                // Move owner into newly allocated space.
475
0
                owner_ptr.write(owner);
476
0
477
0
                // Drop guard that cleans up should building the dependent panic.
478
0
                let mut drop_guard =
479
0
                    $crate::unsafe_self_cell::OwnerAndCellDropGuard::new(joined_ptr);
480
0
481
0
                match dependent_builder(&*owner_ptr) {
482
0
                    ::core::result::Result::Ok(dependent) => {
483
0
                        dependent_ptr.write(dependent);
484
0
                        ::core::mem::forget(drop_guard);
485
0
486
0
                        ::core::result::Result::Ok(Self {
487
0
                            unsafe_self_cell: $crate::unsafe_self_cell::UnsafeSelfCell::new(
488
0
                                joined_void_ptr,
489
0
                            ),
490
0
                            $(owner_marker: $crate::_covariant_owner_marker_ctor!($OwnerLifetime) ,)?
491
0
                        })
492
                    }
493
0
                    ::core::result::Result::Err(err) => {
494
0
                        // In contrast to into_owner ptr::read, here no dependent
495
0
                        // ever existed in this function and so we are sure its
496
0
                        // drop impl can't access owner after the read.
497
0
                        // And err can't return a reference to owner.
498
0
                        let owner_on_err = ::core::ptr::read(owner_ptr);
499
0
500
0
                        // Allowing drop_guard to finish would let it double free owner.
501
0
                        // So we dealloc the JoinedCell here manually.
502
0
                        ::core::mem::forget(drop_guard);
503
0
                        $crate::alloc::alloc::dealloc(joined_void_ptr.as_ptr(), layout);
504
0
505
0
                        ::core::result::Result::Err((owner_on_err, err))
506
                    }
507
                }
508
            }
509
0
        }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::try_new_or_recover::<_, _>
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::try_new_or_recover::<_, _>
510
0
511
0
        /// Borrows owner.
512
0
        $Vis fn borrow_owner<'_q>(&'_q self) -> &'_q $Owner {
513
0
            unsafe { self.unsafe_self_cell.borrow_owner::<$Dependent<'_q>>() }
514
0
        }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::borrow_owner
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::borrow_owner
515
516
        /// Calls given closure `func` with a shared reference to dependent.
517
0
        $Vis fn with_dependent<'outer_fn, Ret>(
518
0
            &'outer_fn self,
519
0
            func: impl for<'_q> ::core::ops::FnOnce(&'_q $Owner, &'outer_fn $Dependent<'_q>
520
0
        ) -> Ret) -> Ret {
521
0
            unsafe {
522
0
                func(
523
0
                    self.unsafe_self_cell.borrow_owner::<$Dependent>(),
524
0
                    self.unsafe_self_cell.borrow_dependent()
525
0
                )
526
0
            }
527
0
        }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::with_dependent::<core::result::Result<(), core::fmt::Error>, <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell as core::fmt::Debug>::fmt::{closure#0}>
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::with_dependent::<core::result::Result<(), core::fmt::Error>, <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell as core::fmt::Debug>::fmt::{closure#0}>
528
529
        /// Calls given closure `func` with an unique reference to dependent.
530
0
        $Vis fn with_dependent_mut<'outer_fn, Ret>(
531
0
            &'outer_fn mut self,
532
0
            func: impl for<'_q> ::core::ops::FnOnce(&'_q $Owner, &'outer_fn mut $Dependent<'_q>) -> Ret
533
0
        ) -> Ret {
534
0
            let (owner, dependent) = unsafe {
535
0
                    self.unsafe_self_cell.borrow_mut()
536
0
            };
537
0
538
0
            func(owner, dependent)
539
0
        }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::with_dependent_mut::<_, _>
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::with_dependent_mut::<_, _>
540
541
        $crate::_covariant_access!($Covariance, $Vis, $Dependent);
542
543
        /// Consumes `self` and returns the the owner.
544
0
        $Vis fn into_owner(self) -> $Owner {
545
0
            // This is only safe to do with repr(transparent).
546
0
            let unsafe_self_cell = unsafe { ::core::mem::transmute::<
547
0
                Self,
548
0
                $crate::unsafe_self_cell::UnsafeSelfCell<
549
0
                    $StructName$(<$OwnerLifetime>)?,
550
0
                    $Owner,
551
0
                    $Dependent<'static>
552
0
                >
553
0
            >(self) };
554
0
555
0
            let owner = unsafe { unsafe_self_cell.into_owner::<$Dependent>() };
556
0
557
0
            owner
558
0
        }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::into_owner
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::into_owner
559
    }
560
561
    impl $(<$OwnerLifetime>)? Drop for $StructName $(<$OwnerLifetime>)? {
562
0
        fn drop(&mut self) {
563
0
            unsafe {
564
0
                self.unsafe_self_cell.drop_joined::<$Dependent>();
565
0
            }
566
0
        }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell as core::ops::drop::Drop>::drop
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell as core::ops::drop::Drop>::drop
567
    }
568
569
    // The user has to choose which traits can and should be automatically
570
    // implemented for the cell.
571
    $($(
572
        $crate::_impl_automatic_derive!($AutomaticDerive, $StructName);
573
    )*)*
574
};
575
}
576
577
#[doc(hidden)]
578
#[macro_export]
579
macro_rules! _covariant_access {
580
    (covariant, $Vis:vis, $Dependent:ident) => {
581
        /// Borrows dependent.
582
0
        $Vis fn borrow_dependent<'_q>(&'_q self) -> &'_q $Dependent<'_q> {
583
0
            fn _assert_covariance<'x: 'y, 'y>(x: &'y $Dependent<'x>) -> &'y $Dependent<'y> {
584
0
                //  This function only compiles for covariant types.
585
0
                x // Change the macro invocation to not_covariant.
586
0
            }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::borrow_dependent::_assert_covariance
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::borrow_dependent::_assert_covariance
587
0
588
0
            unsafe { self.unsafe_self_cell.borrow_dependent() }
589
0
        }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::borrow_dependent
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell>::borrow_dependent
590
    };
591
    (not_covariant, $Vis:vis, $Dependent:ident) => {
592
        // For types that are not covariant it's unsafe to allow
593
        // returning direct references.
594
        // For example a lifetime that is too short could be chosen:
595
        // See https://github.com/Voultapher/self_cell/issues/5
596
    };
597
    ($x:ident, $Vis:vis, $Dependent:ident) => {
598
        compile_error!("This macro only accepts `covariant` or `not_covariant`");
599
    };
600
}
601
602
#[doc(hidden)]
603
#[macro_export]
604
macro_rules! _covariant_owner_marker {
605
    (covariant, $OwnerLifetime:lifetime) => {
606
        // Ensure that contravariant owners don't imply covariance
607
        // over the dependent. See issue https://github.com/Voultapher/self_cell/issues/18
608
        ::core::marker::PhantomData<&$OwnerLifetime ()>
609
    };
610
    (not_covariant, $OwnerLifetime:lifetime) => {
611
        // See the discussion in https://github.com/Voultapher/self_cell/pull/29
612
        //
613
        // If the dependent is non_covariant, mark the owner as invariant over its
614
        // lifetime. Otherwise unsound use is possible.
615
        ::core::marker::PhantomData<fn(&$OwnerLifetime ()) -> &$OwnerLifetime ()>
616
    };
617
    ($x:ident, $OwnerLifetime:lifetime) => {
618
        compile_error!("This macro only accepts `covariant` or `not_covariant`");
619
    };
620
}
621
622
#[doc(hidden)]
623
#[macro_export]
624
macro_rules! _covariant_owner_marker_ctor {
625
    ($OwnerLifetime:lifetime) => {
626
        // Helper to optionally expand into PhantomData for construction.
627
        ::core::marker::PhantomData
628
    };
629
}
630
631
#[doc(hidden)]
632
#[macro_export]
633
macro_rules! _impl_automatic_derive {
634
    (Debug, $StructName:ident) => {
635
        impl ::core::fmt::Debug for $StructName {
636
0
            fn fmt(
637
0
                &self,
638
0
                fmt: &mut ::core::fmt::Formatter,
639
0
            ) -> ::core::result::Result<(), ::core::fmt::Error> {
640
0
                self.with_dependent(|owner, dependent| {
641
0
                    fmt.debug_struct(stringify!($StructName))
642
0
                        .field("owner", owner)
643
0
                        .field("dependent", dependent)
644
0
                        .finish()
645
0
                })
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell as core::fmt::Debug>::fmt::{closure#0}
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell as core::fmt::Debug>::fmt::{closure#0}
646
0
            }
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell as core::fmt::Debug>::fmt
Unexecuted instantiation: <wasmer_compiler::artifact_builders::artifact_builder::ArtifactBuildFromArchiveCell as core::fmt::Debug>::fmt
647
        }
648
    };
649
    (PartialEq, $StructName:ident) => {
650
        impl ::core::cmp::PartialEq for $StructName {
651
            fn eq(&self, other: &Self) -> bool {
652
                *self.borrow_owner() == *other.borrow_owner()
653
            }
654
        }
655
    };
656
    (Eq, $StructName:ident) => {
657
        // TODO this should only be allowed if owner is Eq.
658
        impl ::core::cmp::Eq for $StructName {}
659
    };
660
    (Hash, $StructName:ident) => {
661
        impl ::core::hash::Hash for $StructName {
662
            fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
663
                self.borrow_owner().hash(state);
664
            }
665
        }
666
    };
667
    ($x:ident, $StructName:ident) => {
668
        compile_error!(concat!(
669
            "No automatic trait impl for trait: ",
670
            stringify!($x)
671
        ));
672
    };
673
}