Merge pull request #1332 from Demonthos/fix-variance
Separate Parent and Child Component Lifetimes
This commit is contained in:
5 files changed
+65
-4
No files matched your search
@@ -39,6 +39,7 @@ dioxus = { workspace = true }
|
|||||||
pretty_assertions = "1.3.0"
|
pretty_assertions = "1.3.0"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
dioxus-ssr = { workspace = true }
|
dioxus-ssr = { workspace = true }
|
||||||
|
trybuild = "1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
fn app(cx: Scope) -> Element {
|
||||||
|
let count: &RefCell<Vec<Element>> = cx.use_hook(|| RefCell::new(Vec::new()));
|
||||||
|
|
||||||
|
render! {
|
||||||
|
unsafe_child_component {
|
||||||
|
borrowed: count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Props)]
|
||||||
|
struct Testing<'a> {
|
||||||
|
borrowed: &'a RefCell<Vec<Element<'a>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unsafe_child_component<'a>(cx: Scope<'a, Testing<'a>>) -> Element<'a> {
|
||||||
|
let Testing { borrowed } = cx.props;
|
||||||
|
let borrowed_temporary_data =
|
||||||
|
cx.use_hook(|| String::from("This data is only valid for the lifetime of the child"));
|
||||||
|
|
||||||
|
borrowed
|
||||||
|
.borrow_mut()
|
||||||
|
.push(render! {"{borrowed_temporary_data}"});
|
||||||
|
|
||||||
|
cx.render(rsx! {
|
||||||
|
div { "Hello, world!" }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
error[E0521]: borrowed data escapes outside of function
|
||||||
|
--> compile_tests/props_safety.rs:8:5
|
||||||
|
|
|
||||||
|
5 | fn app(cx: Scope) -> Element {
|
||||||
|
| --
|
||||||
|
| |
|
||||||
|
| `cx` is a reference that is only valid in the function body
|
||||||
|
| has type `&'1 Scoped<'1>`
|
||||||
|
...
|
||||||
|
8 | / render! {
|
||||||
|
9 | | unsafe_child_component {
|
||||||
|
10 | | borrowed: count
|
||||||
|
11 | | }
|
||||||
|
12 | | }
|
||||||
|
| | ^
|
||||||
|
| | |
|
||||||
|
| |_____`cx` escapes the function body here
|
||||||
|
| argument requires that `'1` must outlive `'static`
|
||||||
|
|
|
||||||
|
= note: this error originates in the macro `render` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
@@ -73,3 +73,10 @@ impl EmptyBuilder {
|
|||||||
pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element<'a>) -> T::Builder {
|
pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element<'a>) -> T::Builder {
|
||||||
T::builder()
|
T::builder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(miri))]
|
||||||
|
#[test]
|
||||||
|
fn unsafe_props_fail() {
|
||||||
|
let t = trybuild::TestCases::new();
|
||||||
|
t.compile_fail("compile_tests/props_safety.rs");
|
||||||
|
}
|
||||||
@@ -481,19 +481,20 @@ impl<'src> ScopeState {
|
|||||||
/// fn(Scope<Props>) -> Element;
|
/// fn(Scope<Props>) -> Element;
|
||||||
/// async fn(Scope<Props<'_>>) -> Element;
|
/// async fn(Scope<Props<'_>>) -> Element;
|
||||||
/// ```
|
/// ```
|
||||||
pub fn component<P>(
|
pub fn component<'child, P>(
|
||||||
&'src self,
|
&'src self,
|
||||||
component: fn(Scope<'src, P>) -> Element<'src>,
|
component: fn(Scope<'child, P>) -> Element<'child>,
|
||||||
props: P,
|
props: P,
|
||||||
fn_name: &'static str,
|
fn_name: &'static str,
|
||||||
) -> DynamicNode<'src>
|
) -> DynamicNode<'src>
|
||||||
where
|
where
|
||||||
P: Properties + 'src,
|
P: Properties + 'child,
|
||||||
|
'src: 'child,
|
||||||
{
|
{
|
||||||
let vcomp = VProps::new(component, P::memoize, props);
|
let vcomp = VProps::new(component, P::memoize, props);
|
||||||
|
|
||||||
// cast off the lifetime of the render return
|
// cast off the lifetime of the render return
|
||||||
let as_dyn: Box<dyn AnyProps<'src> + '_> = Box::new(vcomp);
|
let as_dyn: Box<dyn AnyProps<'child> + '_> = Box::new(vcomp);
|
||||||
let extended: Box<dyn AnyProps<'src> + 'src> = unsafe { std::mem::transmute(as_dyn) };
|
let extended: Box<dyn AnyProps<'src> + 'src> = unsafe { std::mem::transmute(as_dyn) };
|
||||||
|
|
||||||
DynamicNode::Component(VComponent {
|
DynamicNode::Component(VComponent {
|
||||||
|
|||||||
Reference in new issue
Block a user