Where can I find the technique document about "borrow of partially moved value"?

struct A(String);
fn main(){
    let mut a = A(String::from("abc"));
    let s = a.0;
    let b = &a;
}

The compiler renders an error:

error[E0382]: borrow of partially moved value: a

I tried to find the relevant technique reference at 2094-nll - The Rust RFC Book to interpret how the borrowing checker works on this case, however, the RFC seems to do not cover this case. Which RFC covers this part?

I don't think there's an RFC for this. RFCs did not exist from the beginning of the language, so they only cover major additions/changes to the language made after the RFC process was introduced.

The closest I could find to an explicit explanation in the docs was this section in Rust by Example on partial moves.

I'm not sure what you are looking for. This has nothing to do with NLL – the code you posted cannot compile under any implementation of the borrow checker.

A reference to a value points to the entire value. If the value is a struct, it includes all of its fields. So if a field of a struct has been invalidated by having been moved from, you can't get a reference to the entire struct anymore, because references must always point to valid, fully initialized values.

3 Likes

Here you go

The fields of a struct or a reference to a struct are treated as separate entities when borrowing. If the struct does not implement Drop and is stored in a local variable, this also applies to moving out of each of its fields.

a place expression... If the type of that value implements Copy, then the value will be copied. In the remaining situations, if that type is Sized, then it may be possible to move the value. Only the following place expressions may be moved out of:

  • ...
  • Fields of a place expression which can be moved out of and don't implement Drop.

Your wrapper type A doesn't implement Drop and the value a can be moved out of, so a.0 can be moved.

To see a case that breaks the rule and understand why don't-implement-Drop on the wrapper type matters: Rust Playground

3 Likes

The whole linked references do not interpret why a struct cannot be borrowed once its fields are moved out of it.

It's right here:

The raw address-of operators must be used instead of a borrow operator whenever the place expression could evaluate to a place that is not properly aligned or does not store a valid value as determined by its type, or whenever creating a reference would introduce incorrect aliasing assumptions. In those situations, using a borrow operator would cause undefined behavior by creating an invalid reference

3 Likes

Just under the second quote I pasted. If you really click the second item link [1] , you'll see it.

After moving out of a place expression that evaluates to a local variable, the location is deinitialized and cannot be read from again until it is reinitialized. In all other cases, trying to use a place expression in a value expression context is an error.

It's a bit annoying that one wants to know something from the documentation but doesn't read it through.


  1. or third link if you call it; the first item containing two links directs to the same webpage ↩ī¸Ž

5 Likes

I think the case is simple, just gets bogged down in detail.
You can't create references to uninitialised values. (The error message not stating this.)
Quick search has me at example in destructors

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.