-
Notifications
You must be signed in to change notification settings - Fork 90
Closed as not planned
Description
struct V(u32);
#[derive(Builder)]
#[builder(pattern = "owned")]
struct Foo {
a: V,
#[builder(default = "self.calc_b()")]
b: V,
}
impl FooBuilder {
fn calc_b(&self) -> V {
V(self.a.as_ref().unwrap().0 + 5)
}
}
This fails to compile with
borrow of partially moved value: `self`
--> src/lib.rs:9:25
|
3 | #[derive(Builder)]
| ------- value partially moved here
...
7 | #[builder(default = "self.calc_b()")]
| ^^^^^^^^^^^^^^^ value borrowed here after partial move
Looking at cargo expand it's easy to see why:
fn build(
self,
) -> ::derive_builder::export::core::result::Result<Foo, FooBuilderError> {
Ok(Foo {
a: match self.a {
// partial move here
Some(value) => value,
None => {
return ::derive_builder::export::core::result::Result::Err(
::derive_builder::export::core::convert::Into::into(
::derive_builder::UninitializedFieldError::from("a"),
),
);
}
},
b: match self.b {
Some(value) => value,
// borrow after partial move here
None => self.calc_b(),
},
})
}
A possible fix would be to calculate custom default values before the match expression.
A small issue with that is, that the default value will be calculated even if not needed, but I don't think that is a big problem here and can be ignored, except for maybe mentioning it in the documentation.
I'd be willing to create a PR for this if this solution is acceptable.
Metadata
Metadata
Assignees
Labels
No labels