-
Notifications
You must be signed in to change notification settings - Fork 13.3k
impl Generator
complains about missing named lifetime if yielded expression contains a borrow
#44197
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
Comments
cc @Zoxc |
This may or may not be the same as #44200 |
Like #44200 this is due to how interior types are being calculated. |
Just to be clear, you're only talking about the situation due to the bug with generators, right? Because in regular Rust the borrow of |
@Arnavion It's not really a bug (just undesirable semantics), and you typically don't notice these rules unless the types involved have destructors (which references do not) and isn't immediately moved. |
Okay, regardless of what we call it, it's something that happens only with generators and not with regular Rust code, so it would be nice to fix it. |
This code produces the same error: fn multiply<G>(g: G, x: i32) -> impl Generator<Return = (), Yield = i32>
where
G: Generator<Return = (), Yield = i32>,
{
|| while let GeneratorState::Yielded(v) = g.resume() {
yield v * x;
}
} Is there some workaround? |
fn multiply<G>(mut g: G, x: i32) -> impl Generator<Return = (), Yield = i32>
where
G: Generator<Return = (), Yield = i32>
{
move || loop {
let state = g.resume();
if let GeneratorState::Yielded(v) = state {
yield v * x;
}
else {
return;
}
}
} If you still want to keep the move || while let GeneratorState::Yielded(v) = { let state = g.resume(); state } {
yield v * x;
} |
That's not actually correct. |
If you'll use expr_use_visitor, you should be able to identify all lexpr spots by looking for when the |
…ws across suspension points to borrowck. Fixes rust-lang#44197, rust-lang#45259 and rust-lang#45093.
Immovable generators This adds support for immovable generators which allow you to borrow local values inside generator across suspension points. These are declared using a `static` keyword: ```rust let mut generator = static || { let local = &Vec::new(); yield; local.push(0i8); }; generator.resume(); // ERROR moving the generator after it has resumed would invalidate the interior reference // drop(generator); ``` Region inference is no longer affected by the types stored in generators so the regions inside should be similar to other code (and unaffected by the presence of `yield` expressions). The borrow checker is extended to pick up the slack so interior references still result in errors for movable generators. This fixes #44197, #45259 and #45093. This PR depends on [PR #44917 (immovable types)](#44917), I suggest potential reviewers ignore the first commit as it adds immovable types.
... even though the value of the expression does not borrow from anything.
Case 1:
This gives:
Workaround:
Case 2:
This gives
Workaround:
I assume the borrows in the expressions are the problem because in both cases, adding a
+ 'static
bound to theimpl Generator
returns the error thatbaz
does not live long enough, even though it does not need to be borrowed past the call tofoo(&baz)
.The text was updated successfully, but these errors were encountered: