Skip to content

Drop order twist of && and || chains #103107

Closed
@est31

Description

@est31

If you consider the following program:

struct LoudDrop(&'static str);

impl Drop for LoudDrop {
    fn drop(&mut self) {
        print!("{},", self.0);
    }
}

impl LoudDrop {
    fn foo(&self) -> bool {
        true
    }
}

fn main() {
    if LoudDrop("1").foo() &&
    LoudDrop("2").foo() &&
    LoudDrop("3").foo() &&
    LoudDrop("4").foo() {}
    println!("");

    let _b = LoudDrop("1").foo() &&
    LoudDrop("2").foo() &&
    LoudDrop("3").foo() &&
    LoudDrop("4").foo();
    println!("");

    if !LoudDrop("1").foo() ||
    !LoudDrop("2").foo() ||
    !LoudDrop("3").foo() ||
    !LoudDrop("4").foo() {}
    println!("");

    let _b = !LoudDrop("1").foo() ||
    !LoudDrop("2").foo() ||
    !LoudDrop("3").foo() ||
    !LoudDrop("4").foo();
    println!("");
}

It will print "2,3,4,1," four times. The issue occurs on recent nightly as well as all the way back to 1.0.0. This is a bit weird IMO, and makes && and || chains non-associative. IMO it's a bug that should be fixed to print "1,2,3,4,".

IDK how much we can do about this at the current point, given backwards compatibility concerns. It might not stop programs from compiling, but programs might differ in their runtime output. There is RFC 1857 with the name "Stabilize drop order" but if you read the text, it only concerns the drop order of structs, vecs, tuples, etc. Also, after the merge, the RFC author themself made a PR to add regression tests in #43125 , and mentioned that that PR was enough for getting the RFC tested. The RFC didn't include anything about && chains. I think the language should not be interpreted too generally.

It took a long time until #100526 in which we we got some further drop order tests for "established" language constructs, while there have been many PRs with drop order tests for let-else.

Originally I've discovered this in: #102998 (comment) , but given that it's so visible, I'm sure that someone else has already complained about this.

Maybe one can just implement the change to "1,2,3,4," and make a crater run for it?

cc @Nilstrieb @nathanwhit

@rustbot label T-lang

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions