-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
A-attributesArea: Attributes (`#[…]`, `#![…]`)Area: Attributes (`#[…]`, `#![…]`)A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
The following produces no warnings or errors:
#[must_use = "function with no return type"]
fn foo() {}
fn main() {
foo();
}
Is this intended? Shouldn't it produce a lint warning on the attribute? This is a good mentoring issue, I can bang out instructions once I get an answer (fortunately this doesn't seem to involve hygiene this time so hopefully I should get it right... @petrochenkov)
leonardo-m
Metadata
Metadata
Assignees
Labels
A-attributesArea: Attributes (`#[…]`, `#![…]`)Area: Attributes (`#[…]`, `#![…]`)A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
zackmdavis commentedon Oct 5, 2018
The fact that
unused-must-use
doesn't fire on thefoo();
is a consequence of the lint pass returning early for()
and!
.I agree that it's useless to put
#[must_use]
on a function that returns()
, but I don't think anyone thought ahead and decided it should (or shouldn't) be an error. (I wouldn't want to write a dedicated lint for such an edge-case, and I think these days we tend to frown on non-lint warnings on account of their unsilenceability.)#48486 is a similar issue with trait implementations.
zackmdavis commentedon Oct 5, 2018
... well, come to think of it, I see a good case that this should trigger
unused_attributes
, as @petrochenkov recently argued with respect to empty#[derive()]
s.Havvy commentedon Oct 5, 2018
I concur. This should definitely cause
unused_attributes
to fire.Centril commentedon Oct 6, 2018
Should the lint
unused_attributes
also fire for an arbitrary unit type in that case?There should be some consistency in the behavior.
hanna-kruppe commentedon Oct 6, 2018
By "unit type" do you mean
struct Foo;
? I'd say no,must_use
on user-defined types is always potentially sensible, e.g. ZSTs can be used as tokens for something that the caller should not usually forget to do.Centril commentedon Oct 6, 2018
@rkruppe I mean any terminal object in the category of Rust types, so
struct Foo;
,((), ())
,enum Foo { Bar }
, and so on.abonander commentedon Oct 6, 2018
I would say an explicit
()
and any arity of tuple that's all()
.Centril commentedon Oct 6, 2018
@abonander including recursively? e.g
((), ((), ()))
abonander commentedon Oct 7, 2018
Probably, because those types typically don't have any meaning or semantics that can be added to them by the user. I guess it's possible with extension traits but that's going to be a very weird corner case.
Centril commentedon Oct 7, 2018
I'm down with that. It seems to me not too arbitrary a rule.
On the other hand, if we could get
#[must_use]
on all types to emit a warning that could work as well.abonander commentedon Oct 7, 2018
Like @rkruppe said, custom ZSTs can have semantics attached to them so I don't think it's good to warn on
#[must_use]
for those.hanna-kruppe commentedon Oct 7, 2018
I was skeptical about linting even () but forgetting to fill in the return type is at least a plausible scenario where such a lint could help. Going any further does not seem likely to help anyone in any scenario. Types like ((), ()) are rarely even constructed much less written in function signatures.
26 remaining items