Borrow of moved value: `s`

Why do you get an error compiling this code, if the block is not executed.
b=false or b=true, the compile time error is the same.

fn main() {
      let s = String::from("hello");
      let s2;
      let b = false;
      if b {
        s2 = s;
      }
      println!("{}", s);
}

The compiler doesn't do that level of analysis to see that the branch is never taken -- at least not at this borrow checker phase. Optimization will surely wipe that out, but that's later.

1 Like

If I have similar code in my project development then won't it not compile and pass? How should I handle it?

Rust intentionally doesn't do value-level analysis like this, so that when you're testing stuff you can set things to constants and it's not going to change your initialization and borrow checking errors.

1 Like

I don't understand what it means, can you say it carefully?

Why does this code then execute correctly

fn read(y: bool) {
    if y {
        println!("y is true!{}",y);
    }
}

fn main() {
    let x = false;
    read(x);
}

Is there any information on this

Why shouldn't it?

Because the current code b = false; if statement block is not executed so I do not think the error will be reported, and no matter b = false or b = true the program will report the same error. This is a bit surprising and confusing to me

Sorry, I don't understand at all what you are asking. If you are having trouble expressing yourself reasonably well in English, please seek help with translating your question.


Your latest code snippet doesn't contain any errors – regardless of whether the variable x is true or false, it is a valid program. It either prints something or it doesn't, but it doesn't ever attempt to do anything potentially invalid. There is no reason why any errors should be reported by the compiler for that piece of code.

Sorry I wasn't clear, I was talking about this question I initiated, not the code mentioned in the Q&A

People have already responded to your original question. Rust intentionally doesn't try to guess as many of your runtime values as possible at compile time for the purposes of type checking, because then the following problem could happen:

  • you write a function similar to the above that depends on an argument passed by the user
  • you set your argument to false in a test
  • your code compiles, your test passes, and you happily release your code
  • someone using your code sets the same argument to true
  • now your code won't compile and they will be SadTM, because they thought your code that they are trying to use was working, but it is in fact incorrect.

To avoid such situations, type checking has to require that a piece of code is valid, regardless of the concrete values any variables happen to have during any particular execution.

This is the same reason why Rust generics require explicit trait bounds for all capabilities to be used, unlike C++ templates, for example. It is the same reason why conflicting implementations of 3rd-party traits for 3rd-party types aren't allowed. It's all the same spiel – you want your code to be reliable and not blow up in the user's face, so the compiler has to anticipate all possible circumstances in which it may be used.

I'm sorry, I don't understand what you're trying to say, can you tell me carefully, is there any official information on this?

I'm sorry – I was as careful as I can. If you don't understand this explanation, chances are you wouldn't understand any other "official" explanation, either. At this point, I can't say anything more.

1 Like

Here you never borrowed x. It's moved into the read function

I searched for a while, and sadly no official documemtation that clarifies how move semantics actually works is found. The exactly same question is here:

I always see comments that say move semantics is bitwise copy in essence on machine code. So I won't be surprised when you use a clone of String and it can be optimized away.

1 Like

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.