{"id":16991631,"url":"https://github.com/pstolarz/rust-playground","last_synced_at":"2025-03-22T04:11:13.822Z","repository":{"id":98196827,"uuid":"457037680","full_name":"pstolarz/rust-playground","owner":"pstolarz","description":"My Rust battlefield.","archived":false,"fork":false,"pushed_at":"2024-12-08T17:56:19.000Z","size":78,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-03T04:32:41.637Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pstolarz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-08T17:36:39.000Z","updated_at":"2024-12-08T17:56:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"92df7ef3-66bc-4406-a505-bf0513098f13","html_url":"https://github.com/pstolarz/rust-playground","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pstolarz%2Frust-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pstolarz%2Frust-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pstolarz%2Frust-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pstolarz%2Frust-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pstolarz","download_url":"https://codeload.github.com/pstolarz/rust-playground/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244902928,"owners_count":20529115,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T03:26:42.792Z","updated_at":"2025-03-22T04:11:13.806Z","avatar_url":"https://github.com/pstolarz.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# My Rust battlefield\n\n* Rust Operators and symbols\n  [[RPL]](https://doc.rust-lang.org/book/appendix-02-operators.html)\n* _Type coercions_ - automatic type conversions in some specific cases.\n  [[REF]](https://doc.rust-lang.org/reference/type-coercions.html).\n* _Deref coercions_ - automatic dereference and type conversion for `Deref` implementers.\n  [[RPL]](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/deref-coercions.html).\n* _Orphan rule_ (aka _Coherence_) - Implementation allowed in the same crate.\n  [[RPL]](https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type).\n* Rust undefined behaviour [[REF]](https://doc.rust-lang.org/reference/behavior-considered-undefined.html).\n\n* Unsized objects:\n  * slices (including `str`),\n  * Trait objects [[REF]](https://doc.rust-lang.org/reference/types/trait-object.html),\n  * `struct` with last object unsized.\n\n## Variable declaration\n\n**let** [**ref**] [**mut**] _VAR_ [**:**_T_] [**=** _RHS_] **;**\n\nwhere:\n\n_T_ - specifies _RHS_ value type. If not specified _T_ is implied from _RHS_.\u003cbr\u003e\n\n_T_: [**\u0026mut**] [**\u0026**] _T_\u003cbr\u003e\n_T_: _non_ref_type_\n\n**ref**, **mut** defines _VAR_ as a reference and/or make it mutable.\n\n```rust\n// i type: i32\nlet i = 0;\n// ri type: \u0026i32\nlet ref ri = i;\n// rri type: \u0026\u0026i32\nlet ref rri = ri;\n// mi type: mutable i32\nlet mut mi = i;\n// rmi type: \u0026mut i32\nlet ref mut rmi = mi;\n```\n\nNote, the most generic format of the variable(s) declaration is:\n\n**let** _PATTERN_ = _RHS_ **;**\n\nThat means pattern matching may occur for the **let** statement, e.g.:\n\n```rust\nlet mut mi = 0;\nlet ref mut rmi = mi;\n\n// pattern matching, i type: i32\nlet \u0026mut i = rmi;\n```\n\n## `Fn`, `FnMut`, `FnOnce`\n\n* Function traits inheritance\n  `Fn`: possible to call multiple times for multiple copies,\u003cbr\u003e\n  `FnMut`: possible to call multiple times for a single copy,\u003cbr\u003e\n  `FnOnce`: possible to call once for a single copy.\u003cbr\u003e\n\n  If an object may be called multiple times for multiple copies, it may be also\n  called multiple times for a single copy. Similarly, if an object may be called\n  multiple times for a single copy, it may be also called once for that copy.\n\n  For that reason `Fn` is subtype of `FnMut` which is subtype of `FnOnce`.\n\n* If function trait doesn't own accessed objects, it contains references to them\n  (mutable on non-mutable). The compiler elides the references lifetime. In some\n  cases it may be required to explicitly refer to the lifetime. Good example is\n  provided in `std::thread::scope`:\n\n  ```rust\n  pub fn scope\u003c'env, F, T\u003e(f: F) -\u003e T\n  where\n       F: for\u003c'scope\u003e FnOnce(\u0026'scope Scope\u003c'scope, 'env\u003e) -\u003e T,\n  {\n      // We put the `ScopeData` into an `Arc` so that other threads can finish their\n      // `decrement_num_running_threads` even after this function returns.\n      let scope = Scope {\n          data: Arc::new(ScopeData {\n              num_running_threads: AtomicUsize::new(0),\n              main_thread: current(),\n              a_thread_panicked: AtomicBool::new(false),\n          }),\n          env: PhantomData,\n          scope: PhantomData,\n      };\n\n      // Run `f`, but catch panics so we can make sure to wait for all the threads to join.\n      let result = catch_unwind(AssertUnwindSafe(|| f(\u0026scope)));\n\n      ...\n  }\n  ```\n\n  Here `'env` denotes `f` environment lifetime (that is reference lifetime of\n  objects accessed by `f`).\n\n  NOTES\n  * At first `scope` object is created without `'scope` and `'env` lifetimes\n    which are specified later on - once `f` is called and the actual lifetimes\n    are known (an object needs not to be fully specified until its first use,\n    that is, in this case, the `f` call).\n  * `F: for\u003c'scope\u003e FnOnce(\u0026'scope Scope\u003c'scope, 'env\u003e) -\u003e T` uses `'scope`\n    lifetime in _HRTB_ context, while `'env` is bound to `f` environment lifetime.\n\n## `Send`, `Sync`\n\n* `Send`: unsafe auto trait marking a type `T` as safe to be sent between threads\n  (value move).\n* `Sync`: unsafe auto trait marking a type `T` as safe to be shared between threads\n  (`\u0026T` is therefore `Send`).\n\nSee [[NOM]](https://doc.rust-lang.org/nomicon/send-and-sync.html) and\n[[STD]](https://doc.rust-lang.org/std/marker/trait.Sync.html).\n\n\n```rust\n#![feature(negative_impls)]\n\nstruct S1;\nstruct S2;\nstruct S3;\n\nimpl !Sync for S2{}\nimpl !Send for S3{}\n\nfn main() {\n    let s2: S2;\n\n    std::thread::scope(|s| {\n        s.spawn(|| {\n            // OK: S1 is Send and may be safely sent between threads\n            return S1;\n        });\n        s.spawn(|| {\n            // OK: S2 is Send and may be safely sent between threads\n            return S2;\n        });\n        s.spawn(|| {\n            // ERROR: S2 is not Sync, therfore \u0026S2 CAN'T be safely sent between threads\n            return \u0026s2;\n        });\n        s.spawn(|| {\n            // ERROR: S3 is not Send, therfore CAN'T be safely sent between threads\n            return S3;\n        });\n    });\n}\n```\n\n## Lifetimes\n\n* Notations\n  * `'b: 'a`: Lifetime `'b` must outlive lifetime `'a` (`'b` is a subtype\n    of `'a`). See _Lifetime bounds_ [[REF]](https://doc.rust-lang.org/reference/trait-bounds.html#lifetime-bounds).\n  * `T: 'a`: Generic type T must outlive lifetime `'a` (all references in T\n    must outlive `'a`). See _Implied bounds_ [[REF]](https://doc.rust-lang.org/reference/trait-bounds.html#implied-bounds).\n\n* _Lifetime elision_ - automatic lifetimes marking. [[REF]](https://doc.rust-lang.org/reference/lifetime-elision.html).\n\n* `struct S` defined as: `struct S\u003c'a, 'b, ...\u003e { ... }` means: lifetimes `'a`,\n  `'b`, ..., associated with `struct S` must outlive `struct S` object lifetime:\n  `S: 'S_obj_lifetime`\n\n  ```rust\n  struct S\u003c'a\u003e(Option\u003c\u0026'a S\u003c'a\u003e\u003e);\n\n  let s1 = S::\u003c'_\u003e(None);\n  {\n      // s2 references to s1 which outlives s2\n      let s2 = S::\u003c'_\u003e(Some(\u0026s1));\n  }\n  ```\n\n* While matching declared lifetimes with the actual object (for `struct`s or\n  function calls) they refer to, a compiler tries to find proper lifetimes\n  fulfilling the declaration, lifetime bounds etc.\n\n  Some [example](src/lifetime.rs) illustrating lifetime bounds for legacy and\n  newer lifetime notation.\n\n  The process of the substitution of actual lifetimes (e.g. in the process of\n  function call) with their identifiers is expressed by _Higher-ranked trait bounds_\n  (_HRTB_) [[NOM]](https://doc.rust-lang.org/nomicon/hrtb.html),\n  [[REF]](https://doc.rust-lang.org/reference/trait-bounds.html#higher-ranked-trait-bounds),\n  where \"for all lifetimes\" term is used to name the substitution.\n\n* _Subtyping and Variance_ [[NOM]](https://doc.rust-lang.org/nomicon/subtyping.html#subtyping), [[REF]](https://doc.rust-lang.org/reference/subtyping.html)\n\n  While passing reference to T in a function: `fn func\u003c'a\u003e(t: \u0026'a mut T)`,\n  passing parameter must not outlive the function argument, which basically means\n  `T`, after the `func()` call, must not contain references with shorter lifetime that\n  object passed to the function to avoid dangling references.\n\n  Good example illustrating the rule has been provided in [[NOM]](https://doc.rust-lang.org/nomicon/subtyping.html#variance).\n\n  ```rust\n  fn assign\u003cT\u003e(input: \u0026mut T, val: T) {\n      *input = val;\n  }\n\n  fn main() {\n      let mut hello: \u0026'static str = \"hello\";\n      {\n          let world = String::from(\"world\");\n          assign(\u0026mut hello, \u0026world);\n      }\n      println!(\"{hello}\"); // use after free!\n  }\n  ```\n\n  Actual parameter to `assign()` has type `\u0026'a mut \u0026'static str`, while the\n  function argument type is `\u0026'a mut \u0026'a str`, where `'a` denotes `world`\n  lifetime. `'static` is a subtype of `'a` (longer lifetime), therefore after\n  returning from `assign()` `str` may be a dangling reference.\n\n  NOTE: The above excerpt would compile fine in case mutability had been removed.\n\n## Conversion diagrams\n\n### `From`, `Into`\n```\n    From\u003cB\u003e\n A ◄─────────────────────── B\n                    Into\u003cA\u003e (*)\n\n\n   (*) Created automatically\n```\n\n### `FromIterator`\n```\n    FromIterator\u003cT\u003e\n A ◄─────────────────────── B\n                            │ IntoIterator\u003cItem=T\u003e\n                            │\n                            │\n                            │\n                            │ Iterator\u003cItem=T\u003e\n                            ▼\n                            I\n```\n\n### `FromStr`\n```\n         FromStr\u003cErr=E\u003e\n      A ◄──────────────────────── str\n(Result\u003cA,E\u003e)\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpstolarz%2Frust-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpstolarz%2Frust-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpstolarz%2Frust-playground/lists"}