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

Visit attributes in more places. #96745

Merged
merged 8 commits into from
Aug 15, 2022

Conversation

ehuss
Copy link
Contributor

@ehuss ehuss commented May 5, 2022

This adds 3 loosely related changes (I can split PRs if desired):

  • Attribute checking on pattern struct fields.
  • Attribute checking on struct expression fields.
  • Lint level visiting on pattern struct fields, struct expression fields, and generic parameters.

There are still some lints which ignore lint levels in various positions. This is a consequence of how the lints themselves are implemented. For example, lint levels on associated consts don't work with unused_braces.

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 5, 2022
@rust-highfive
Copy link
Collaborator

r? @jackh726

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 5, 2022
@ehuss
Copy link
Contributor Author

ehuss commented May 5, 2022

I don't really know if the HIR changes make sense, as I don't fully understand it. I'm likely doing things wrong.

  • I'm confused that HirId's seem to be generated for things that aren't nodes. Why does it do that? That seems like it should be invalid to me.
  • It seems awkward to add these HIR nodes. I don't know if it makes sense to make it a Node, but I don't see any other way.
  • Would it make sense to add dedicated visit_field methods to intravisit to visit struct expression and pattern fields, so that it is easier to override? I think that could make it cleaner, but I'm uncertain about the consequences of extending the visitor.
  • The pretty-printer seems to be missing stuff. What is the state of it? Should I add tests for that?

@petrochenkov
Copy link
Contributor

This does not try to resolve #81282.

You say that it does not, but GitHub thinks that it does.

@ehuss
Copy link
Contributor Author

ehuss commented May 5, 2022

You say that it does not, but GitHub thinks that it does.

Oops, tricky keywords. Thanks! I removed that comment.

@bors
Copy link
Contributor

bors commented May 20, 2022

☔ The latest upstream changes (presumably #96833) made this pull request unmergeable. Please resolve the merge conflicts.

@ehuss ehuss force-pushed the even-more-attribute-validation branch from fa6cafa to e088252 Compare May 20, 2022 19:32
Copy link
Contributor

@cjgillot cjgillot left a comment

Choose a reason for hiding this comment

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

I'm confused that HirId's seem to be generated for things that aren't nodes. Why does it do that? That seems like it should be invalid to me.

I agree that HirIds should eventually map 1-to-1 to Nodes. I guess nobody ever cared enough to enforce it.

It seems awkward to add these HIR nodes. I don't know if it makes sense to make it a Node, but I don't see any other way.

From the code, I don't understand why you need them.

Would it make sense to add dedicated visit_field methods to intravisit to visit struct expression and pattern fields, so that it is easier to override? I think that could make it cleaner, but I'm uncertain about the consequences of extending the visitor.

That would actually be better, yes.

The pretty-printer seems to be missing stuff. What is the state of it? Should I add tests for that?

I've been considering dropping the HIR pretty printer entirely. It's only use is for debugging, and I'm not sure it's actually used by anyone.

@@ -193,6 +193,11 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
let node =
if let PatKind::Binding(..) = pat.kind { Node::Binding(pat) } else { Node::Pat(pat) };
self.insert(pat.span, pat.hir_id, node);
if let PatKind::Struct(_, fields, _) = pat.kind {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be inside the call to with_parent.

compiler/rustc_hir/src/hir.rs Show resolved Hide resolved
@@ -224,6 +224,11 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {

fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
if let ExprKind::Struct(_, fields, _) = expr.kind {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be inside with_parent.

@@ -2286,6 +2286,11 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
};

self.check_attributes(expr.hir_id, expr.span, target, None);
if let hir::ExprKind::Struct(_, fields, _) = expr.kind {
for field in fields {
self.check_attributes(field.hir_id, field.span, Target::PatField, None);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do expression fields behave exactly like PatField? Should the PatField's name reflect that?

Copy link
Contributor Author

@ehuss ehuss May 23, 2022

Choose a reason for hiding this comment

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

That was a bad copy/paste. It should have been Target::ExprField.

compiler/rustc_hir/src/hir.rs Show resolved Hide resolved
})
match e.kind {
hir::ExprKind::Struct(qpath, fields, base_expr) => {
self.with_lint_attrs(e.hir_id, |builder| {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we keep this call outside of the match? It's common to both branches.

hir::ExprKind::Struct(qpath, fields, base_expr) => {
self.with_lint_attrs(e.hir_id, |builder| {
builder.visit_qpath(qpath, e.hir_id, e.span);
for field in fields {
Copy link
Contributor

Choose a reason for hiding this comment

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

With all this custom visits, I wonder if we shouldn't add a visit_expr_struct_field to hir::Visitor and use it where appropriate.

match &p.kind {
hir::PatKind::Struct(qpath, fields, _) => {
self.visit_qpath(&qpath, p.hir_id, p.span);
for field in *fields {
Copy link
Contributor

Choose a reason for hiding this comment

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

Likewise with visit_pat_struct_field (or another name).

@@ -751,9 +751,26 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
}

fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the early lint visitor be updated the same way?

@@ -796,6 +813,28 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
intravisit::walk_impl_item(builder, impl_item);
});
}

fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the early lint visitor be updated the same way?

@cjgillot
Copy link
Contributor

Also, do we need some kind of signoff by the lang team before taking into account lint attributes in more places?

@ehuss
Copy link
Contributor Author

ehuss commented May 23, 2022

From the code, I don't understand why you need them.

My understanding is:

  • CheckAttrVisitor is built around using hir().attrs(hir_id) in order to get the set of attributes given a HirId.
  • In order for that HirId → Attributes lookup to work, the HirId needs to be in the owners map.
  • In order for that mapping to get into the owners map, one needs to call NodeCollector.insert, which requires something to be a Node.

This also helps ensure that struct_span_lint_hir is able to look up the correct lint-level at that node.

Also, do we need some kind of signoff by the lang team before taking into account lint attributes in more places?

That's a good question, I don't know. My intuition is that the lint controls should be allowed anywhere one can place an attribute, so I figured this was just an oversight. They could be disallowed in these positions, but I'm not sure the reasoning for restricting it would be.


I added visit_pat_field and visit_expr_field which looks a lot better to me.

@jackh726
Copy link
Member

jackh726 commented Jun 7, 2022

r? @cjgillot

@rust-highfive rust-highfive assigned cjgillot and unassigned jackh726 Jun 7, 2022
@@ -219,6 +225,11 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {

fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
if let ExprKind::Struct(_, fields, _) = expr.kind {
for field in fields {
self.insert(field.span, field.hir_id, Node::ExprField(field));
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this be moved into visit_expr_field?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved. That changed the parent relationship, which I think is correct, but required modifications on various things looking at the parent.

self.with_lint_attrs(param.id, &param.attrs, |cx| {
run_early_pass!(cx, check_generic_param, param);
ast_visit::walk_generic_param(cx, param);
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Should there be similar modifications for expr field and pat fields?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

visit_expr_field was already there (added in #87146). I added visit_pat_field which fixed handling for early lints on pattern fields.

@cjgillot cjgillot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 12, 2022
@bors
Copy link
Contributor

bors commented Jul 2, 2022

☔ The latest upstream changes (presumably #98802) made this pull request unmergeable. Please resolve the merge conflicts.

@ehuss ehuss force-pushed the even-more-attribute-validation branch from 31c8dc8 to 269ed24 Compare July 6, 2022 01:40
@ehuss ehuss added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 28, 2022
@cjgillot
Copy link
Contributor

Thanks @ehuss, this is great.
@bors r+ rollup=iffy

@bors
Copy link
Contributor

bors commented Jul 30, 2022

📌 Commit 269ed24b66b43a117601c6d494d6930ce307182a has been approved by cjgillot

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 30, 2022
@bors
Copy link
Contributor

bors commented Jul 30, 2022

⌛ Testing commit 269ed24b66b43a117601c6d494d6930ce307182a with merge cbae2e3618280f231ef33b34c729fd7a2a234a23...

@bors
Copy link
Contributor

bors commented Jul 30, 2022

💔 Test failed - checks-actions

@bors bors removed the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Jul 30, 2022
Attributes on struct expression fields were not being checked for
validity. This adds the fields as HIR nodes so that `CheckAttrVisitor`
can visit those nodes to check their attributes.
This extends the LintLevelBuilder to handle lint level attributes on
struct expression fields and pattern fields.

This also updates the early lints to honor lint levels on generic
parameters.
This helps simplify the code. It also fixes it to use the correct parent
when lowering. One consequence is the `non_snake_case` lint needed
to change the way it looked for parent nodes in a struct pattern.

This also includes a small fix to use the correct `Target` for
expression field attribute validation.
This was incorrectly inserting the ExprField as a sibling of the struct
expression.

This required adjusting various parts which were looking at parent node
of a field expression to find the struct.
This ensures that lint attributes on pattern fields can control
early lints.
Now that fields are first-class HIR nodes, they appear before the struct pat.
@ehuss ehuss force-pushed the even-more-attribute-validation branch from 3fac153 to 900a9d3 Compare August 12, 2022 04:56
@ehuss
Copy link
Contributor Author

ehuss commented Aug 12, 2022

Would it be OK to move forward with this? I think the clippy changes aren't substantially different from where they were before. I was just wondering if there was a simpler way to go from a ExprField to its Ty, but it doesn't look like there is.

@cjgillot
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Aug 12, 2022

📌 Commit 900a9d3 has been approved by cjgillot

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 12, 2022
@bors
Copy link
Contributor

bors commented Aug 14, 2022

⌛ Testing commit 900a9d3 with merge 50c8baf6e5d96319ba99ab4e334e3be204e8eba2...

@bors
Copy link
Contributor

bors commented Aug 14, 2022

💥 Test timed out

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 14, 2022
@ehuss
Copy link
Contributor Author

ehuss commented Aug 14, 2022

@bors retry

4hour timeout on x86_64-mingw-1

These tests hung:
2022-08-14T18:12:50.9442844Z test fs::tests::read_large_dir has been running for over 60 seconds
2022-08-14T18:12:51.0011567Z test io::stdio::tests::panic_doesnt_poison has been running for over 60 seconds
2022-08-14T18:12:51.0020489Z test io::stdio::tests::test_lock_stderr has been running for over 60 seconds

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 14, 2022
@rust-log-analyzer
Copy link
Collaborator

A job failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@bors
Copy link
Contributor

bors commented Aug 15, 2022

⌛ Testing commit 900a9d3 with merge 6ce7609...

@bors
Copy link
Contributor

bors commented Aug 15, 2022

☀️ Test successful - checks-actions
Approved by: cjgillot
Pushing 6ce7609 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Aug 15, 2022
@bors bors merged commit 6ce7609 into rust-lang:master Aug 15, 2022
@rustbot rustbot added this to the 1.65.0 milestone Aug 15, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (6ce7609): comparison url.

Instruction count

  • Primary benchmarks: ❌ relevant regression found
  • Secondary benchmarks: no relevant changes found
mean1 max count2
Regressions ❌
(primary)
0.8% 0.8% 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.8% 0.8% 1

Max RSS (memory usage)

Results
  • Primary benchmarks: ❌ relevant regression found
  • Secondary benchmarks: no relevant changes found
mean1 max count2
Regressions ❌
(primary)
2.8% 2.8% 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 2.8% 2.8% 1

Cycles

Results
  • Primary benchmarks: no relevant changes found
  • Secondary benchmarks: mixed results
mean1 max count2
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
6.4% 6.4% 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.7% -2.7% 1
All ❌✅ (primary) - - 0

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

Footnotes

  1. the arithmetic mean of the percent change 2 3

  2. number of relevant changes 2 3

Jarcho pushed a commit to Jarcho/rust that referenced this pull request Aug 29, 2022
… r=cjgillot

Visit attributes in more places.

This adds 3 loosely related changes (I can split PRs if desired):

- Attribute checking on pattern struct fields.
- Attribute checking on struct expression fields.
- Lint level visiting on pattern struct fields, struct expression fields, and generic parameters.

There are still some lints which ignore lint levels in various positions. This is a consequence of how the lints themselves are implemented. For example, lint levels on associated consts don't work with `unused_braces`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants