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

[PoC] Add @nodiscard attribute #11765

Closed
wants to merge 2 commits into from
Closed

Conversation

pbackus
Copy link
Contributor

@pbackus pbackus commented Sep 19, 2020

Edit: This PR was based on an early draft version of DIP 1038. It has been superseded by #13589. The original PR description follows below.


Fixes issue 5464 - Attribute to not ignore function result


Still need to write up a DIP for this, but I figured I'd post it early to get feedback. The design is the same as Rust's #[must_use]: on a function, it applies to the return value; on a type, it applies to all expressions of that type.

@dlang-bot
Copy link
Contributor

dlang-bot commented Sep 19, 2020

Thanks for your pull request and interest in making D better, @pbackus! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Auto-close Bugzilla Severity Description
5464 enhancement Attribute to not ignore function result

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#11765"

@TurkeyMan
Copy link
Contributor

It seems to me that pure functions should implicitly have this attribute... unless a separate warning to tell you've discarded a pure functions result already exists?

@pbackus
Copy link
Contributor Author

pbackus commented Sep 19, 2020

@TurkeyMan Yes, the compiler already gives a warning (not an error) for discarding the result of a pure function.

@zopsicle
Copy link
Contributor

What is the effect of using this attribute on a constructor? If none, may want to prohibit there.

@pbackus
Copy link
Contributor Author

pbackus commented Sep 19, 2020

@chloekek Good question. It does work on constructors, because they return a reference to the constructed object. That's not really documented in the language spec, though (closest thing is a mention of constructors' return type under "Ref Return Scope Parameters"), so I should probably mention constructors explicitly in the DIP.

Fixes issue 5464 - Attribute to not ignore function result
@pbackus pbackus force-pushed the nodiscard-attribute branch from a943388 to 0101bc9 Compare September 26, 2020 20:13
@thewilsonator thewilsonator added Review:Needs Changelog A changelog entry needs to be added to /changelog Review:Needs Spec PR A PR updating the language specification needs to be submitted to dlang.org labels Sep 27, 2020
Copy link
Contributor

@RazvanN7 RazvanN7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind the comments. Also, this need to be tested more thoroughly:

  • for BinAssignExps
  • for aliases to nodiscard types and functions
  • for overloaded @NODISCARD functions
  • for @NODISCARD member functions
  • for @NODISCARD overriden functions (how do you override a nodiscard function?)
  • @NODISCARD auto functions
  • @NODISCARD templated functions

@@ -1444,6 +1444,8 @@ final class Parser(AST) : Lexer
stc = isBuiltinAtAttribute(token.ident);
if (!stc)
{
if (token.ident == Id.nodiscard)
deprecation("use of `@nodiscard` as a user-defined attribute is deprecated.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DIP should be amended to contain this deprecation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DIP is correct; this PR is based on a previous revision and needs to be updated.

src/dmd/parse.d Show resolved Hide resolved
scope IsAssignment v = new IsAssignment();
e.accept(v);
return v.result;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function would be more efficient if it would simply be replaced by an if statement:

private bool isAssignmentExp(Expression e) @safe pure @nogc nothrow
{
    return e.isAssignExp || e.isBinAssignExp;
}
        

return false;
if (auto ce = e.isCallExp())
{
if (ce.f && (ce.f.storage_class & STC.nodiscard)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curly brace on the next line

{
auto sym = e.type.toDsymbol(null);
auto ad = sym ? sym.isAggregateDeclaration() : null;
if (ad && (ad.storage_class & STC.nodiscard) != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curly brace on the next line

/**
* Check whether the e is a call to a @nodiscard function, or is
* a non-assignment expression with @nodiscard type.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should specify that this function issues an error in the above mentioned cases.

Also, this function is called "isNodiscard", therefore the expectation would be that it simply verifies if an expression contains an @NODISCARD expression. However, this function does more than that: it also errors if the expression is nodiscard. I suggest you rename the function to checkNodiscard. This implies that an error might be issued.

@pbackus pbackus marked this pull request as draft January 8, 2021 15:57
@pbackus
Copy link
Contributor Author

pbackus commented Jan 28, 2022

Since the final accepted version of DIP 1038 has diverged significantly from the draft this PR was based on, I am closing it. DIP 1038 will be implemented in a new PR.

Thank you, @RazvanN7, for your review—I plan to incorporate your feedback into the final implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Review:Needs Changelog A changelog entry needs to be added to /changelog Review:Needs Rebase Review:Needs Spec PR A PR updating the language specification needs to be submitted to dlang.org Review:Pending DIP Approval Review:stalled Severity:Enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants