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

Updated RFC #886 with lessons learned from #1812 #1940

Merged
merged 21 commits into from
Jul 17, 2017
Merged

Conversation

iopq
Copy link
Contributor

@iopq iopq commented Mar 2, 2017

See #886 and #1812

Rendered

Took out ok() parts

@mark-i-m
Copy link
Member

mark-i-m commented Mar 2, 2017

I like the idea in general.

But i see two other alternatives:

  1. Add must_use for types. That is, when a value of type T is ignored via a semicolon which is marked must_use a lint warning is triggered. This might make sense for types like Result, which may be used to indicate an error.

  2. A stricter rule would be to emit warnings for all ignored values of types other than ! and (). Then, you could opt out of the warning explicitly.

Have these options been considered?

@Nemo157
Copy link
Member

Nemo157 commented Mar 2, 2017

Those are both already implemented, Result (and a few other standard types) are must_use, and there's the unused_results lint (allowed by default) to let you get warnings/errors for ignoring any type (other than (), and I guess ! sorta since you can't actually reach it).

@mark-i-m
Copy link
Member

mark-i-m commented Mar 2, 2017

Ah, so IIUC, the argument of this RFC is that there are types for which must_use is too strong? For example, what prevents us from simply must_useing bool and Option?

In reading the RFC, I didn't understand why existing solutions are insufficient...

@sfackler
Copy link
Member

sfackler commented Mar 2, 2017

There are quite a lot of APIs that return things you don't always care about, e.g. HashMap::insert.

@mark-i-m
Copy link
Member

mark-i-m commented Mar 2, 2017

Ah, ok. That's what I thought, but it's good to be sure 😄

Perhaps the RFC can explain this more explicitly.

@Nemo157
Copy link
Member

Nemo157 commented Mar 2, 2017

One specific example of why making bool as a whole must_use would be really annoying is HashSet::insert; sometimes it's useful to know if you just inserted a new value, other times you just don't care.

A similar example against making Option must_use is Vec::pop; a lot of times when I end up using pop I don't actually want to use the resulting value, I might just be popping off a couple of known values.

What this RFC allows for are cases where a function is returning a more general type like those, but you still want to force the user to do something with the result. The example from #1812 is that by applying must_use to PartialEq::eq then code containing a line like foo == bar; on its own (a noop in any decent implementation of PartialEq) would trigger the must_use lint as it's likely intended to be foo = bar;.

@nrc nrc added the T-lang Relevant to the language team, which will review and decide on the RFC. label Mar 3, 2017
@withoutboats withoutboats self-assigned this Mar 3, 2017
@iopq
Copy link
Contributor Author

iopq commented Mar 7, 2017

https://github.com/zcoinofficial/zcoin/blob/81a667867b5d84893e4c225a8d73eddd78ac16c2/src/main.cpp#L963

zccoinSpend.denomination == libzerocoin::ZQ_LOVELACE;

this typo has enabled an attacker to create 548,000 Zcoins

this should motivate this RFC - right now Rust doesn't warn about this

@mark-i-m
Copy link
Member

mark-i-m commented Mar 7, 2017

Well, actually, the amount of motivation is proportional to the cost of a zcoin 😜

Seriously, though, I does anyone know how common such mistakes actually are in the wild?

I already agree with the RFC, but I am curious.

@iopq
Copy link
Contributor Author

iopq commented Mar 7, 2017

It is estimated that the attacker made ~$750,000 when he sold his Zcoins. Those are some expensive bugs.

@withoutboats
Copy link
Contributor

withoutboats commented Apr 29, 2017

@iopq Rather than trying to wrangle merging two PR branches together, I think I want to propose we just merge this branch as RFC 886.

However, there are a few more amendments I think it needs to get it in line with the current consensus I'm going to list them as concerns and simultaneously propose a merge of this branch.

@withoutboats
Copy link
Contributor

@rfcbot fcp merge

@withoutboats
Copy link
Contributor

withoutboats commented Apr 29, 2017

@rfcbot concern "partial_eq"

The detailed design doesn't mention attaching this attribute to PartialEq::partial_eq, which is something I think we know we want to do.

@withoutboats
Copy link
Contributor

@rfcbot concern "Result::ok"

The drawback and motivation sections still contain a lot of the original commentary about Result::ok. Probably that should be trimmed down, since we aren't considering adding this attribute to Result::ok right now.

@withoutboats
Copy link
Contributor

@rfcbot concern "traits"

One thing this RFC doesn't mention is how this plays out with traits and impls - clearly we want to support applying this attribute to trait declarations, but can you apply it to methods in a trait impl block, so that only that particular impl warns? I don't know what implementation concerns that would raise and I'd like to hear from someone about whether or not it would be hard to allow that.

@rfcbot
Copy link
Collaborator

rfcbot commented Apr 29, 2017

Team member @withoutboats has proposed to merge this. The next step is review by the rest of the tagged teams:

Concerns:

Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@withoutboats
Copy link
Contributor

@rfcbot resolved "Result::ok"

@withoutboats
Copy link
Contributor

@rfcbot resolved "traits"

@liigo
Copy link
Contributor

liigo commented Jun 20, 2017

update rendered @iopq

@rfcbot
Copy link
Collaborator

rfcbot commented Jul 6, 2017

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot rfcbot added the final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. label Jul 6, 2017
@liigo
Copy link
Contributor

liigo commented Jul 11, 2017

Result::{ok, err} are mentioned in Summary, but not in Detailed design section.

@rfcbot
Copy link
Collaborator

rfcbot commented Jul 16, 2017

The final comment period is now complete.

@aturon aturon merged commit a099f17 into rust-lang:master Jul 17, 2017
@aturon
Copy link
Member

aturon commented Jul 17, 2017

Huzzah! This RFC has been merged! Tracking issue.

Thanks, everyone who helped push this idea through!

@olson-dan
Copy link

olson-dan commented Jul 20, 2017

I know the final comment period is complete but #[must_use] is a bad choice as opposed to #[maybe_not_used] because it implies the wrong default behavior.

(Sorry for wading into a pile of well-considered discussion and dropping this, but I feel it's very important for languages that value correctness to have the default behavior of warning on unused return value, which would make things like #[muse_use] unnecessary. Normally I would let it go but I think it's very important for Rust to make good choices going forward instead of drifting into programming language status quo.)

@ssokolow
Copy link

@olson-dan

#[maybe_not_used] is not at all intuitive unless changed to #[warn(maybe_not_used)] because it's a state of being rather than a command.

If it were changed, I'd recommend something like #[warn_if_unused] for that very reason.

@olson-dan
Copy link

@ssokolow

If I read your comment right I think it means I wasn't clear... I'm saying that #[must_use] should be the default behavior and that default behavior should not be opted-into but opted out of.

@ssokolow
Copy link

ssokolow commented Jul 20, 2017

@olson-dan What you're arguing for is implementing full-blown linear typing as a lint and this is the only way that's really a viable option.

See The Pain Of Real Linear Types in Rust for details.

As for phrasing, my point about intuitiveness still stands. #[may_discard] would be a more intuitive name for what you proposed.

@withoutboats
Copy link
Contributor

withoutboats commented Jul 20, 2017

That would be a breaking change anyway & is just not on the table for that reason.

@olson-dan
Copy link

@withoutboats

By breaking you mean it would break 1.0 code? If it was not enabled by default it would not. Although it should definitely be default behavior a warning that can be opted-into globally is preferable to local, opt-ins.

Or more specifically: I can't rely on developers to locally opt-in to behavior that helps them write code correctly, but I can control compiler options across my organization. This is a major frustration in C++ because "Just add [[nodiscard]] to every function" is not an enforceable solution in that language.

Rust is going this route, it seems, and while #[must_use] is a valuable tool in the absence of proper warnings, it's not sufficient for my needs.

@Nemo157
Copy link
Member

Nemo157 commented Jul 20, 2017

@olson-dan see the existing unused-results lint, this is allowed by default but you can enable it for your own codebase. I have attempted to use this in the past and found it to be too strict for real code.

@olson-dan
Copy link

@Nemo157

Thanks, that solves it for me. Sorry to derail the issue.

bors added a commit to rust-lang/rust that referenced this pull request Aug 9, 2017
#[must_use] for functions

This implements [RFC 1940](rust-lang/rfcs#1940).

The RFC and discussion thereof seem to suggest that tagging `PartialEq::eq` and friends as `#[must_use]` would automatically lint for unused comparisons, but it doesn't work out that way (at least the way I've implemented it): unused `.eq` method calls get linted, but not `==` expressions. (The lint operates on the HIR, which sees binary operations as their own thing, even if they ultimately just call `.eq` _&c._.)

What do _you_ think??

Resolves #43302.
@Centril Centril added A-attributes Proposals relating to attributes A-lint Proposals relating to lints / warnings / clippy. labels Nov 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Proposals relating to attributes A-lint Proposals relating to lints / warnings / clippy. final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.