-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
lint reasons (RFC 2383, part 1) #54683
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
src/librustc/lint/levels.rs
Outdated
ast::MetaItemKind::NameValue(ref name_value) => { | ||
let name_ident = item.ident.segments[0].ident; | ||
let name = name_ident.name.as_str(); | ||
if name == "reason" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, you can just use item.ident == "reason"
.
//~^ ERROR malformed lint attribute | ||
#![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ||
//~^ ERROR malformed lint attribute | ||
#![warn(ellipsis_inclusive_range_patterns, reason)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a couple more cases:
#[warn(lint1, reason = "zzz", reason = "yyy")]
- duplicated reason (probably an error).
#[warn(lint1, reason = "zzz", lint2)]
- reason is not the last (an error? just to be conservative)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reason is not the last (an error? just to be conservative)
Sure. I trust this is compliant with the spirit of the RFC? @Centril @myrrlyn
This is also nice from an implementer's perspective—in the first revision of this PR, I felt bad about doing a entire extra iteration over the meta items just to pick up the reason before entering the loop that processes the lint names themselves, but with this restriction, we can just peek at the end.
src/librustc/lint/levels.rs
Outdated
@@ -245,11 +246,33 @@ impl<'a> LintLevelsBuilder<'a> { | |||
} | |||
} else { | |||
let mut err = bad_attr(name_value.span); | |||
err.help("reason must be a string literal"); | |||
if let ast::LitKind::ByteStr(_) = name_value.node { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No code is good, code is evil.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this case will ever be hit realistically, so I see this as an immediate technical debt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have known sin 😰 💀
Ping from triage @zackmdavis. It looks like some changes have been requested to your PR. Is this PR blocked on #54926? |
@TimNN No, I just suffer from a psychological defect in which composing shiny new PRs is more fun than addressing reviews of outstanding PRs (and the microincentives of which tasks are more fun play a disproportionate role in determining what humans will actually accomplish in general, not just as an open-source volunteer); give me a few more days |
☔ The latest upstream changes (presumably #54969) made this pull request unmergeable. Please resolve the merge conflicts. |
e5ec30d
to
f575218
Compare
(My local build is mysteriously failing right now.) |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
☔ The latest upstream changes (presumably #55015) made this pull request unmergeable. Please resolve the merge conflicts. |
"Mysterious", bah! (This was actually a really idiotic bug where the reslicing that I meant to do when we found the |
f575218
to
0ddf461
Compare
@petrochenkov updated 🏁 |
} else { | ||
reason = Some(rationale); | ||
} | ||
let tail_li = &metas[metas.len()-1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will panic on #[allow()]
, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... right. 😰 😥 💀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this trigger unused_attributes
? (As recently discussed for empty derives and inappropriate #[must_use]
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels reasonable to me to trigger unused_attributes for empty allow; esp. if we do it for empty derives.
#![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] | ||
//~^ ERROR malformed lint attribute | ||
//~| HELP reason in lint attribute must come last | ||
#![warn(missing_copy_implementations, reason)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens with #[allow(reason = "foo")]
?
I.e. no lints to allow, only the reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's make this an error (it would have been a no-op if you hadn't pointed this out).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... well, actually, I guess I could see a case that, if empty lint attributes (#[allow()]
as discussed above) aren't an error (the stable behavior), then we should also allow reason-only lint attributes for consistency/uniformity.
(Presumably the only sane reason for empty lint attributes to exist is for the sake of the base case of some recursive macro, and if we care about that, then we should also care about a macro that's otherwise identical but also includes a reason.)
0ddf461
to
fecc001
Compare
I took a shot at implementing unused-attributes linting for empty and reason-only lint attributes, but I didn't understand some of the behavior I was seeing (the first empty lint attribute in a program was getting linted twice for some reason), so I've elected to defer that, filing an issue (#55112) and leaving FIXME comments. (I could have hacked around the duplication with one-time-diagnostics, but that would be bad; if you want to write correct software and you don't understand something, don't guess.) In this revision, we don't panic on ... I could be persuaded to go with my first instinct and make @petrochenkov what do you think?? |
💔 Test failed - status-appveyor |
Failed a
|
☔ The latest upstream changes (presumably #54658) made this pull request unmergeable. Please resolve the merge conflicts. |
This is just for the `reason =` name-value meta-item; the `#[expect(lint)]` attribute also described in the RFC is a problem for another day. The place where we were directly calling `emit()` on a match block (whose arms returned a mutable reference to a diagnostic-builder) was admittedly cute, but no longer plausibly natural after adding the if-let to the end of the `LintSource::Node` arm. This regards rust-lang#54503.
We take stability seriously, so we shy away from making even seemingly "trivial" features insta-stable.
Vadim Petrochenkov suggested this in review ("an error? just to be conservative"), and it turns out to be convenient from the implementer's perspective: in the initial proposed implementation (or `HEAD~2`, as some might prefer to call it), we were doing an entire whole iteration over the meta items just to find the reason (before iterating over them to set the actual lint levels). This way, we can just peek at the end rather than adding that extra loop (or restructuring the existing code). The RFC doesn't seem to take a position on this, and there's some precedent for restricting things to be at the end of a sequence (we only allow `..` at the end of a struct pattern, even if it would be possible to let it appear anywhere in the sequence).
We avoid an ICE by checking for an empty meta-item list before we index into the meta-items, and leave commentary about where we'd like to issue unused-attributes lints in the future. Note that empty lint attributes are already accepted by the stable compiler; generalizing this to weird reason-only lint attributes seems like the conservative/consilient generalization.
@kennytm I can't reproduce this (Ubuntu 16.04). (At least not consistently—I remember seeing it once while trying to reproduce the other week, while also struggling with a flaky build, but it's passing for me now, as illustrated by output below.) Please advise?
|
fecc001
to
f66ea66
Compare
@zackmdavis maybe try to test on windows? |
... I don't have a Windows machine handy. I would be pretty surprised if there was really a Windows-specific bug to find here (what Windows-specific API could this patch be using??), as opposed to something about the cargo fix test being spuriously nondeterministic (which would be bad, but not something we can fix in this pull request). Is it OK if we try one more time? @bors r=petrochenkov (feel free to r- if you disagree with my judgement) |
📌 Commit f66ea66 has been approved by |
…r=petrochenkov lint reasons (RFC 2883, part 1) This implements the `reason =` functionality described in [the RFC](https://github.com/rust-lang/rfcs/blob/master/text/2383-lint-reasons.md) under a `lint_reasons` feature gate. ![lint_reasons_pt_1](https://user-images.githubusercontent.com/1076988/46252097-eed51000-c418-11e8-8212-939d3f02f95d.png)
lint reasons (RFC 2883, part 1) This implements the `reason =` functionality described in [the RFC](https://github.com/rust-lang/rfcs/blob/master/text/2383-lint-reasons.md) under a `lint_reasons` feature gate. ![lint_reasons_pt_1](https://user-images.githubusercontent.com/1076988/46252097-eed51000-c418-11e8-8212-939d3f02f95d.png)
☀️ Test successful - status-appveyor, status-travis |
Could the RFC number in the ticket title be corrected for ease of searching? Also, is it right that this remains labelled as "S-waiting-on-bors"? |
Edited the title. As for S-waiting-on-bors, it seems bors keeps it on every merged PR. |
This implements the
reason =
functionality described in the RFC under alint_reasons
feature gate.