-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsD-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.Diagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Code
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)
}
}
Current output
error[E0382]: borrow of partially moved value: `self`
--> src/main.rs:9:25
|
5 | #[derive(Builder)]
| ------- value partially moved here
...
9 | #[builder(default = "self.calc_b()")]
| ^^^^^^^^^^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because value has type `V`, which does not implement the `Copy` trait
help: borrow this binding in the pattern to avoid moving the value
|
5 | #[derive(ref Builder)]
| +++
Desired output
error[E0382]: borrow of partially moved value: `self`
--> src/main.rs:9:25
|
5 | #[derive(Builder)]
| ------- value partially moved here
...
9 | #[builder(default = "self.calc_b()")]
| ^^^^^^^^^^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because value has type `V`, which does not implement the `Copy` trait
Rationale and extra context
I encountered the error while using the rust-dervie-builder crate. The above code is invalid as explained in this issue here: colin-kiegel/rust-derive-builder#298
Basically the expansion of this derive macro leads to self
being referenced after a partial move.
The first part of the error message is correct. The suggested fix however is just wrong.
For context, the expansion of the relevant code is the following
struct FooBuilder {
a: ::derive_builder::export::core::option::Option<V>,
b: ::derive_builder::export::core::option::Option<V>,
}
impl FooBuilder {
fn build(
self,
) -> ::derive_builder::export::core::result::Result<Foo, FooBuilderError> {
Ok(Foo {
a: match self.a {
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,
None => self.calc_b(),
},
})
}
}
Other cases
No response
Rust Version
rustc 1.77.0 (aedd173a2 2024-03-17)
binary: rustc
commit-hash: aedd173a2c086e558c2b66d3743b344f977621a7
commit-date: 2024-03-17
host: x86_64-unknown-linux-gnu
release: 1.77.0
LLVM version: 17.0.6
Anything else?
No response
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsD-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.Diagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.