Skip to content

Parameter patterns are dropped *after* arguments #36088

Description

@arielb1

Meta

$ rustc -V
rustc 1.13.0-dev (528c6f3ed 2016-08-25)

STR

struct NoisyDrop(&'static str);
impl Drop for NoisyDrop {
    fn drop(&mut self) {
        println!("dropping {}", self.0);
    }
}

fn argument_buf((_,v,_): (NoisyDrop, NoisyDrop, NoisyDrop)) {
    println!("in argument_buf");
}
fn main() {
    argument_buf((NoisyDrop("x"), NoisyDrop("y"), NoisyDrop("z")));
}

Actual Result

in argument_buf
dropping x
dropping z
dropping y

Explanation

When the function exits, the argument arg0 is dropped first, followed by the variable var0 aka y. This is the reverse of what happened in old trans, and looks quite unnatural. OTOH, it is quite similar to let-bindings, so maybe that is for the best.

Relation to match statements

I don't think that lifetimes in match patterns are a good example for anything (see #46525), but a match statement drops the discriminant last:

    match (NoisyDrop("x"), NoisyDrop("y"), NoisyDrop("z")) {
        (_, v, _) => println!("in match")
    }

prints

in match
dropping y
dropping x
dropping z

Activity

  1. added
    A-destructorsArea: Destructors (`Drop`, …)
    T-langRelevant to the language team
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Aug 28, 2016
  2. Stebalien commented on Aug 29, 2016

    @Stebalien
    Contributor

    Really, I'd expect x and z to be dropped at the start of the function (same as let bindings).

  3. Centril commented on Feb 18, 2019

    @Centril
    Contributor

    @arielb1 What's the status of this?

  4. jonas-schievink commented on Feb 18, 2019

    @jonas-schievink
    Contributor

    This does look somewhat expected to me - _ never binds anything, so the value is dropped as soon as the pattern is matched. v keeps the only bound value alive until the function exits, so dropping y is printed later.

  5. arielb1 commented on Feb 25, 2019

    @arielb1
    ContributorAuthor

    @Centril

    This still exists. With NLL it can't cause any soundness problems, but it just feels weird to me. Whatever we choose, this needs to be documented in the reference near the temporary lifetimes documentation.

    @jonas-schievink

    Not quite. The drop of both the arguments and the patterns happens at the function end, not at function start (see my edited post).

  6. Centril commented on Feb 25, 2019

    @Centril
    Contributor

    This still exists. With NLL it can't cause any soundness problems, but it just feels weird to me. Whatever we choose, this needs to be documented in the reference near the temporary lifetimes documentation.

    iirc @matthewjasper has a PR to document this, rust-lang/reference#514 (I need to get back to it soon).

    Also, to fix a regression, we recently changed the drop semantics so that the drop order is y x z rather than x y z. This is seen in https://play.rust-lang.org/?version=beta&mode=debug&edition=2018&gist=9d2cd068bf948d37a988f70f7d1bce59. Is that what you expect?

  7. arielb1 commented on Feb 28, 2019

    @arielb1
    ContributorAuthor

    Sure enough, this was fixed in #56044, with a test. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-destructorsArea: Destructors (`Drop`, …)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions