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:
14 files changed
+74
-52
No files matched your search
@@ -1,21 +1,21 @@
|
||||
use crate::{AtomId, AtomRoot, Readable, Writable};
|
||||
|
||||
pub type Atom<T> = fn(AtomBuilder) -> T;
|
||||
pub struct Atom<T>(pub fn(AtomBuilder) -> T);
|
||||
pub struct AtomBuilder;
|
||||
|
||||
impl<V> Readable<V> for Atom<V> {
|
||||
impl<V> Readable<V> for &'static Atom<V> {
|
||||
fn read(&self, _root: AtomRoot) -> Option<V> {
|
||||
todo!()
|
||||
}
|
||||
fn init(&self) -> V {
|
||||
(*self)(AtomBuilder)
|
||||
self.0(AtomBuilder)
|
||||
}
|
||||
fn unique_id(&self) -> AtomId {
|
||||
*self as *const ()
|
||||
*self as *const Atom<V> as *const ()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Writable<V> for Atom<V> {
|
||||
impl<V> Writable<V> for &'static Atom<V> {
|
||||
fn write(&self, _root: AtomRoot, _value: V) {
|
||||
todo!()
|
||||
}
|
||||
@@ -23,6 +23,22 @@ impl<V> Writable<V> for Atom<V> {
|
||||
|
||||
#[test]
|
||||
fn atom_compiles() {
|
||||
static TEST_ATOM: Atom<&str> = |_| "hello";
|
||||
dbg!(TEST_ATOM.init());
|
||||
static TEST_ATOM: Atom<&str> = Atom(|_| "hello");
|
||||
dbg!((&TEST_ATOM).init());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn atom_is_unique() {
|
||||
static TEST_ATOM_1: Atom<&str> = Atom(|_| "hello");
|
||||
static TEST_ATOM_2: Atom<&str> = Atom(|_| "hello");
|
||||
assert_eq!((&TEST_ATOM_1).unique_id(), (&TEST_ATOM_1).unique_id());
|
||||
assert_ne!((&TEST_ATOM_1).unique_id(), (&TEST_ATOM_2).unique_id());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn atom_is_unique_2() {
|
||||
struct S(String);
|
||||
static TEST_ATOM_1: Atom<Vec<S>> = Atom(|_| Vec::new());
|
||||
static TEST_ATOM_2: Atom<Vec<String>> = Atom(|_| Vec::new());
|
||||
assert_ne!((&TEST_ATOM_1).unique_id(), (&TEST_ATOM_2).unique_id());
|
||||
}
|
||||
@@ -2,23 +2,23 @@ use crate::{AtomId, AtomRoot, Readable, Writable};
|
||||
use im_rc::HashMap as ImMap;
|
||||
|
||||
pub struct AtomFamilyBuilder;
|
||||
pub type AtomFamily<K, V> = fn(AtomFamilyBuilder) -> ImMap<K, V>;
|
||||
pub struct AtomFamily<K, V>(pub fn(AtomFamilyBuilder) -> ImMap<K, V>);
|
||||
|
||||
impl<K, V> Readable<ImMap<K, V>> for AtomFamily<K, V> {
|
||||
impl<K, V> Readable<ImMap<K, V>> for &'static AtomFamily<K, V> {
|
||||
fn read(&self, _root: AtomRoot) -> Option<ImMap<K, V>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn init(&self) -> ImMap<K, V> {
|
||||
(*self)(AtomFamilyBuilder)
|
||||
self.0(AtomFamilyBuilder)
|
||||
}
|
||||
|
||||
fn unique_id(&self) -> AtomId {
|
||||
*self as *const ()
|
||||
*self as *const AtomFamily<K, V> as *const ()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Writable<ImMap<K, V>> for AtomFamily<K, V> {
|
||||
impl<K, V> Writable<ImMap<K, V>> for &'static AtomFamily<K, V> {
|
||||
fn write(&self, _root: AtomRoot, _value: ImMap<K, V>) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -2,24 +2,24 @@ use crate::{AtomId, AtomRoot, Readable};
|
||||
use std::cell::RefCell;
|
||||
|
||||
pub struct AtomRefBuilder;
|
||||
pub type AtomRef<T> = fn(AtomRefBuilder) -> T;
|
||||
pub struct AtomRef<T>(pub fn(AtomRefBuilder) -> T);
|
||||
|
||||
impl<V> Readable<RefCell<V>> for AtomRef<V> {
|
||||
impl<V> Readable<RefCell<V>> for &'static AtomRef<V> {
|
||||
fn read(&self, _root: AtomRoot) -> Option<RefCell<V>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn init(&self) -> RefCell<V> {
|
||||
RefCell::new((*self)(AtomRefBuilder))
|
||||
RefCell::new(self.0(AtomRefBuilder))
|
||||
}
|
||||
|
||||
fn unique_id(&self) -> AtomId {
|
||||
*self as *const ()
|
||||
*self as *const AtomRef<V> as *const ()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn atom_compiles() {
|
||||
static TEST_ATOM: AtomRef<Vec<String>> = |_| vec![];
|
||||
dbg!(TEST_ATOM.init());
|
||||
static TEST_ATOM: AtomRef<Vec<String>> = AtomRef(|_| vec![]);
|
||||
dbg!((&TEST_ATOM).init());
|
||||
}
|
||||
@@ -13,7 +13,10 @@ use std::{
|
||||
///
|
||||
///
|
||||
///
|
||||
pub fn use_atom_ref<T: 'static>(cx: &ScopeState, atom: AtomRef<T>) -> &UseAtomRef<T> {
|
||||
pub fn use_atom_ref<'a, T: 'static>(
|
||||
cx: &'a ScopeState,
|
||||
atom: &'static AtomRef<T>,
|
||||
) -> &'a UseAtomRef<T> {
|
||||
let root = use_atom_root(cx);
|
||||
|
||||
&cx.use_hook(|| {
|
||||
|
||||
@@ -19,7 +19,7 @@ use std::{
|
||||
/// static COUNT: Atom<u32> = |_| 0;
|
||||
///
|
||||
/// fn Example(cx: Scope) -> Element {
|
||||
/// let mut count = use_atom_state(cx, COUNT);
|
||||
/// let mut count = use_atom_state(cx, &COUNT);
|
||||
///
|
||||
/// cx.render(rsx! {
|
||||
/// div {
|
||||
|
||||
Reference in new issue
Block a user