use std::sync::{Arc, Mutex};
use tokio::sync::Notify;
struct Allowance {
state: Mutex<(bool, bool)>, //allow,allowance_acquired
notify: Notify,
}
async fn test(allowance: Arc<Allowance>) {
let wait_for_not_allow = {
let mut allowance_guard = allowance.state.lock().unwrap();
if !allowance_guard.0 || allowance_guard.1 {
return;
}
allowance_guard.1 = true;
let mut notified = allowance.notify.notified();
let clear_guard = scopeguard::guard((), |_| {
allowance.state.lock().unwrap().1 = false;
});
// !There is no 'move' here, why doesn't the compiler report an error? After leave block, won't 'clear_guard' and 'notified' go out of scope?
async {
clear_guard;
loop {
notified.await;
notified = allowance.notify.notified();
if !allowance.state.lock().unwrap().0 {
break;
}
}
}
};
wait_for_not_allow.await;
}
#[tokio::main]
async fn main() {
test(Arc::new(Allowance {
state: Mutex::new((true, false)),
notify: Notify::new(),
}))
.await;
}
#Is this a compiler bug or something I didn't understand?
3 messages · Page 1 of 1 (latest)
where were you expecting to get the error exactly?
for the record, the move keyword only tells rust to move a value if it would otherwise have borrowed it. in other words, not including the move keyword does not mean that a value won't be moved.
for example, this is possible:
#[tokio::main]
async fn main() {
let my_str = String::from("hello");
async {
// this will move my_str even though there's no move keyword,
// because drop() takes the argument by value, not reference
drop(my_str);
}.await;
// this would be an error, because my_str has been moved
//println!("{my_str}");
}