Why does the temporary in the last statement is dropped after the local variable?

Right. But you phrased it like this behaviour is, somehow, “strange and wrong”, not just badly documented.

I would have been very surprised about any other behaviour because then simple and obvious refactoring where block is moved into it's own function would, suddenly, change the behaviour. That would be, definitely, unintuitive.

As for documentation: it may be improved, sure, but then topic should be named differently and talk about issues with documentation, not issues with language.

And since you still, even after long discussion, talk about “intuitive” it's clear than your beef is with language, not documentation. Documentation can not be “intuitive”. It may be “complete” or “incomplete”, “correct” or “incorrect”, “clear” or “unclear”. But how would “intuitive” documentation differ from “non-intuitive”? Do we even want “intuitive” documentation or “non-intuitive” one?

No, I did mean the proposed design for changing the temporary lifetime in this document Temporary lifetimes - HackMD, especially super let <pat> = <expr> is non-intuitive.

Oh, indeed. That does seem wrong. That should say "the entire function", without the word "body".

So, you seem to agree this is wrong here in the Rust reference

Yes, it's being fixed.

3 Likes

Moving a block to a separate function does change the drop order. For example:

fn function1() -> i32 {
    let sum = {
        let a = PrintOnDrop("a");
        match PrintOnDrop("b") {
            _ => 6
        }
    } + {
        let a = PrintOnDrop("a");
        match PrintOnDrop("b") {
            _ => 6
        }
    };
    sum
}

fn function2() -> i32 {
    let sum = function3() + function3();
    sum
}

fn function3() -> i32 {
    let a = PrintOnDrop("a");
    match PrintOnDrop("b") {
        _ => 6
    }
}

function1 prints "a a b b" while function2 prints "a b a b".

It seems to me like arguing about these details is not really fruitful. Why are you (OP) so interested about any "formal wording" regarding this behavior? Surely you aren't planning to rely on it? These sort of details, however precisely or formally specified, will probably never be intuitive or obvious, and you should not write code of which the correctness depends on the drop order of temporaries.

2 Likes

Touche. I guess this sample doesn't cause a rejection in my mind because drops happen in the “drop points” which, in function case, can not exist entirely outside of the function, but that's one of cases where “common sense” conflicts with attempts to create simple yet consistent rules.

Because “common sense” tells me that I want to preserve the drop order in that example but it also tells me that function have to drop it's own temporary variables, somehow. There's obvious conflict which resolves “reasonably”.

Sadly this approach wouldn't work for a compiler. It needs precise definitions.

Easier said than done. MutexGuard is temporary quite often and if you use two of them… bam: correctness of your code now depends on that order.

Well he's pointed out two things that were wrong in the reference, there was already a ticket for one and not for the other, and I've created pull requests for both as a result, so I'd say this thread has actually been unusually fruitful.

1 Like

I interpret the statement as agreeing with that, but implying "so don't use temporaries in that case!"

And thus a recommendation to drop(guard1); drop(guard2);, or use let guard: MutexGuard<_>;s at the appropriate scopes to have them dropped based on block rules, or ...

4 Likes

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.