From f91eeccca784ea2c64c751148d052f513b2c77d2 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 9 Aug 2023 10:49:47 -0700 Subject: [PATCH] add compile test for unsound case --- packages/core/Cargo.toml | 1 + packages/core/compile_tests/props_safety.rs | 32 +++++++++++++++++++ .../core/compile_tests/props_safety.stderr | 20 ++++++++++++ packages/core/src/properties.rs | 6 ++++ 4 files changed, 59 insertions(+) create mode 100644 packages/core/compile_tests/props_safety.rs create mode 100644 packages/core/compile_tests/props_safety.stderr diff --git a/packages/core/Cargo.toml b/packages/core/Cargo.toml index 7c9515fc0..71afe5825 100644 --- a/packages/core/Cargo.toml +++ b/packages/core/Cargo.toml @@ -39,6 +39,7 @@ dioxus = { workspace = true } pretty_assertions = "1.3.0" rand = "0.8.5" dioxus-ssr = { workspace = true } +trybuild = "1.0" [features] default = [] diff --git a/packages/core/compile_tests/props_safety.rs b/packages/core/compile_tests/props_safety.rs new file mode 100644 index 000000000..a9729cec9 --- /dev/null +++ b/packages/core/compile_tests/props_safety.rs @@ -0,0 +1,32 @@ +use dioxus::prelude::*; + +fn main() {} + +fn app(cx: Scope) -> Element { + let count: &RefCell> = cx.use_hook(|| RefCell::new(Vec::new())); + + render! { + unsafe_child_component { + borrowed: count + } + } +} + +#[derive(Props)] +struct Testing<'a> { + borrowed: &'a RefCell>>, +} + +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!" } + }) +} diff --git a/packages/core/compile_tests/props_safety.stderr b/packages/core/compile_tests/props_safety.stderr new file mode 100644 index 000000000..565d7b6cc --- /dev/null +++ b/packages/core/compile_tests/props_safety.stderr @@ -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) diff --git a/packages/core/src/properties.rs b/packages/core/src/properties.rs index 834b0cabd..05f5cbea9 100644 --- a/packages/core/src/properties.rs +++ b/packages/core/src/properties.rs @@ -73,3 +73,9 @@ impl EmptyBuilder { pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element<'a>) -> T::Builder { T::builder() } + +#[test] +fn unsafe_props_fail() { + let t = trybuild::TestCases::new(); + t.compile_fail("compile_tests/props_safety.rs"); +}