-
Notifications
You must be signed in to change notification settings - Fork 13.3k
document and justify temporary lifetime rules in the documentation #12032
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
1.0 blocker, P-low. |
Nominating for removal from milestone. We'll live if this isn't documented. |
Removing from 1.0 milestone. |
Traige: I'm not sure what these are exactly, maybe we can have a chat about them, @nikomatsakis ? |
@steveklabnik I would say
My go-to example of a gotcha here: Consider the following hypothetical desugaring of macro_rules! for_bad {
(($pat:pat) in $head:expr { $($body:stmt)* }) => { {
let mut iter = IntoIterator::into_iter($head);
loop {
match Iterator::next(&mut iter) {
Some($pat) => { $($body)* }
None => break,
}
}
} }
} The above is remarkably easy to read, at least for someone versed in Unfortunately, it does not work, and (according to my understanding), it is due to the R-value lifetime rules for temporaries. In particular, consider: let mut iter = IntoIterator::into_iter($head); only live to the end of that statement, not beyond. Thus the So, what's the go-to fix for this? Its this: Bind via Here's that desugaring: macro_rules! for_gud {
(($pat:pat) in $head:expr { $($body:stmt)* }) => { {
match IntoIterator::into_iter($head) {
mut iter => loop {
match Iterator::next(&mut iter) {
Some($pat) => { $($body)* }
None => break,
}
}
}
} }
} And here's a playpen link to save you the trouble of transcribing the above into code if you want to play with it: http://is.gd/NmptIx |
Any update? I wrote down some rules here: https://internals.rust-lang.org/t/borrow-scopes/1732 |
@pnkfelix Wouldn't it work to just bind $head with a let? macro_rules! for_ok {
(($pat:pat) in $head:expr { $($body:stmt)* }) => { {
let head = $head;
let mut iter = IntoIterator::into_iter(head);
loop {
match Iterator::next(&mut iter) {
Some($pat) => { $($body)* }
None => break,
}
}
} }
} |
After doing #26833 , @nikomatsakis and I decided to not actually go through this right now. At some point, we'll be developing a more formal model for Rust, and this information will belong there, but as it is, it feels weird in the reference. |
… r=jonas-schievink feat: display signature help when applying "Add `::<>`" assist Closes rust-lang/rust-analyzer#12031
The new syntax-based rules for temporary lifetimes that landed with #3511 have not yet been thoroughly documented outside the source. This should be fixed!
The text was updated successfully, but these errors were encountered: