Parcourir la source

fix borrowed props with temp values

Evan Almloff il y a 1 an
Parent
commit
d559fdaeab

+ 24 - 0
packages/core/compile_tests/props_safety_temporary_values.rs

@@ -0,0 +1,24 @@
+use dioxus::prelude::*;
+
+fn main() {}
+
+fn app(cx: Scope) -> Element {
+    let count = vec![1, 2, 3];
+
+    render! {
+        unsafe_child_component {
+            borrowed: &count
+        }
+    }
+}
+
+#[derive(Props)]
+struct Testing<'a> {
+    borrowed: &'a Vec<u32>,
+}
+
+fn unsafe_child_component<'a>(cx: Scope<'a, Testing<'a>>) -> Element<'a> {
+    cx.render(rsx! {
+        div { "{cx.props.borrowed:?}" }
+    })
+}

+ 12 - 0
packages/core/compile_tests/props_safety_temporary_values.stderr

@@ -0,0 +1,12 @@
+error[E0515]: cannot return value referencing local variable `count`
+  --> compile_tests/props_safety_temporary_values.rs:8:5
+   |
+8  | /     render! {
+9  | |         unsafe_child_component {
+10 | |             borrowed: &count
+   | |                       ------ `count` is borrowed here
+11 | |         }
+12 | |     }
+   | |_____^ returns a value referencing data owned by the current function
+   |
+   = note: this error originates in the macro `render` (in Nightly builds, run with -Z macro-backtrace for more info)

+ 1 - 0
packages/core/src/properties.rs

@@ -79,4 +79,5 @@ pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element<'a>)
 fn unsafe_props_fail() {
 fn unsafe_props_fail() {
     let t = trybuild::TestCases::new();
     let t = trybuild::TestCases::new();
     t.compile_fail("compile_tests/props_safety.rs");
     t.compile_fail("compile_tests/props_safety.rs");
+    t.compile_fail("compile_tests/props_safety_temporary_values.rs");
 }
 }

+ 3 - 1
packages/core/src/scopes.rs

@@ -424,7 +424,9 @@ impl<'src> ScopeState {
         fn_name: &'static str,
         fn_name: &'static str,
     ) -> DynamicNode<'src>
     ) -> DynamicNode<'src>
     where
     where
-        P: Properties + 'child,
+        // The properties must be valid until the next bump frame
+        P: Properties + 'src,
+        // The current bump allocator frame must outlive the child's borrowed props
         'src: 'child,
         'src: 'child,
     {
     {
         let vcomp = VProps::new(component, P::memoize, props);
         let vcomp = VProps::new(component, P::memoize, props);