diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/ouroboros | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/ouroboros')
-rw-r--r-- | third_party/rust/ouroboros/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/ouroboros/Cargo.toml | 27 | ||||
-rw-r--r-- | third_party/rust/ouroboros/src/lib.rs | 249 |
3 files changed, 277 insertions, 0 deletions
diff --git a/third_party/rust/ouroboros/.cargo-checksum.json b/third_party/rust/ouroboros/.cargo-checksum.json new file mode 100644 index 0000000000..764dcc22be --- /dev/null +++ b/third_party/rust/ouroboros/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"5e757a99e461764a5fadbc8dd3d55570c1d41c6ffeee2b8bdae58db95fcf44c4","src/lib.rs":"60fad6e825c78e83c577ed4134132c46d7d3e613ea764089e9dce57396e9dfa0"},"package":"b0b666c900ea45a357bc7915a4dc8fab7e295f2e756e843aa3c0788d94aa3a29"}
\ No newline at end of file diff --git a/third_party/rust/ouroboros/Cargo.toml b/third_party/rust/ouroboros/Cargo.toml new file mode 100644 index 0000000000..f622812d9e --- /dev/null +++ b/third_party/rust/ouroboros/Cargo.toml @@ -0,0 +1,27 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "ouroboros" +version = "0.7.0" +authors = ["Joshua Maros <joshua-maros@github.com>"] +description = "Easy, safe self-referential struct generation." +documentation = "https://docs.rs/ouroboros" +readme = "../README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/joshua-maros/ouroboros" +[dependencies.ouroboros_macro] +version = "0.7.0" + +[dependencies.stable_deref_trait] +version = "1.2" diff --git a/third_party/rust/ouroboros/src/lib.rs b/third_party/rust/ouroboros/src/lib.rs new file mode 100644 index 0000000000..12f053a4fe --- /dev/null +++ b/third_party/rust/ouroboros/src/lib.rs @@ -0,0 +1,249 @@ +//! A crate for creating safe self-referencing structs. +//! +//! See the documentation of [`ouroboros_examples`](https://docs.rs/ouroboros_examples) for +//! sample documentation of structs which have had the macro applied to them. + +#![allow(clippy::needless_doctest_main)] + +/// This macro is used to turn a regular struct into a self-referencing one. An example: +/// ```rust +/// use ouroboros::self_referencing; +/// +/// #[self_referencing] +/// struct MyStruct { +/// int_data: Box<i32>, +/// float_data: Box<f32>, +/// #[borrows(int_data)] +/// int_reference: &'this i32, +/// #[borrows(mut float_data)] +/// float_reference: &'this mut f32, +/// } +/// +/// fn main() { +/// let mut my_value = MyStructBuilder { +/// int_data: Box::new(42), +/// float_data: Box::new(3.14), +/// int_reference_builder: |int_data: &i32| int_data, +/// float_reference_builder: |float_data: &mut f32| float_data, +/// }.build(); +/// +/// // Prints 42 +/// println!("{:?}", my_value.borrow_int_data()); +/// // Prints 3.14 +/// println!("{:?}", my_value.borrow_float_reference()); +/// // Sets the value of float_data to 84.0 +/// my_value.with_mut(|fields| { +/// **fields.float_reference = (**fields.int_reference as f32) * 2.0; +/// }); +/// +/// // We can hold on to this reference... +/// let int_ref = *my_value.borrow_int_reference(); +/// println!("{:?}", *int_ref); +/// // As long as the struct is still alive. +/// drop(my_value); +/// // This will cause an error! +/// // println!("{:?}", *int_ref); +/// } +/// ``` +/// To explain the features and limitations of this crate, some definitions are necessary: +/// # Definitions +/// - **immutably borrowed field**: a field which is immutably borrowed by at least one other field. +/// - **mutably borrowed field**: a field which is mutably borrowed by exactly one other field. +/// - **self-referencing field**: a field which borrows at least one other field. +/// - **head field**: a field which does not borrow any other fields, I.E. not self-referencing. +/// This does not include fields with empty borrows annotations (`#[borrows()]`.) +/// - **tail field**: a field which is not borrowed by any other fields. +/// +/// # Usage +/// To make a self-referencing struct, you must write a struct definition and place +/// `#[self_referencing]` on top. For every field that borrows other fields, you must place +/// `#[borrows()]` on top and place inside the parenthesis a list of fields that it borrows. Mut can +/// be prefixed to indicate that a mutable borrow is required. For example, +/// `#[borrows(a, b, mut c)]` indicates that the first two fields need to be borrowed immutably and +/// the third needs to be borrowed mutably. You can also use `#[borrows()]` without any arguments to +/// indicate a field that will eventually borrow from the struct, but does not borrow anything when +/// first created. For example, you could use this on a field like `error: Option<&'this str>`. +/// +/// # You must comply with these limitations +/// - Fields must be declared before the first time they are borrowed. +/// - Normal borrowing rules apply, E.G. a field cannot be borrowed mutably twice. +/// - Fields that are borrowed must be of a data type that implement +/// [`StableDeref`](https://docs.rs/stable_deref_trait/1.2.0/stable_deref_trait/trait.StableDeref.html). +/// Normally this just means `Box<T>`. +/// - Fields that use the `'this` lifetime must have a corresponding `#[borrows()]` annotation. +/// The error for this needs some work, currently you will get an error saying that `'this` is +/// undefined at the location it was illegally used in. +/// +/// Violating them will result in an error message directly pointing out the violated rule. +/// +/// # Flexibility of this crate +/// The example above uses plain references as the self-referencing part of the struct, but you can +/// use anything that is dependent on lifetimes of objects inside the struct. For example, you could +/// do something like this: +/// ```rust +/// use ouroboros::self_referencing; +/// +/// pub struct ComplexData<'a, 'b> { +/// aref: &'a i32, +/// bref: &'b mut i32, +/// number: i32, +/// } +/// +/// impl<'a, 'b> ComplexData<'a, 'b> { +/// fn new(aref: &'a i32, bref: &'b mut i32, number: i32) -> Self { +/// Self { aref, bref, number } +/// } +/// +/// /// Copies the value aref points to into what bref points to. +/// fn transfer(&mut self) { +/// *self.bref = *self.aref; +/// } +/// +/// /// Prints the value bref points to. +/// fn print_bref(&self) { +/// println!("{}", *self.bref); +/// } +/// } +/// +/// fn main() { +/// #[self_referencing] +/// struct DataStorage { +/// immutable: Box<i32>, +/// mutable: Box<i32>, +/// #[borrows(immutable, mut mutable)] +/// complex_data: ComplexData<'this, 'this>, +/// } +/// +/// let mut data_storage = DataStorageBuilder { +/// immutable: Box::new(10), +/// mutable: Box::new(20), +/// complex_data_builder: |i: &i32, m: &mut i32| ComplexData::new(i, m, 12345), +/// }.build(); +/// data_storage.with_complex_data_mut(|data| { +/// // Copies the value in immutable into mutable. +/// data.transfer(); +/// // Prints 10 +/// data.print_bref(); +/// }); +/// } +/// ``` +/// # Using `chain_hack` +/// Unfortunately, as of September 2020, Rust has a +/// [known limitation in its type checker](https://users.rust-lang.org/t/why-does-this-not-compile-box-t-target-t/49027/7?u=aaaaa) +/// which prevents chained references from working (I.E. structs where field C references field B +/// which references field A.) To counteract this problem, you can use +/// `#[self_referencing(chain_hack)]` to allow creating these kinds of structs at the cost of +/// additional restrictions and possible loss of clarity in some error messages. The main limitation +/// is that all fields that are borrowed must be of type `Box<T>`. A nice error message will be +/// generated if you use a different type. There should be no other limitations, but some +/// configurations may produce strange compiler errors. If you find such a configuration, please +/// open an issue on the [Github repository](https://github.com/joshua-maros/ouroboros/issues). +/// You can view a documented example of a struct which uses `chain_hack` [here](https://docs.rs/ouroboros_examples/latest/ouroboros_examples/struct.ChainHack.html). +/// +/// # What does the macro generate? +/// The `#[self_referencing]` struct will replace your definition with an unsafe self-referencing +/// struct with a safe public interface. Many functions will be generated depending on your original +/// struct definition. Documentation is generated for all items, so building documentation for +/// your project allows accessing detailed information about available functions. Using +/// `#[self_referencing(no_doc)]` will hide the generated items from documentation if it is becoming +/// too cluttered. +/// +/// ### A quick note on visibility +/// The visibility of generated items is dependent on one of two things. If the +/// generated item is related to a specific field of the struct, it uses the visibility of the +/// original field. (The actual field in the struct will be made private since accessing it could cause +/// undefined behavior.) If the generated item is not related to any particular field, it will by +/// default only be visible to the module the struct is declared in. (This includes things like +/// `new()` and `with()`.) You can use `#[self_referencing(pub_extras)]` to make these items have the +/// same visibility as the struct itself. +/// +/// # List of generated items +/// ### `MyStruct::new(fields...) -> MyStruct` +/// A basic constructor. It accepts values for each field in the order you declared them in. For +/// **head fields**, you only need to pass in what value it should have and it will be moved in +/// to the output. For **self-referencing fields**, you must provide a function or closure which creates +/// the value based on the values it borrows. A field using the earlier example of +/// `#[borrow(a, b, mut c)]` would require a function typed as +/// `FnOnce(a: &_, b: &_, c: &mut _) -> _`. Fields which have an empty borrows annotation +/// (`#[borrows()]`) should have their value directly passed in. A field using the earlier example +/// of `Option<&'this str>` would require an input of `None`. Do not pass a function. Do not collect +/// 200 dollars. +/// ### `MyStructBuilder` +/// This is the preferred way to create a new instance of your struct. It is similar to using the +/// `MyStruct { a, b, c, d }` syntax instead of `MyStruct::new(a, b, c, d)`. It contains one field +/// for every argument in the actual constructor. **Head fields** have the same name that you +/// originally defined them with. **self-referencing fields** are suffixed with `_builder` since you need +/// to provide a function instead of a value. Fields with an empty borrows annotation are not +/// initialized using builders. Calling `.build()` on an instance of `MyStructBuilder` +/// will convert it to an instance of `MyStruct`. +/// ### `MyStruct::try_new<E>(fields...) -> Result<MyStruct, E>` +/// Similar to the regular `new()` function, except the functions wich create values for all +/// **self-referencing fields** can return `Result<>`s. If any of those are `Err`s, that error will be +/// returned instead of an instance of `MyStruct`. The preferred way to use this function is through +/// `MyStructTryBuilder` and its `try_build()` function. +/// ### `MyStruct::try_new_or_recover<E>(fields...) -> Result<MyStruct, (E, Heads)>` +/// Similar to the `try_new()` function, except that all the **head fields** are returned along side +/// the original error in case of an error. The preferred way to use this function is through +/// `MyStructTryBuilder` and its `try_build_or_recover()` function. +/// ### `MyStruct::with_FIELD<R>(&self, user: FnOnce(field: &FieldType) -> R) -> R` +/// This function is generated for every **tail and immutably-borrowed field** in your struct. It +/// allows safely accessing +/// a reference to that value. The function generates the reference and passes it to `user`. You +/// can do anything you want with the reference, it is constructed to not outlive the struct. +/// ### `MyStruct::borrow_FIELD(&self) -> &FieldType` +/// This function is generated for every **tail and immutably-borrowed field** in your struct. It +/// is equivalent to calling `my_struct.with_FIELD(|field| field)`. Note that certain types of +/// fields would cause this function to generate a compiler error, so it is ommitted. Generally, if +/// your field uses `'this` as a lifetime parameter, the corresponding `borrow_FIELD` function will +/// not be generated. There is no `borrow_FIELD_mut`, unfortunately, as Rust's +/// borrow checker is currently not capable of ensuring that such a method would be used safely. +/// ### `MyStruct::with_FIELD_mut<R>(&mut self, user: FnOnce(field: &mut FieldType) -> R) -> R` +/// This function is generated for every **tail field** in your struct. It is the mutable version +/// of `with_FIELD`. +/// ### `MyStruct::with<R>(&self, user: FnOnce(fields: AllFields) -> R) -> R` +/// Allows borrowing all **tail and immutably-borrowed fields** at once. Functions similarly to +/// `with_FIELD`. +/// ### `MyStruct::with_mut<R>(&self, user: FnOnce(fields: AllFields) -> R) -> R` +/// Allows mutably borrowing all **tail fields** and immutably borrowing all **immutably-borrowed** +/// fields at once. Functions similarly to `with_FIELD_mut`, except that you can borrow multiple +/// fields as mutable at the same time and also have immutable access to any remaining fields. +/// ### `MyStruct::into_heads(self) -> Heads` +/// Drops all self-referencing fields and returns a struct containing all **head fields**. +pub use ouroboros_macro::self_referencing; + +#[doc(hidden)] +pub mod macro_help { + use stable_deref_trait::StableDeref; + use std::ops::DerefMut; + + /// Converts a reference to an object implementing Deref to a static reference to the data it + /// Derefs to. This is obviously unsafe because the compiler can no longer guarantee that the + /// data outlives the reference. This function is templated to only work for containers that + /// implement StableDeref, E.G. Box and Rc. The intent is that the data that is being pointed + /// to will never move as long as the container itself is not dropped. It is up to the consumer + /// to get rid of the reference before the container is dropped. The + 'static ensures that + /// whatever we are referring to will remain valid indefinitely, that there are no limitations + /// on how long the pointer itself can live. + /// + /// # Safety + /// + /// The caller must ensure that the returned reference is not used after the originally passed + /// reference would become invalid. + pub unsafe fn stable_deref_and_strip_lifetime<'a, T: StableDeref + 'static>( + data: &'a T, + ) -> &'static T::Target { + &*((&**data) as *const _) + } + + /// Like stable_deref_and_strip_lifetime, but for mutable references. + /// + /// # Safety + /// + /// The caller must ensure that the returned reference is not used after the originally passed + /// reference would become invalid. + pub unsafe fn stable_deref_and_strip_lifetime_mut<'a, T: StableDeref + DerefMut + 'static>( + data: &'a mut T, + ) -> &'static mut T::Target { + &mut *((&mut **data) as *mut _) + } +} |