Reputation: 108
I have a question about lifetime of varable in Rust programming language.
createTest
function creates and returns r-value reference. and when it returns a reference, testValue
is destroyed. But test.print() doesn't lead to crash. Why?
(Is Test::print function called as static function?)
Code
struct Test;
impl Drop for Test {
fn drop (&mut self) {
println("Dropped.");
}
}
impl Test {
fn print(&self) { println!("Print!"); }
}
fn createTest() -> &Test {
let testValue = &Test;
return testValue;
}
fn main() {
let test = createTest();
test.print();
println("Test");
}
Result
Dropped.
Print!
Test
Upvotes: 2
Views: 1639
Reputation: 102256
The reason the code compiles is because the use of a unit struct (i.e. no fields), is basically equivalent to:
struct Test;
static TestStatic: Test = Test;
fn createTest() -> &Test {
&TestStatic
}
And so the &TestStatic
expression has type &'static Test
. Every lifetime is a sub-lifetime of 'static
, including the implicit anonymous one for the -> &Test
, so you're allowed to return a 'static
in it's place.
This behaviour is covered by two bugs:
That said, it is very strange that Drop
runs like that, so thank you for filing 11681.
Upvotes: 3
Reputation: 128071
This looks like a bug to me. A simple extension of your example does not compile with absolutely natural error message:
struct Test {
x: int
}
impl Drop for Test {
fn drop (&mut self) {
println("Dropped.");
}
}
impl Test {
fn print(&self) { println!("Print: {}", self.x); }
}
fn createTest() -> &Test {
let testValue = &Test{ x: 10 };
testValue
}
fn main() {
let test = createTest();
test.print();
println("Test");
}
Error message:
main.rs:16:19: 16:24 error: borrowed value does not live long enough
main.rs:16 let testValue = &Test{ x: 10 };
^~~~~
main.rs:15:26: 18:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 15:25...
main.rs:15 fn createTest() -> &Test {
main.rs:16 let testValue = &Test{ x: 10 };
main.rs:17 testValue
main.rs:18 }
main.rs:15:26: 18:2 note: ...but borrowed value is only valid for the block at 15:25
main.rs:15 fn createTest() -> &Test {
main.rs:16 let testValue = &Test{ x: 10 };
main.rs:17 testValue
main.rs:18 }
BTW, you don't have to write return
when you want to return something from a function unless it is an early return (e.g. from inside a loop). Just leave out semicolon at the last statement.
Upvotes: 1