Fix the issue of duplicate unique ID for atoms using newtype.

The MergeFunctionsPass in LLVM merges identical functions (https://rust.godbolt.org/z/3nnr9nMne), resulting in the same function addresses.
This commit is contained in:
DianQK committed 2023-06-21 21:50:10 +08:00
1 parent 9731640434
commit 535435a4cf
14 files changed
+74 -52

No files matched your search

@@ -95,7 +95,7 @@ Calling `deref` or `deref_mut` is actually more complex than it seems. When a va
Sometimes you want a signal to propagate across your app, either through far-away siblings or through deeply-nested components. In these cases, we use Dirac: Dioxus's first-class state management toolkit. Dirac atoms automatically implement the Signal API. This component will bind the input element to the `TITLE` atom.
```rust
const TITLE: Atom<String> = || "".to_string();
const TITLE: Atom<String> = Atom(|| "".to_string());
const Provider: Component = |cx|{
let title = use_signal(cx, &TITLE);
render!(input { value: title })
@@ -131,7 +131,7 @@ By default, Dioxus is limited when you use iter/map. With the `For` component, y
Dioxus automatically understands how to use your signals when mixed with iterators through `Deref`/`DerefMut`. This lets you efficiently map collections while avoiding the re-rendering of lists. In essence, signals act as a hint to Dioxus on how to avoid un-necessary checks and renders, making your app faster.
```rust
const DICT: AtomFamily<String, String> = |_| {};
const DICT: AtomFamily<String, String> = AtomFamily(|_| {});
const List: Component = |cx|{
let dict = use_signal(cx, &DICT);
cx.render(rsx!(
+4 -4
View File
@@ -146,7 +146,7 @@ async fn editor_service(rx: UnboundedReceiver<EditorCommand>) {
We can combine coroutines with [Fermi](https://docs.rs/fermi/latest/fermi/index.html) to emulate Redux Toolkit's Thunk system with much less headache. This lets us store all of our app's state *within* a task and then simply update the "view" values stored in Atoms. It cannot be understated how powerful this technique is: we get all the perks of native Rust tasks with the optimizations and ergonomics of global state. This means your *actual* state does not need to be tied up in a system like Fermi or Redux – the only Atoms that need to exist are those that are used to drive the display/UI.
```rust
static USERNAME: Atom<String> = |_| "default".to_string();
static USERNAME: Atom<String> = Atom(|_| "default".to_string());
fn app(cx: Scope) -> Element {
let atoms = use_atom_root(cx);
@@ -159,7 +159,7 @@ fn app(cx: Scope) -> Element {
}
fn Banner(cx: Scope) -> Element {
let username = use_read(cx, USERNAME);
let username = use_read(cx, &USERNAME);
cx.render(rsx!{
h1 { "Welcome back, {username}" }
@@ -177,8 +177,8 @@ enum SyncAction {
}
async fn sync_service(mut rx: UnboundedReceiver<SyncAction>, atoms: AtomRoot) {
let username = atoms.write(USERNAME);
let errors = atoms.write(ERRORS);
let username = atoms.write(&USERNAME);
let errors = atoms.write(&ERRORS);
while let Ok(msg) = rx.next().await {
match msg {
@@ -118,14 +118,14 @@ enum InputError {
TooShort,
}
static INPUT_ERROR: Atom<InputError> = |_| InputError::None;
static INPUT_ERROR: Atom<InputError> = Atom(|_| InputError::None);
```
Then, in our top level component, we want to explicitly handle the possible error state for this part of the tree.
```rust
fn TopLevel(cx: Scope) -> Element {
let error = use_read(cx, INPUT_ERROR);
let error = use_read(cx, &INPUT_ERROR);
match error {
TooLong => return cx.render(rsx!{ "FAILED: Too long!" }),
@@ -139,7 +139,7 @@ Now, whenever a downstream component has an error in its actions, it can simply
```rust
fn Commandline(cx: Scope) -> Element {
let set_error = use_set(cx, INPUT_ERROR);
let set_error = use_set(cx, &INPUT_ERROR);
cx.render(rsx!{
input {
+4 -4
View File
@@ -105,7 +105,7 @@ async fn editor_service(rx: UnboundedReceiver<EditorCommand>) {
Podemos combinar corrotinas com `Fermi` para emular o sistema `Thunk` do **Redux Toolkit** com muito menos dor de cabeça. Isso nos permite armazenar todo o estado do nosso aplicativo _dentro_ de uma tarefa e, em seguida, simplesmente atualizar os valores de "visualização" armazenados em `Atoms`. Não pode ser subestimado o quão poderosa é essa técnica: temos todas as vantagens das tarefas nativas do Rust com as otimizações e ergonomia do estado global. Isso significa que seu estado _real_ não precisa estar vinculado a um sistema como `Fermi` ou `Redux` – os únicos `Atoms` que precisam existir são aqueles que são usados para controlar a interface.
```rust
static USERNAME: Atom<String> = |_| "default".to_string();
static USERNAME: Atom<String> = Atom(|_| "default".to_string());
fn app(cx: Scope) -> Element {
let atoms = use_atom_root(cx);
@@ -118,7 +118,7 @@ fn app(cx: Scope) -> Element {
}
fn Banner(cx: Scope) -> Element {
let username = use_read(cx, USERNAME);
let username = use_read(cx, &USERNAME);
cx.render(rsx!{
h1 { "Welcome back, {username}" }
@@ -134,8 +134,8 @@ enum SyncAction {
}
async fn sync_service(mut rx: UnboundedReceiver<SyncAction>, atoms: AtomRoot) {
let username = atoms.write(USERNAME);
let errors = atoms.write(ERRORS);
let username = atoms.write(&USERNAME);
let errors = atoms.write(&ERRORS);
while let Ok(msg) = rx.next().await {
match msg {
@@ -113,14 +113,14 @@ enum InputError {
TooShort,
}
static INPUT_ERROR: Atom<InputError> = |_| InputError::None;
static INPUT_ERROR: Atom<InputError> = Atom(|_| InputError::None);
```
Então, em nosso componente de nível superior, queremos tratar explicitamente o possível estado de erro para esta parte da árvore.
```rust
fn TopLevel(cx: Scope) -> Element {
let error = use_read(cx, INPUT_ERROR);
let error = use_read(cx, &INPUT_ERROR);
match error {
TooLong => return cx.render(rsx!{ "FAILED: Too long!" }),
@@ -134,7 +134,7 @@ Agora, sempre que um componente _downstream_ tiver um erro em suas ações, ele
```rust
fn Commandline(cx: Scope) -> Element {
let set_error = use_set(cx, INPUT_ERROR);
let set_error = use_set(cx, &INPUT_ERROR);
cx.render(rsx!{
input {