From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- third_party/rust/self_cell/README.md | 186 +++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 third_party/rust/self_cell/README.md (limited to 'third_party/rust/self_cell/README.md') diff --git a/third_party/rust/self_cell/README.md b/third_party/rust/self_cell/README.md new file mode 100644 index 0000000000..819bdc87ca --- /dev/null +++ b/third_party/rust/self_cell/README.md @@ -0,0 +1,186 @@ +[github](https://github.com/Voultapher/self_cell) +[crates.io](https://crates.io/crates/self_cell) +[docs.rs](https://docs.rs/self_cell) + +# `self_cell!` + +Use the macro-rules macro: `self_cell!` to create safe-to-use self-referential +structs in stable Rust, without leaking the struct internal lifetime. + +In a nutshell, the API looks *roughly* like this: + +```rust +// User code: + +self_cell!( + struct NewStructName { + owner: Owner, + + #[covariant] + dependent: Dependent, + } + + impl {Debug} +); + +// Generated by macro: + +struct NewStructName(...); + +impl NewStructName { + fn new( + owner: Owner, + dependent_builder: impl for<'a> FnOnce(&'a Owner) -> Dependent<'a> + ) -> NewStructName { ... } + fn borrow_owner<'a>(&'a self) -> &'a Owner { ... } + fn borrow_dependent<'a>(&'a self) -> &'a Dependent<'a> { ... } +} + +impl Debug for NewStructName { ... } +``` + +Self-referential structs are currently not supported with safe vanilla Rust. The +only reasonable safe alternative is to expect the user to juggle 2 separate data +structures which is a mess. The library solution ouroboros is really expensive +to compile due to its use of procedural macros. + +This alternative is `no_std`, uses no proc-macros, some self contained unsafe +and works on stable Rust, and is miri tested. With a total of less than 300 +lines of implementation code, which consists mostly of type and trait +implementations, this crate aims to be a good minimal solution to the problem of +self-referential structs. + +It has undergone [community code review](https://users.rust-lang.org/t/experimental-safe-to-use-proc-macro-free-self-referential-structs-in-stable-rust/52775) +from experienced Rust users. + +### Fast compile times + +``` +$ rm -rf target && cargo +nightly build -Z timings + +Compiling self_cell v0.9.0 +Completed self_cell v0.9.0 in 0.2s +``` + +Because it does **not** use proc-macros, and has 0 dependencies compile-times +are fast. + +Measurements done on a slow laptop. + +### A motivating use case + +```rust +use self_cell::self_cell; + +#[derive(Debug, Eq, PartialEq)] +struct Ast<'a>(pub Vec<&'a str>); + +self_cell!( + struct AstCell { + owner: String, + + #[covariant] + dependent: Ast, + } + + impl {Debug, Eq, PartialEq} +); + +fn build_ast_cell(code: &str) -> AstCell { + // Create owning String on stack. + let pre_processed_code = code.trim().to_string(); + + // Move String into AstCell, then build Ast inplace. + AstCell::new( + pre_processed_code, + |code| Ast(code.split(' ').filter(|word| word.len() > 1).collect()) + ) +} + +fn main() { + let ast_cell = build_ast_cell("fox = cat + dog"); + + println!("ast_cell -> {:?}", &ast_cell); + println!("ast_cell.borrow_owner() -> {:?}", ast_cell.borrow_owner()); + println!("ast_cell.borrow_dependent().0[1] -> {:?}", ast_cell.borrow_dependent().0[1]); +} +``` + +``` +$ cargo run + +ast_cell -> AstCell { owner: "fox = cat + dog", dependent: Ast(["fox", "cat", "dog"]) } +ast_cell.borrow_owner() -> "fox = cat + dog" +ast_cell.borrow_dependent().0[1] -> "cat" +``` + +There is no way in safe Rust to have an API like `build_ast_cell`, as soon as +`Ast` depends on stack variables like `pre_processed_code` you can't return the +value out of the function anymore. You could move the pre-processing into the +caller but that gets ugly quickly because you can't encapsulate things anymore. +Note this is a somewhat niche use case, self-referential structs should only be +used when there is no good alternative. + +Under the hood, it heap allocates a struct which it initializes first by moving +the owner value to it and then using the reference to this now Pin/Immovable +owner to construct the dependent inplace next to it. This makes it safe to move +the generated SelfCell but you have to pay for the heap allocation. + +See the documentation for a more in-depth API overview and advanced examples: +https://docs.rs/self_cell + +### Installing + +[See cargo docs](https://doc.rust-lang.org/cargo/guide/). + +## Running the tests + +``` +cargo test + +cargo miri test +``` + +### Related projects + +[ouroboros](https://github.com/joshua-maros/ouroboros) + +[rental](https://github.com/jpernst/rental) + +[Schroedinger](https://github.com/dureuill/sc) + +[owning_ref](https://github.com/Kimundi/owning-ref-rs) + +[ghost-cell](https://github.com/matthieu-m/ghost-cell) + +## Min required rustc version + +By default the minimum required rustc version is 1.51. + +There is an optional feature you can enable called "old_rust" that enables +support down to rustc version 1.36. However this requires polyfilling std +library functionality for older rustc with technically UB versions. Testing does +not show older rustc versions (ab)using this. Use at your own risk. + +The minimum versions are a best effor and may change with any new major release. + +## Contributing + +Please respect the [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) when contributing. + +## Versioning + +We use [SemVer](http://semver.org/) for versioning. For the versions available, +see the [tags on this repository](https://github.com/Voultapher/self_cell/tags). + +## Authors + +* **Lukas Bergdoll** - *Initial work* - [Voultapher](https://github.com/Voultapher) + +See also the list of [contributors](https://github.com/Voultapher/self_cell/contributors) +who participated in this project. + +## License + +This project is licensed under the Apache License, Version 2.0 - +see the [LICENSE.md](LICENSE.md) file for details. -- cgit v1.2.3