-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Conversation
r? @jackh726 (rust-highfive has picked a reviewer for you, use r? to override) |
I don't really know if the HIR changes make sense, as I don't fully understand it. I'm likely doing things wrong.
|
You say that it does not, but GitHub thinks that it does. |
Oops, tricky keywords. Thanks! I removed that comment. |
☔ The latest upstream changes (presumably #96833) made this pull request unmergeable. Please resolve the merge conflicts. |
fa6cafa
to
e088252
Compare
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'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 HirId
s should eventually map 1-to-1 to Node
s. 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 { |
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 should be inside the call to with_parent
.
@@ -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 { |
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 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); |
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.
Do expression fields behave exactly like PatField
? Should the PatField
's name reflect that?
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.
That was a bad copy/paste. It should have been Target::ExprField
.
compiler/rustc_lint/src/levels.rs
Outdated
}) | ||
match e.kind { | ||
hir::ExprKind::Struct(qpath, fields, base_expr) => { | ||
self.with_lint_attrs(e.hir_id, |builder| { |
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 we keep this call outside of the match? It's common to both branches.
compiler/rustc_lint/src/levels.rs
Outdated
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 { |
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.
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.
compiler/rustc_lint/src/levels.rs
Outdated
match &p.kind { | ||
hir::PatKind::Struct(qpath, fields, _) => { | ||
self.visit_qpath(&qpath, p.hir_id, p.span); | ||
for field in *fields { |
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.
Likewise with visit_pat_struct_field
(or another name).
compiler/rustc_lint/src/levels.rs
Outdated
@@ -751,9 +751,26 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> { | |||
} | |||
|
|||
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) { |
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 the early lint visitor be updated the same way?
compiler/rustc_lint/src/levels.rs
Outdated
@@ -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>) { |
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 the early lint visitor be updated the same way?
Also, do we need some kind of signoff by the lang team before taking into account lint attributes in more places? |
My understanding is:
This also helps ensure that
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 |
r? @cjgillot |
@@ -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)); |
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.
Can this be moved into visit_expr_field?
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.
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, ¶m.attrs, |cx| { | ||
run_early_pass!(cx, check_generic_param, param); | ||
ast_visit::walk_generic_param(cx, param); | ||
}); | ||
} |
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 there be similar modifications for expr field and pat fields?
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.
visit_expr_field
was already there (added in #87146). I added visit_pat_field
which fixed handling for early lints on pattern fields.
☔ The latest upstream changes (presumably #98802) made this pull request unmergeable. Please resolve the merge conflicts. |
31c8dc8
to
269ed24
Compare
📌 Commit 269ed24b66b43a117601c6d494d6930ce307182a has been approved by It is now in the queue for this repository. |
⌛ Testing commit 269ed24b66b43a117601c6d494d6930ce307182a with merge cbae2e3618280f231ef33b34c729fd7a2a234a23... |
💔 Test failed - checks-actions |
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.
3fac153
to
900a9d3
Compare
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 |
@bors r+ |
⌛ Testing commit 900a9d3 with merge 50c8baf6e5d96319ba99ab4e334e3be204e8eba2... |
💥 Test timed out |
@bors retry 4hour timeout on x86_64-mingw-1 These tests hung: |
☀️ Test successful - checks-actions |
Finished benchmarking commit (6ce7609): comparison url. Instruction count
Max RSS (memory usage)Results
CyclesResults
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression Footnotes |
… 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`.
This adds 3 loosely related changes (I can split PRs if desired):
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
.