Open nox opened 5 years ago
This, I believe, is the case that we cut out from NLL (what I called "Problem case #3" in my initial blog post) -- specifically, the dreaded "conditionally return borrow". The pattern you have there is:
data_struct
, which borrows input
)data_structu.fields.iter_mut()
)In that case, with NLL as currently implemented, the borrow (from point A) is extended until the end of the function. This means the borrow is considered ins cope from point A until the end of the function, which in this case includes input.span()
.
TL;DR: Polonius is supposed to fix this.
The workaround btw is something like this (playground):
use syn::spanned::Spanned;
use syn::{Data, DeriveInput, Error, Field, Fields};
// Uncommenting the two lines below trigger a borrowck error.
pub fn struct_fields_mut(
input: &mut DeriveInput,
) -> Result<impl Iterator<Item = &mut Field>, Error> {
if let Data::Struct(ref data_struct) = input.data {
if let Fields::Named(_) = data_struct.fields {
// Repeat the borrow here, where it can never
// reach the latter use
if let Data::Struct(ref mut data_struct) = input.data {
return Ok(data_struct.fields.iter_mut());
} else {
panic!()
}
}
}
Err(Error::new(
input.span(),
"only structs can be automatically neutralized",
))
}
fn main() { }
This looks like a duplicate of #21906. If not, it's a duplicate of #51545.
Playground