// #![allow(unused, non_upper_case_globals)] // use bumpalo::Bump; // use dioxus_core::nodebuilder::*; // use dioxus_core::prelude::VNode; // use dioxus_core::prelude::*; // use once_cell::sync::{Lazy, OnceCell}; use std::ops::Deref; /* A guard over underlying T that provides access in callbacks via "Copy" */ // #[derive(Clone)] struct ContextGuard2 { _val: std::marker::PhantomData, } impl Clone for ContextGuard2 { // we aren't cloning the underlying data so clone isn't necessary fn clone(&self) -> Self { todo!() } } impl Copy for ContextGuard2 {} impl ContextGuard2 { fn get<'a>(&'a self) -> ContextLock<'a, T> { todo!() } } struct ContextLock<'a, T> { _val: std::marker::PhantomData<&'a T>, } impl<'a, T: 'a + 'static> Deref for ContextLock<'a, T> { type Target = T; fn deref<'b>(&'b self) -> &'b T { todo!() } } /* The source of the data that gives out context guards */ struct Context<'a> { _p: std::marker::PhantomData<&'a ()>, } impl<'a> Context<'a> { fn use_context<'b, I, O: 'b>(&self, _f: fn(&'b I) -> O) -> ContextGuard2 { todo!() } fn add_listener(&self, _f: impl Fn(()) + 'a) { todo!() } fn render(self, _f: impl FnOnce(&'a String) + 'a) {} // fn view(self, f: impl for<'b> FnOnce(&'a String) + 'a) {} // fn view(self, f: impl for<'b> FnOnce(&'b String) + 'a) {} } struct Example { value: String, } /* Example compiling */ fn t<'a>(ctx: Context<'a>) { let value = ctx.use_context(|b: &Example| &b.value); // Works properly, value is moved by copy into the closure let refed = value.get(); println!("Value is {}", refed.as_str()); let r2 = refed.as_str(); ctx.add_listener(move |_| { // let val = value.get().as_str(); let _val2 = r2.as_bytes(); println!("v2 is {}", r2); // println!("refed is {}", refed); }); // let refed = value.deref(); // returns &String // returns &String // let refed = value.deref(); // returns &String // let refed = value.deref(); // returns &String // Why does this work? This closure should be static but is holding a reference to refed // The context guard is meant to prevent any references moving into the closure // if the references move they might become invalid due to mutlithreading issues ctx.add_listener(move |_| { // let val = value.as_str(); // let val2 = refed.as_bytes(); }); ctx.render(move |_b| {}); } fn main() {}