Rust temporary variable lifetime in method chaining The 2019 Stack Overflow Developer Survey Results Are InIs there a way to use match() in rust when modifying the selector?Using a static integer in the definition of a structFactory method: instance does not live long enoughWhy are explicit lifetimes needed in Rust?Encapsulating sequentially initialized state with self-references in Rust structRust lifetime for database connection bundleRust function that allocates memory and calls a C++ callback crashesHow does the dropping of temporary values work in rust?Matching against the enclosing function's return typeTemporary Lifetime in Arc in Rust

Should I write numbers in words or as numerals when there are multiple next to each other?

What is the meaning of Triage in Cybersec world?

What are the motivations for publishing new editions of an existing textbook, beyond new discoveries in a field?

Landlord wants to switch my lease to a "Land contract" to "get back at the city"

Does a dangling wire really electrocute me if I'm standing in water?

Does light intensity oscillate really fast since it is a wave?

How was Skylab's orbit inclination chosen?

I see my dog run

Patience, young "Padovan"

Is three citations per paragraph excessive for undergraduate research paper?

Geography at the pixel level

How come people say “Would of”?

Lethal sonic weapons

Falsification in Math vs Science

Is "plugging out" electronic devices an American expression?

Is there a name of the flying bionic bird?

Is it possible for the two major parties in the UK to form a coalition with each other instead of a much smaller party?

What does Linus Torvalds mean when he says that Git "never ever" tracks a file?

Which Sci-Fi work first showed weapon of galactic-scale mass destruction?

Does duplicating a spell with Wish count as casting that spell?

Why could you hear an Amstrad CPC working?

Why is the maximum length of openwrt’s root password 8 characters?

How can I create a character who can assume the widest possible range of creature sizes?

Monty Hall variation



Rust temporary variable lifetime in method chaining



The 2019 Stack Overflow Developer Survey Results Are InIs there a way to use match() in rust when modifying the selector?Using a static integer in the definition of a structFactory method: instance does not live long enoughWhy are explicit lifetimes needed in Rust?Encapsulating sequentially initialized state with self-references in Rust structRust lifetime for database connection bundleRust function that allocates memory and calls a C++ callback crashesHow does the dropping of temporary values work in rust?Matching against the enclosing function's return typeTemporary Lifetime in Arc in Rust



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








3















I'm trying to learn Rust's lifetime rules by comparing it to similar concepts in C++, which I'm more familiar with. Most of the time, my intuition works really well and I can make sense the rule. However, in the following case, I'm not sure if my understanding is correct or not.



In Rust, a temporary value's lifetime is the end of its statement, except when the last temporary value is bound to a name using let.



struct A(u8);
struct B(u8);

impl A
fn get_b(&mut self) -> Option<B>
Some(B(self.0))



fn a(v: u8) -> A
A(v)


// temporary A's lifetime is the end of the statement
// temporary B binds to a name so lives until the enclosing block
let b = a(1).get_b();

// temporary A's lifetime is the end of the statement
// temporary B's lifetime extends to the enclosing block,
// so that taking reference of temporary works similar as above
let b = &a(2).get_b();


If the temporary value is in an if condition, according to the reference, the lifetime is instead limited to the conditional expression.



// Both temporary A and temporary B drops before printing some
if a(3).get_b().unwrap().val <= 3
println!("some");



Now to the question:



If putting let in if condition, because of pattern matching, we are binding to the inner part of the temporary value. I'd expect the temporary value bound by let to be extended to the enclosing block, while other temporary values should still have a lifetime limited by the if condition.



(In this case actually everything is copied I would say even temporary B can be dropped, but that's a separate question.)



However, both temporaries' lifetimes are extended to the enclosing if block.



// Both temporary A and temporary B's lifetime are extended to the end of the enclosing block,
// which is the if statement
if let Some(B(v @ 0...4)) = a(4).get_b()
println!("some ", v);



Should this be considered an inconsistency in Rust? Or am I misunderstanding and there is a consistent rule that can explain this behavior?



Full code example:



  • playground

  • The same thing implemented in C++ that matches my expectation

Note the output from Rust is



some 4
Drop B 4
Drop A 4


while the output from C++ is



Drop A 4 
some 4
Drop B 4


I have read this Reddit thread and Rust issue, which I think is quite relevant, but I still can't find a clear set of lifetime rule that works for all the cases in Rust.



Update:



What I'm unclear about is why the temporary lifetime rule about if conditional expression does not apply to if let. I think the let Some(B(v @ 0...4)) = a(4).get_b() should be the conditional expression, and thus the temporary A's lifetime should be limited by that, rather than the entire if statement.



The behaviour of extending temporary B's lifetime to the entire if statement is expected, because that is borrowed by the pattern matching.










share|improve this question



















  • 2





    you borrow &mut self, so I expect this result, try by consume self => get_b(self)

    – Stargateur
    Mar 22 at 5:11











  • @Stargateur get_b does borrow &mut self, but the return value doesn't contain a lifetime, so it doesn't need to "stay borrowed". I think what's happening here is the compiler considers the entire if let expression "the current statement" (i.e., it doesn't work the same way as let tmp = a(4).get_b(); if let Some(B(_)) = tmp ... which would have the same output as the similar C++ code.)

    – trentcl
    Mar 22 at 12:34












  • @trentcl The issue explain why, github.com/rust-lang/rust/issues/37612#issuecomment-304626464, pattern matching extend the borrow to the scope of the pattern matching. let b = a(4).get_b(); if let Some(B(v@ 0...4)) = b println!("some ", v); should work as expected.

    – Stargateur
    Mar 22 at 12:57






  • 1





    It's not that the borrow is extended, but the lifetime of the temporary is extended even though it isn't borrowed. At least that's my interpretation

    – trentcl
    Mar 22 at 13:20











  • @Stargateur if get_b consumes self, then that's a different situation. Temporary A will be dropped inside get_b body because it is moved there. That's not the same effect as dropping at the end of the statement.

    – Aetf
    Mar 22 at 16:39

















3















I'm trying to learn Rust's lifetime rules by comparing it to similar concepts in C++, which I'm more familiar with. Most of the time, my intuition works really well and I can make sense the rule. However, in the following case, I'm not sure if my understanding is correct or not.



In Rust, a temporary value's lifetime is the end of its statement, except when the last temporary value is bound to a name using let.



struct A(u8);
struct B(u8);

impl A
fn get_b(&mut self) -> Option<B>
Some(B(self.0))



fn a(v: u8) -> A
A(v)


// temporary A's lifetime is the end of the statement
// temporary B binds to a name so lives until the enclosing block
let b = a(1).get_b();

// temporary A's lifetime is the end of the statement
// temporary B's lifetime extends to the enclosing block,
// so that taking reference of temporary works similar as above
let b = &a(2).get_b();


If the temporary value is in an if condition, according to the reference, the lifetime is instead limited to the conditional expression.



// Both temporary A and temporary B drops before printing some
if a(3).get_b().unwrap().val <= 3
println!("some");



Now to the question:



If putting let in if condition, because of pattern matching, we are binding to the inner part of the temporary value. I'd expect the temporary value bound by let to be extended to the enclosing block, while other temporary values should still have a lifetime limited by the if condition.



(In this case actually everything is copied I would say even temporary B can be dropped, but that's a separate question.)



However, both temporaries' lifetimes are extended to the enclosing if block.



// Both temporary A and temporary B's lifetime are extended to the end of the enclosing block,
// which is the if statement
if let Some(B(v @ 0...4)) = a(4).get_b()
println!("some ", v);



Should this be considered an inconsistency in Rust? Or am I misunderstanding and there is a consistent rule that can explain this behavior?



Full code example:



  • playground

  • The same thing implemented in C++ that matches my expectation

Note the output from Rust is



some 4
Drop B 4
Drop A 4


while the output from C++ is



Drop A 4 
some 4
Drop B 4


I have read this Reddit thread and Rust issue, which I think is quite relevant, but I still can't find a clear set of lifetime rule that works for all the cases in Rust.



Update:



What I'm unclear about is why the temporary lifetime rule about if conditional expression does not apply to if let. I think the let Some(B(v @ 0...4)) = a(4).get_b() should be the conditional expression, and thus the temporary A's lifetime should be limited by that, rather than the entire if statement.



The behaviour of extending temporary B's lifetime to the entire if statement is expected, because that is borrowed by the pattern matching.










share|improve this question



















  • 2





    you borrow &mut self, so I expect this result, try by consume self => get_b(self)

    – Stargateur
    Mar 22 at 5:11











  • @Stargateur get_b does borrow &mut self, but the return value doesn't contain a lifetime, so it doesn't need to "stay borrowed". I think what's happening here is the compiler considers the entire if let expression "the current statement" (i.e., it doesn't work the same way as let tmp = a(4).get_b(); if let Some(B(_)) = tmp ... which would have the same output as the similar C++ code.)

    – trentcl
    Mar 22 at 12:34












  • @trentcl The issue explain why, github.com/rust-lang/rust/issues/37612#issuecomment-304626464, pattern matching extend the borrow to the scope of the pattern matching. let b = a(4).get_b(); if let Some(B(v@ 0...4)) = b println!("some ", v); should work as expected.

    – Stargateur
    Mar 22 at 12:57






  • 1





    It's not that the borrow is extended, but the lifetime of the temporary is extended even though it isn't borrowed. At least that's my interpretation

    – trentcl
    Mar 22 at 13:20











  • @Stargateur if get_b consumes self, then that's a different situation. Temporary A will be dropped inside get_b body because it is moved there. That's not the same effect as dropping at the end of the statement.

    – Aetf
    Mar 22 at 16:39













3












3








3


1






I'm trying to learn Rust's lifetime rules by comparing it to similar concepts in C++, which I'm more familiar with. Most of the time, my intuition works really well and I can make sense the rule. However, in the following case, I'm not sure if my understanding is correct or not.



In Rust, a temporary value's lifetime is the end of its statement, except when the last temporary value is bound to a name using let.



struct A(u8);
struct B(u8);

impl A
fn get_b(&mut self) -> Option<B>
Some(B(self.0))



fn a(v: u8) -> A
A(v)


// temporary A's lifetime is the end of the statement
// temporary B binds to a name so lives until the enclosing block
let b = a(1).get_b();

// temporary A's lifetime is the end of the statement
// temporary B's lifetime extends to the enclosing block,
// so that taking reference of temporary works similar as above
let b = &a(2).get_b();


If the temporary value is in an if condition, according to the reference, the lifetime is instead limited to the conditional expression.



// Both temporary A and temporary B drops before printing some
if a(3).get_b().unwrap().val <= 3
println!("some");



Now to the question:



If putting let in if condition, because of pattern matching, we are binding to the inner part of the temporary value. I'd expect the temporary value bound by let to be extended to the enclosing block, while other temporary values should still have a lifetime limited by the if condition.



(In this case actually everything is copied I would say even temporary B can be dropped, but that's a separate question.)



However, both temporaries' lifetimes are extended to the enclosing if block.



// Both temporary A and temporary B's lifetime are extended to the end of the enclosing block,
// which is the if statement
if let Some(B(v @ 0...4)) = a(4).get_b()
println!("some ", v);



Should this be considered an inconsistency in Rust? Or am I misunderstanding and there is a consistent rule that can explain this behavior?



Full code example:



  • playground

  • The same thing implemented in C++ that matches my expectation

Note the output from Rust is



some 4
Drop B 4
Drop A 4


while the output from C++ is



Drop A 4 
some 4
Drop B 4


I have read this Reddit thread and Rust issue, which I think is quite relevant, but I still can't find a clear set of lifetime rule that works for all the cases in Rust.



Update:



What I'm unclear about is why the temporary lifetime rule about if conditional expression does not apply to if let. I think the let Some(B(v @ 0...4)) = a(4).get_b() should be the conditional expression, and thus the temporary A's lifetime should be limited by that, rather than the entire if statement.



The behaviour of extending temporary B's lifetime to the entire if statement is expected, because that is borrowed by the pattern matching.










share|improve this question
















I'm trying to learn Rust's lifetime rules by comparing it to similar concepts in C++, which I'm more familiar with. Most of the time, my intuition works really well and I can make sense the rule. However, in the following case, I'm not sure if my understanding is correct or not.



In Rust, a temporary value's lifetime is the end of its statement, except when the last temporary value is bound to a name using let.



struct A(u8);
struct B(u8);

impl A
fn get_b(&mut self) -> Option<B>
Some(B(self.0))



fn a(v: u8) -> A
A(v)


// temporary A's lifetime is the end of the statement
// temporary B binds to a name so lives until the enclosing block
let b = a(1).get_b();

// temporary A's lifetime is the end of the statement
// temporary B's lifetime extends to the enclosing block,
// so that taking reference of temporary works similar as above
let b = &a(2).get_b();


If the temporary value is in an if condition, according to the reference, the lifetime is instead limited to the conditional expression.



// Both temporary A and temporary B drops before printing some
if a(3).get_b().unwrap().val <= 3
println!("some");



Now to the question:



If putting let in if condition, because of pattern matching, we are binding to the inner part of the temporary value. I'd expect the temporary value bound by let to be extended to the enclosing block, while other temporary values should still have a lifetime limited by the if condition.



(In this case actually everything is copied I would say even temporary B can be dropped, but that's a separate question.)



However, both temporaries' lifetimes are extended to the enclosing if block.



// Both temporary A and temporary B's lifetime are extended to the end of the enclosing block,
// which is the if statement
if let Some(B(v @ 0...4)) = a(4).get_b()
println!("some ", v);



Should this be considered an inconsistency in Rust? Or am I misunderstanding and there is a consistent rule that can explain this behavior?



Full code example:



  • playground

  • The same thing implemented in C++ that matches my expectation

Note the output from Rust is



some 4
Drop B 4
Drop A 4


while the output from C++ is



Drop A 4 
some 4
Drop B 4


I have read this Reddit thread and Rust issue, which I think is quite relevant, but I still can't find a clear set of lifetime rule that works for all the cases in Rust.



Update:



What I'm unclear about is why the temporary lifetime rule about if conditional expression does not apply to if let. I think the let Some(B(v @ 0...4)) = a(4).get_b() should be the conditional expression, and thus the temporary A's lifetime should be limited by that, rather than the entire if statement.



The behaviour of extending temporary B's lifetime to the entire if statement is expected, because that is borrowed by the pattern matching.







rust






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 22 at 17:06







Aetf

















asked Mar 22 at 2:45









AetfAetf

4619




4619







  • 2





    you borrow &mut self, so I expect this result, try by consume self => get_b(self)

    – Stargateur
    Mar 22 at 5:11











  • @Stargateur get_b does borrow &mut self, but the return value doesn't contain a lifetime, so it doesn't need to "stay borrowed". I think what's happening here is the compiler considers the entire if let expression "the current statement" (i.e., it doesn't work the same way as let tmp = a(4).get_b(); if let Some(B(_)) = tmp ... which would have the same output as the similar C++ code.)

    – trentcl
    Mar 22 at 12:34












  • @trentcl The issue explain why, github.com/rust-lang/rust/issues/37612#issuecomment-304626464, pattern matching extend the borrow to the scope of the pattern matching. let b = a(4).get_b(); if let Some(B(v@ 0...4)) = b println!("some ", v); should work as expected.

    – Stargateur
    Mar 22 at 12:57






  • 1





    It's not that the borrow is extended, but the lifetime of the temporary is extended even though it isn't borrowed. At least that's my interpretation

    – trentcl
    Mar 22 at 13:20











  • @Stargateur if get_b consumes self, then that's a different situation. Temporary A will be dropped inside get_b body because it is moved there. That's not the same effect as dropping at the end of the statement.

    – Aetf
    Mar 22 at 16:39












  • 2





    you borrow &mut self, so I expect this result, try by consume self => get_b(self)

    – Stargateur
    Mar 22 at 5:11











  • @Stargateur get_b does borrow &mut self, but the return value doesn't contain a lifetime, so it doesn't need to "stay borrowed". I think what's happening here is the compiler considers the entire if let expression "the current statement" (i.e., it doesn't work the same way as let tmp = a(4).get_b(); if let Some(B(_)) = tmp ... which would have the same output as the similar C++ code.)

    – trentcl
    Mar 22 at 12:34












  • @trentcl The issue explain why, github.com/rust-lang/rust/issues/37612#issuecomment-304626464, pattern matching extend the borrow to the scope of the pattern matching. let b = a(4).get_b(); if let Some(B(v@ 0...4)) = b println!("some ", v); should work as expected.

    – Stargateur
    Mar 22 at 12:57






  • 1





    It's not that the borrow is extended, but the lifetime of the temporary is extended even though it isn't borrowed. At least that's my interpretation

    – trentcl
    Mar 22 at 13:20











  • @Stargateur if get_b consumes self, then that's a different situation. Temporary A will be dropped inside get_b body because it is moved there. That's not the same effect as dropping at the end of the statement.

    – Aetf
    Mar 22 at 16:39







2




2





you borrow &mut self, so I expect this result, try by consume self => get_b(self)

– Stargateur
Mar 22 at 5:11





you borrow &mut self, so I expect this result, try by consume self => get_b(self)

– Stargateur
Mar 22 at 5:11













@Stargateur get_b does borrow &mut self, but the return value doesn't contain a lifetime, so it doesn't need to "stay borrowed". I think what's happening here is the compiler considers the entire if let expression "the current statement" (i.e., it doesn't work the same way as let tmp = a(4).get_b(); if let Some(B(_)) = tmp ... which would have the same output as the similar C++ code.)

– trentcl
Mar 22 at 12:34






@Stargateur get_b does borrow &mut self, but the return value doesn't contain a lifetime, so it doesn't need to "stay borrowed". I think what's happening here is the compiler considers the entire if let expression "the current statement" (i.e., it doesn't work the same way as let tmp = a(4).get_b(); if let Some(B(_)) = tmp ... which would have the same output as the similar C++ code.)

– trentcl
Mar 22 at 12:34














@trentcl The issue explain why, github.com/rust-lang/rust/issues/37612#issuecomment-304626464, pattern matching extend the borrow to the scope of the pattern matching. let b = a(4).get_b(); if let Some(B(v@ 0...4)) = b println!("some ", v); should work as expected.

– Stargateur
Mar 22 at 12:57





@trentcl The issue explain why, github.com/rust-lang/rust/issues/37612#issuecomment-304626464, pattern matching extend the borrow to the scope of the pattern matching. let b = a(4).get_b(); if let Some(B(v@ 0...4)) = b println!("some ", v); should work as expected.

– Stargateur
Mar 22 at 12:57




1




1





It's not that the borrow is extended, but the lifetime of the temporary is extended even though it isn't borrowed. At least that's my interpretation

– trentcl
Mar 22 at 13:20





It's not that the borrow is extended, but the lifetime of the temporary is extended even though it isn't borrowed. At least that's my interpretation

– trentcl
Mar 22 at 13:20













@Stargateur if get_b consumes self, then that's a different situation. Temporary A will be dropped inside get_b body because it is moved there. That's not the same effect as dropping at the end of the statement.

– Aetf
Mar 22 at 16:39





@Stargateur if get_b consumes self, then that's a different situation. Temporary A will be dropped inside get_b body because it is moved there. That's not the same effect as dropping at the end of the statement.

– Aetf
Mar 22 at 16:39












1 Answer
1






active

oldest

votes


















4














An if let construct is just syntactic sugar for a match construct. let Some(B(v @ 0...4)) = a(4).get_b() is not a conditional used in a regular if expression, because it is not an expression that evaluates to bool. Given your example:



if let Some(B(v @ 0...4)) = a(4).get_b() 
println!("some ", v);



It will behave exactly the same as this example. No exceptions. if let is rewritten into match before the type or borrow checkers are even run.



match a(4).get_b() 
Some(B(v @ 0...4)) =>
println!("some ", v);

_ =>



Temporaries live as long as they do in match blocks because they sometimes come in handy. Like if your last function was fn get_b(&mut self) -> Option<&B>, and if the temporary didn't live for the entire match block, then it wouldn't pass borrowck.



If conditionals don't follow the same rule because it's impossible for the last function call in an if conditional to hold a reference to anything. They have to evaluate to a plain bool.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55292164%2frust-temporary-variable-lifetime-in-method-chaining%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4














    An if let construct is just syntactic sugar for a match construct. let Some(B(v @ 0...4)) = a(4).get_b() is not a conditional used in a regular if expression, because it is not an expression that evaluates to bool. Given your example:



    if let Some(B(v @ 0...4)) = a(4).get_b() 
    println!("some ", v);



    It will behave exactly the same as this example. No exceptions. if let is rewritten into match before the type or borrow checkers are even run.



    match a(4).get_b() 
    Some(B(v @ 0...4)) =>
    println!("some ", v);

    _ =>



    Temporaries live as long as they do in match blocks because they sometimes come in handy. Like if your last function was fn get_b(&mut self) -> Option<&B>, and if the temporary didn't live for the entire match block, then it wouldn't pass borrowck.



    If conditionals don't follow the same rule because it's impossible for the last function call in an if conditional to hold a reference to anything. They have to evaluate to a plain bool.






    share|improve this answer



























      4














      An if let construct is just syntactic sugar for a match construct. let Some(B(v @ 0...4)) = a(4).get_b() is not a conditional used in a regular if expression, because it is not an expression that evaluates to bool. Given your example:



      if let Some(B(v @ 0...4)) = a(4).get_b() 
      println!("some ", v);



      It will behave exactly the same as this example. No exceptions. if let is rewritten into match before the type or borrow checkers are even run.



      match a(4).get_b() 
      Some(B(v @ 0...4)) =>
      println!("some ", v);

      _ =>



      Temporaries live as long as they do in match blocks because they sometimes come in handy. Like if your last function was fn get_b(&mut self) -> Option<&B>, and if the temporary didn't live for the entire match block, then it wouldn't pass borrowck.



      If conditionals don't follow the same rule because it's impossible for the last function call in an if conditional to hold a reference to anything. They have to evaluate to a plain bool.






      share|improve this answer

























        4












        4








        4







        An if let construct is just syntactic sugar for a match construct. let Some(B(v @ 0...4)) = a(4).get_b() is not a conditional used in a regular if expression, because it is not an expression that evaluates to bool. Given your example:



        if let Some(B(v @ 0...4)) = a(4).get_b() 
        println!("some ", v);



        It will behave exactly the same as this example. No exceptions. if let is rewritten into match before the type or borrow checkers are even run.



        match a(4).get_b() 
        Some(B(v @ 0...4)) =>
        println!("some ", v);

        _ =>



        Temporaries live as long as they do in match blocks because they sometimes come in handy. Like if your last function was fn get_b(&mut self) -> Option<&B>, and if the temporary didn't live for the entire match block, then it wouldn't pass borrowck.



        If conditionals don't follow the same rule because it's impossible for the last function call in an if conditional to hold a reference to anything. They have to evaluate to a plain bool.






        share|improve this answer













        An if let construct is just syntactic sugar for a match construct. let Some(B(v @ 0...4)) = a(4).get_b() is not a conditional used in a regular if expression, because it is not an expression that evaluates to bool. Given your example:



        if let Some(B(v @ 0...4)) = a(4).get_b() 
        println!("some ", v);



        It will behave exactly the same as this example. No exceptions. if let is rewritten into match before the type or borrow checkers are even run.



        match a(4).get_b() 
        Some(B(v @ 0...4)) =>
        println!("some ", v);

        _ =>



        Temporaries live as long as they do in match blocks because they sometimes come in handy. Like if your last function was fn get_b(&mut self) -> Option<&B>, and if the temporary didn't live for the entire match block, then it wouldn't pass borrowck.



        If conditionals don't follow the same rule because it's impossible for the last function call in an if conditional to hold a reference to anything. They have to evaluate to a plain bool.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 22 at 19:18









        notriddlenotriddle

        45338




        45338





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55292164%2frust-temporary-variable-lifetime-in-method-chaining%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

            용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

            155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해