Skip to content

Commit 14ff329

Browse files
committed
Fix unsoundess in ChangeTracker
Make sure to annotate the function with `'static` or it is possible that the handler runs closure that reference dead objects
1 parent b432ea4 commit 14ff329

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

internal/core/properties/change_tracker.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ impl ChangeTracker {
5454
/// The `data` is any struct that is going to be passed to the functor.
5555
/// The `eval_fn` is a function that queries and return the property.
5656
/// And the `notify_fn` is the callback run if the property is changed
57-
pub fn init<Data, T: Default + PartialEq, EF: Fn(&Data) -> T, NF: Fn(&Data, &T)>(
57+
pub fn init<
58+
Data: 'static,
59+
T: Default + PartialEq,
60+
EF: Fn(&Data) -> T + 'static,
61+
NF: Fn(&Data, &T) + 'static,
62+
>(
5863
&self,
5964
data: Data,
6065
eval_fn: EF,
@@ -68,7 +73,12 @@ impl ChangeTracker {
6873
/// Same as [`Self::init`], but the first eval function is called in a future evaluation of the event loop.
6974
/// This means that the change tracker will consider the value as default initialized, and the eval function will
7075
/// be called the firs ttime if the initial value is not equal to the default constructed value.
71-
pub fn init_delayed<Data, T: Default + PartialEq, EF: Fn(&Data) -> T, NF: Fn(&Data, &T)>(
76+
pub fn init_delayed<
77+
Data: 'static,
78+
T: Default + PartialEq,
79+
EF: Fn(&Data) -> T + 'static,
80+
NF: Fn(&Data, &T) + 'static,
81+
>(
7282
&self,
7383
data: Data,
7484
eval_fn: EF,
@@ -77,7 +87,12 @@ impl ChangeTracker {
7787
self.init_impl(data, eval_fn, notify_fn, true);
7888
}
7989

80-
fn init_impl<Data, T: Default + PartialEq, EF: Fn(&Data) -> T, NF: Fn(&Data, &T)>(
90+
fn init_impl<
91+
Data: 'static,
92+
T: Default + PartialEq,
93+
EF: Fn(&Data) -> T + 'static,
94+
NF: Fn(&Data, &T) + 'static,
95+
>(
8196
&self,
8297
data: Data,
8398
eval_fn: EF,
@@ -93,7 +108,12 @@ impl ChangeTracker {
93108
evaluating: false.into(),
94109
};
95110

96-
unsafe fn evaluate<T: PartialEq, EF: Fn(&Data) -> T, NF: Fn(&Data, &T), Data>(
111+
unsafe fn evaluate<
112+
T: PartialEq,
113+
EF: Fn(&Data) -> T + 'static,
114+
NF: Fn(&Data, &T) + 'static,
115+
Data: 'static,
116+
>(
97117
_self: *const BindingHolder,
98118
_value: *mut (),
99119
) -> BindingResult {
@@ -135,8 +155,12 @@ impl ChangeTracker {
135155
trait HasBindingVTable {
136156
const VT: &'static BindingVTable;
137157
}
138-
impl<T: PartialEq, EF: Fn(&Data) -> T, NF: Fn(&Data, &T), Data> HasBindingVTable
139-
for ChangeTrackerInner<T, EF, NF, Data>
158+
impl<
159+
T: PartialEq,
160+
EF: Fn(&Data) -> T + 'static,
161+
NF: Fn(&Data, &T) + 'static,
162+
Data: 'static,
163+
> HasBindingVTable for ChangeTrackerInner<T, EF, NF, Data>
140164
{
141165
const VT: &'static BindingVTable = &BindingVTable {
142166
drop: drop::<T, EF, NF, Data>,

0 commit comments

Comments
 (0)