-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Certain Polonius loops do not work with polonius_loop!
#11
Comments
Hey @JohnScience, thanks for the question: you are right there is a rough edge in the crate's API, insofar it may lure you into using
First attempt: use ::polonius_the_crab::prelude::*;
fn response<'a, Response>(
mut responses_list: &'a mut Vec<Vec<Response>>,
// ^^^
// `mut` on the binding is indeed needed by the macro
// (you could always manually do a `let mut responses_list = responses_list;`
// before calling the macro)
) -> Option<&'a mut Response>
{
loop {
polonius!(|responses_list| -> Option<&'polonius mut Response> {
if let Some(response) = responses_list.last_mut()?.last_mut() {
polonius_return!(Some(response));
}
});
let _ = responses_list.pop();
}
} fails because of the Second attempt: use ::polonius_the_crab::prelude::*;
fn response<'a, Response>(
mut responses_list: &'a mut Vec<Vec<Response>>,
) -> Option<&'a mut Response>
{
loop {
polonius!(|responses_list| -> Option<&'polonius mut Response> {
match responses_list.last_mut().map(|it| it.last_mut()) {
// 1st last_mut failed:
None => polonius_return!(None),
// 2nd last_mut failed:
Some(None) => {}, // <- we cannot access `responses_list` yet (still inside the macro)
// both succeeded:
Some(Some(response)) => polonius_return!(Some(response)),
}
}); // <- at the end of the macro we get access to `responses_list` back 🙂
let _ = responses_list.pop();
}
} works! 🥳 |
Basically FWIW, you could also try you luck without the use ::polonius::{polonius, ForLt, PoloniusResult, Placeholder};
fn response<'a, Response>(
mut responses: &'a mut Vec<Vec<Response>>,
) -> Option<&'a mut Response>
{
loop {
let it = polonius::<_, _, ForLt!(/* type here what goes in the Borrowing variant */)>(|responses| {
// answer:
// Option<&mut Response>
// TODO: return `PoloniusResult::Borrowing(None)` here
// v
if let Some(response) = responses.last_mut()?.last_mut() {
PoloniusResult::Borrowing(Some(response))
} else {
PoloniusResult::Owned {
value: (), // <- we have nothing interesting to pass, here
input_borrow: Placeholder, // <- the `polonius()` function will put
// the `responses` input back here
}
}
});
match it {
PoloniusResult::Borrowing(item) => return item,
PoloniusResult::Owned {
value: (), // <- still as uninteresting as we left it
input_borrow, // <- we get back our input `responses` here!
} => {
responses = input_borrow;
},
};
let _ = responses.pop();
}
} |
polonius_the_crab::polonius_loop
polonius_loop!
First of all, hi Yandros!
Getting back the the problem, ...
Code:
I try to rewrite it to make it more amicable to the
polonius_loop!
macro but it has the problem thatresponses_list
has to be mutable.Latest attempt
Deeper look
I also tried to uncover what's the problem myself by looking at the expansion, ...
Before the cleanup:
After the cleanup:
But so far it was fruitless.
Code that (almost) worked
Pie rewrote my code this way but it's actually not equivalent.
This code misses
let _ = responses_list.pop();
part, which is quite important for the algorithm.The text was updated successfully, but these errors were encountered: