Where is it documented in rust reference that function return values are moved, not dropped?
โ Rust ๐ 2025-12-13 ๐ค surdeus ๐๏ธ 2Hello! I'm learning Rust and trying to understand the precise rules around moves and drops. I've written this example to explore the behavior:
struct MyInt(i8);
impl Drop for MyInt {
fn drop(&mut self) {
println!("Drop called for MyInt: {}", self.0);
}
}
fn main() {
let mut a = MyInt(10);
a = smth();
println!("Print from main 1");
MyInt(40);
println!("Print from main 2");
}
fn smth() -> MyInt {
let b = MyInt(20);
let c = MyInt(30);
println!("Print from smth");
b
}
I got the following output:
$ cargo run
Compiling loops v0.1.0 (/home/filip/rustprojects/loops)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.13s
Running `target/debug/loops`
Print from smth
Drop called for MyInt: 30
Drop called for MyInt: 10
Print from main 1
Drop called for MyInt: 40
Print from main 2
Drop called for MyInt: 20
Looking at it logically, output is clear to me. However, I can't find where in the rust reference this behavior is explained. Specifically, where it is explained that by returning b from the function, the value is "moved out" (and not dropped)? Reference states that the "move out" is only performed in the following cases:
When a place expression is evaluated in a value expression context, or is bound by value in a pattern, it denotes the value held in that memory location.
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:
- Variables which are not currently borrowed.
- Temporary values.
- Fields of a place expression which can be moved out of and donโt implement
Drop.- The result of dereferencing an expression with type
Box<T>and that can also be moved out of.
Since smth() is not a place expression, but value expression, "move out of" should not be performed. I also thought that smth() might be classified as a "temporary value":
When using a value expression in most place expression contexts, a temporary unnamed memory location is created and initialized to that value.
But, smth() within a = smth() can't accommodate in anything listed for "place expression context":
The following contexts are place expression contexts:
- The left operand of a compound assignment expression.
- The operand of a unary borrow, raw borrow or dereference operator.
- The operand of a field expression.
- The indexed operand of an array indexing expression.
- The operand of any implicit borrow.
- The initializer of a let statement.
- The scrutinee of an
if let,match, orwhile letexpression.- The base of a functional update struct expression.
Since I'm new to Rust, I'm likely missing something. Any help is greatly appreciated!
14 posts - 5 participants
๐ท๏ธ Rust_feed