Skip to content
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

Documet let _ = ... behavior saliently, or even warn about it #40096

Closed
spinda opened this issue Feb 25, 2017 · 11 comments
Closed

Documet let _ = ... behavior saliently, or even warn about it #40096

spinda opened this issue Feb 25, 2017 · 11 comments
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools

Comments

@spinda
Copy link

spinda commented Feb 25, 2017

A friend ran into an issue today with the following code:

let _ = x.lock();

This apparently secures a lock and then immediately drops it, cf. #10488. The following code holds onto the lock instead of dropping it:

let _lock = x.lock();

I found this surprising and was wholly unaware of this special meaning of the _ name, and going by the reactions of @alexcrichton and others in #10488, I'm not the only one. It's not the most Google-able topic, but I wasn't able to find documentation of this except in the issue referenced above. I have to wonder how much Rust code out there has a landmine like this buried somewhere inside, undiscovered. Not the best look for a language aiming at safety and concurrency.

I suggest doing one of the following:

  1. Documenting this special behavior prominently, somewhere that isn't easy for newcomers to miss.
  2. Warn about uses of let _ = foo();. One could argue that all such lines should be replaced by the more clear foo();.
  3. The nuclear option: change the behavior of let _ = ... or remove it from the language entirely. Not likely post-stabilization and given that the previous discussion in Fix semantics of let _ = ... not to drop #10488. However, I worry about Rust going the way of languages like C++ and accumulating a collection of misfeatures and "don't touch this" areas due to legacy reasons.
@sfackler
Copy link
Member

Warn about uses of let _ = foo();. One could argue that all such lines should be replaced by the more clear foo();.

let _ = ... is commonly used to suppress the must_use warning.

@est31
Copy link
Member

est31 commented Feb 25, 2017

I think it should be documented. For me it was kind of obvious as it was consistent with general behavior of _, but if it confused you then there are many people who it confused as well.

@durka
Copy link
Contributor

durka commented Feb 25, 2017

FWIW, it is somewhat documented in the book:

It’s worth noting that using _ never binds the value in the first place, which means that the value does not move:

[...code...]

This also means that any temporary variables will be dropped at the end of the statement:

// Here, the String created will be dropped immediately, as it’s not bound:

let _ = String::from("  hello  ").trim();

@steveklabnik
Copy link
Member

Yes, this is already described in the book, and that section is linked to from the syntax index. Not much more we can do here, I don't think.

@rt-tondilt
Copy link

There are still some things you could do:

  1. Document underscore as a keyword, because it has special semantics. Self and self are already keywords.
  2. Change all sorts of syntax highlighters so they render _ in a different color.

As I understand _ has special semantics everywhere it is used. In patterns it does not bind a variable and in types it is a wildcard.

@steveklabnik
Copy link
Member

_ isn't a keyword, though.

@steveklabnik steveklabnik added A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools and removed A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools labels Mar 10, 2017
@steveklabnik
Copy link
Member

Triage: this is already documented, closing!

@tmccombs
Copy link
Contributor

Is this documented somewhere in version two of the book? I haven't been able to find it, and this caused me some frustration. At least not explicitly, maybe it would be possible to figure this out from "as a wildcard pattern that will match any value but not bind to the value", but it certainly isn't obvious and there isn't anything that calls out this potential footgun.

@steveklabnik
Copy link
Member

https://doc.rust-lang.org/stable/book/ch18-03-pattern-syntax.html?#ignoring-an-unused-variable-by-starting-its-name-with-_

Note that there is a subtle difference between using only _ and using a name that starts with an underscore. The syntax _x still binds the value to the variable, whereas _ doesn’t bind at all. To show a case where this distinction matters, Listing 18-21 will provide us with an error.

@tmccombs
Copy link
Contributor

hmm, that was hard to find, especially since it is under the section about starting a name with _ instead of the section about using just "_". Also it doesn't say anything about the behavior wrt drop.

@ririsoft
Copy link

Hello,

Basic Rust user here. My personal experience is that the issue is still relevant and not fully addressed yet. I came to #40096 and #10488 through my favorite search engine. This helped me much more than the documentation.

I tried very hard to understand what a let _ = x.lock() would do (discard the lock right away or only at the end of the scope) and could not find relevant information or example in the documentation either from the book or the reference.

_ is definitely something special in Rust and used in various places (lifetime, pattern matching, variable binding, type elision) and should deserve a dedicated page somewhere (Book or Reference), that cross-reference documentation when it already exists and add some clarifications such as the current one when necessary.

Any chance we get this issue re-opened pleased ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools
Projects
None yet
Development

No branches or pull requests

8 participants