Skip to content

Make note of interaction between let _ and Drop #26138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

steveklabnik
Copy link
Member

Fixes #25786

@rust-highfive
Copy link
Contributor

r? @brson

(rust_highfive has picked a reviewer for you, use r? to override)

@alexcrichton
Copy link
Member

While true, it seems like this isn't necessarily what #25786 is talking about. I think that it would be more useful from the book perspective to talk about when one would use _ as a binding (e.g. to just ignore something). The semantics of specifically when it drops seems not overly relevant to the book itself.

@steveklabnik
Copy link
Member Author

The semantics of specifically when it drops seems not overly relevant to the book itself.

Well, I mean it is important to understand when things get dropped, which is why I added it here: it's right after it discusses that drops happen in LIFO order ,and this changes things.

@bluss
Copy link
Member

bluss commented Jun 10, 2015

let _ doesn't itself trigger a drop, compare:

let s = "hi".to_string();
let _ = s; // this is a no-op
let t = s;

@eddyb
Copy link
Member

eddyb commented Jun 11, 2015

It's important to note that _ is not a binding, it's a special wildcard pattern that matches anything and does nothing with it.

let _ = <rvalue expr>; is completely and entirely equivalent to <rvalue expr>; for all semantic purposes.
Rvalue scoping is what destroys rvalues being matched on, nothing to do with the patterns.

The only user-visible difference is in the "unused result" lint, which ignores let _ = ...; pretty much on purpose (though the implementation is inverted, i.e. it ignores everything but statement expressions, so match mk_result() { _ => {} } would also be ignored, for example).

It actually so happens that <lvalue expr>; moves the expression, while let _ = <lvalue expr>; doesn't (a fact I was unaware of, I suspect it changed some time ago - I used to jokingly suggest {x}; as a replacement for drop(x);).

Instead of an "exception", couldn't _ get its own special "wildcard patterns" section? Foo(..) and Bar {..} are also wildcard patterns and behave pretty much the same way.
They match anything, but do nothing.

Which leads to the question: does TRPL even properly describe lvalue and rvalue scopes?
let x = &0; let y = &[0][0]; being valid but let z = [0].get(0); erroring with "borrowed value does not live long enough", and all rvalues inside a match discriminator being alive for the whole duration of the match block, that kind of thing.

@steveklabnik
Copy link
Member Author

does TRPL even properly describe lvalue and rvalue scopes?

Yeah, we do not.

I think the pattern / binding distinction is important, it's true. I'm going to close this for now, and try again soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants