I'm attempting to write some code for an ARM Cortex-M microcontroller and I'm running into an issue with the borrow checker. It is a perfectly valid error, but I want to know how I can avoid it.
My program is using the memory address of variables as a unique identifier of sorts. I know this is incredibly ugly, but it is a very lightweight way to get a unique identifier. This pattern is only valid if I make these variables static so their unique id (i.e. address) lives "forever" which means I have several functions which require a reference with a 'static
lifetime.
I'm using a library by japaric (cortex-m) which provides a method which places the processor in a certain state that allows a function to run in an interrupt-free critical section. This is accomplished by a function which wraps the call to the function that needs to be executed in a critical section with the appropriate assembly calls.
In this contrived example, the wrapper function is called run_in_special_state
. I need to execute the foo
method in the special state. However, it requires a 'static Contrived
. Here's a playground that will illustrate the error:
fn foo(_: &'static Contrived) {
}
fn run_in_special_state<F, R>(f: F) -> R
where
F: FnOnce() -> R,
{
// Some stuff happens before the function
let r = f();
// Some stuff happens after the function
r
}
struct Contrived {
value: u32
}
impl Contrived {
fn func (&'static mut self) {
run_in_special_state(|| {
foo(self)
});
self.value = 6;
}
}
static mut INSTANCE: Contrived = Contrived { value: 4 };
fn main() {
unsafe { INSTANCE.func() };
}
Here's what you'll get when you run that in the playground:
Compiling playground v0.0.1 (file:///playground)
error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function
--> src/main.rs:21:30
|
21 | run_in_special_state(|| {
| ^^ may outlive borrowed value `self`
22 | foo(self)
| ---- `self` is borrowed here
help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword
|
21 | run_in_special_state(move || {
| ^^^^^^^
error: aborting due to previous error
Here's my question: I know that the FnOnce
is going to be called before run_in_special_state
exits. I believe this also means that the closure will not outlive the current function (func
?), since it (the closure) will be executed and discarded before the current function (func
) exits. How can I communicate this to the borrow checker? Or is something else going on here? I've noticed that if I drop the 'static
requirement on foo
that the error disappears.
I also can't do the suggested fix, since I need to use self
after run_in_special_state
is called.