-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Unify AST Visitors with a macro like MIR Visitors #128974
base: master
Are you sure you want to change the base?
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @lcnr (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
This comment has been minimized.
This comment has been minimized.
r? compiler |
r? @cjgillot woops |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
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.
Wow, that's some great work you did @maxcabrajac!
Please take this as an opportunity to simplify stuff. If some distinction has you make weird corner cases, don't hesitate to remove it. My comments are suggestions in this direction.
compiler/rustc_ast/src/visitors.rs
Outdated
make_visit!{P!(Local), visit_local, walk_local} | ||
make_visit!{P!(Pat), visit_pat, walk_pat} | ||
make_visit!{P!(Expr), visit_expr, walk_expr} | ||
make_visit!{P!(Ty), visit_ty, walk_ty} | ||
make_visit!{P!(Block), visit_block, walk_block} | ||
make_visit!{P!(FnDecl), visit_fn_decl, walk_fn_decl} |
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 we remove the P!
from all these?
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 put these P!
to maintain all function signatures the same, thus avoiding changes on implementers. I don't know why the original MutVisitor received &mut P<T>
instead of &mut T
for these types, but I just kept what was being done.
I think it's better to do two passes. Do what can be done without changing the trait API, after that, change what is weird about their original implementation and change all implementers accordingly. What do you think about it? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
6613670
to
2d751e6
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
That force push to this PR was just because I missclicked "Sync fork" on the wrong branch and wanted to revert it. I'm keeping this as reference for what to do in the other PRs. Now I'm doing what can be done before introducing macros, ok?
Added "related to #this PR" to them. One last thing:
Is fn visit_t(&mut self, t: &$($lt)? $($mut)? T)) -> result!() {
walk_t(self, t)
} After already using |
…trochenkov Remove visit_expr_post from ast Visitor `visit_expr_post` is only present in the immutable version of ast Visitors and its default implementation is a noop. Given that its only implementer is on `rustc_lint/src/early.rs` and its name follows the same naming convention as some other lints (`_post`), it seems that `visit_expr_post` being in `Visitor` was a little mistake. r? `@petrochenkov` related to rust-lang#128974
👍
I didn't look into much detail yet, just a general feeling (e.g. there are multiple layers of macros, a dozen of helper macros, etc). |
Rollup merge of rust-lang#132107 - maxcabrajac:remove_expr_post, r=petrochenkov Remove visit_expr_post from ast Visitor `visit_expr_post` is only present in the immutable version of ast Visitors and its default implementation is a noop. Given that its only implementer is on `rustc_lint/src/early.rs` and its name follows the same naming convention as some other lints (`_post`), it seems that `visit_expr_post` being in `Visitor` was a little mistake. r? `@petrochenkov` related to rust-lang#128974
☔ The latest upstream changes (presumably #132116) made this pull request unmergeable. Please resolve the merge conflicts. |
Pass Ident by reference in ast Visitor `MutVisitor`'s version of `visit_ident` passes around `&Ident`, but `Visitor` copies `Ident`. This PR changes that r? `@petrochenkov` related to rust-lang#128974
Rollup merge of rust-lang#132106 - maxcabrajac:ident_ref, r=petrochenkov Pass Ident by reference in ast Visitor `MutVisitor`'s version of `visit_ident` passes around `&Ident`, but `Visitor` copies `Ident`. This PR changes that r? `@petrochenkov` related to rust-lang#128974
@maxcabrajac any updates on this? thanks |
Hi @Dylan-DPC! The motivation for doing it was functions like this: fn visit_expr(&mut self, expr: &mut P<ast::Expr>) {
match expr.kind {
ast::ExprKind::MacCall(_) => *expr = self.remove(expr.id).make_expr(),
_ => walk_expr(self, expr),
}
} In the code above the After removing the wrapper from fn visit_expr(&mut self, expr: &mut ast::Expr) {
match expr.kind {
ast::ExprKind::MacCall(_) => *expr = self.remove(expr.id).make_expr().into_inner(),
_ => walk_expr(self, expr),
}
} This reuses the previous allocation, but throws away the one But changing this requires a huge amount of other changes and thinking about whether each callee requires the wrapper or should also return an unwrapped All of this multiplied by the amount of structs that are wrapped in I still think removing the wrappers from the There are still other unrelated changes to do. I'll focus on them for now. =) |
Pass Ident by reference in ast Visitor `MutVisitor`'s version of `visit_ident` passes around `&Ident`, but `Visitor` copies `Ident`. This PR changes that r? `@petrochenkov` related to rust-lang#128974
…g_arg, r=compiler-errors Change Visitor::visit_precise_capturing_arg so it returns a Visitor::Result r? `@petrochenkov` related to rust-lang#128974
…ochenkov Add visit_coroutine_kind to ast::Visitor r? `@petrochenkov` related to rust-lang#128974
Rollup merge of rust-lang#133049 - maxcabrajac:visit_precise_capturing_arg, r=compiler-errors Change Visitor::visit_precise_capturing_arg so it returns a Visitor::Result r? `@petrochenkov` related to rust-lang#128974
…ochenkov Add visit_coroutine_kind to ast::Visitor r? `@petrochenkov` related to rust-lang#128974
…ochenkov Add visit_coroutine_kind to ast::Visitor r? ``@petrochenkov`` related to rust-lang#128974
Rollup merge of rust-lang#132956 - maxcabrajac:coroutine_kind, r=petrochenkov Add visit_coroutine_kind to ast::Visitor r? ``@petrochenkov`` related to rust-lang#128974
Unify FnKind between AST visitors and make WalkItemKind more straight forward Unifying `FnKind` requires a bunch of changes to `WalkItemKind::walk` signature so I'll change them in one go related to rust-lang#128974 r? `@petrochenkov`
Rollup merge of rust-lang#132787 - maxcabrajac:fnctxt, r=petrochenkov Unify FnKind between AST visitors and make WalkItemKind more straight forward Unifying `FnKind` requires a bunch of changes to `WalkItemKind::walk` signature so I'll change them in one go related to rust-lang#128974 r? `@petrochenkov`
…chenkov Add `visit` methods to ast nodes that already have `walk`s on ast visitors Some `walk` functions are called directly, because there were no correspondent visit functions. related to rust-lang#128974 & rust-lang#127615 r? `@petrochenkov`
Rollup merge of rust-lang#133188 - maxcabrajac:walk_no_visit, r=petrochenkov Add `visit` methods to ast nodes that already have `walk`s on ast visitors Some `walk` functions are called directly, because there were no correspondent visit functions. related to rust-lang#128974 & rust-lang#127615 r? `@petrochenkov`
Add visits to nodes that already have flat_maps in ast::MutVisitor This PR aims to add `visit_` methods for every node that has a `flat_map_` in MutVisitor, giving implementers free choice over overriding `flat_map` for 1-to-n conversions or `visit` for a 1-to-1. There is one major problem: `flat_map_stmt`. While all other default implementations of `flat_map`s are 1-to-1 conversion, as they either only call visits or a internal 1-to-many conversions are natural, `flat_map_stmt` doesn't follow this pattern. `flat_map_stmt`'s default implementation is a 1-to-n conversion that panics if n > 1 (effectively being a 1-to-[0;1]). This means that it cannot be used as is for a default `visit_stmt`, which would be required to be a 1-to-1. Implementing `visit_stmt` without runtime checks would require it to reach over a potential `flat_map_item` or `filter_map_expr` overrides and call for their `visit` counterparts directly. Other than that, if we want to keep the behavior of `flat_map_stmt` it cannot call `visit_stmt` internally. To me, it seems reasonable to make all default implementations 1-to-1 conversions and let implementers handle `visit_stmt` if they need it, but I don't know if calling `visit` directly when a 1-to-1 is required is ok or not. related to rust-lang#128974 & rust-lang#127615 r? `@petrochenkov`
Add visits to nodes that already have flat_maps in ast::MutVisitor This PR aims to add `visit_` methods for every node that has a `flat_map_` in MutVisitor, giving implementers free choice over overriding `flat_map` for 1-to-n conversions or `visit` for a 1-to-1. There is one major problem: `flat_map_stmt`. While all other default implementations of `flat_map`s are 1-to-1 conversion, as they either only call visits or a internal 1-to-many conversions are natural, `flat_map_stmt` doesn't follow this pattern. `flat_map_stmt`'s default implementation is a 1-to-n conversion that panics if n > 1 (effectively being a 1-to-[0;1]). This means that it cannot be used as is for a default `visit_stmt`, which would be required to be a 1-to-1. Implementing `visit_stmt` without runtime checks would require it to reach over a potential `flat_map_item` or `filter_map_expr` overrides and call for their `visit` counterparts directly. Other than that, if we want to keep the behavior of `flat_map_stmt` it cannot call `visit_stmt` internally. To me, it seems reasonable to make all default implementations 1-to-1 conversions and let implementers handle `visit_stmt` if they need it, but I don't know if calling `visit` directly when a 1-to-1 is required is ok or not. related to rust-lang#128974 & rust-lang#127615 r? ``@petrochenkov``
Rollup merge of rust-lang#133153 - maxcabrajac:flat_maps, r=petrochenkov Add visits to nodes that already have flat_maps in ast::MutVisitor This PR aims to add `visit_` methods for every node that has a `flat_map_` in MutVisitor, giving implementers free choice over overriding `flat_map` for 1-to-n conversions or `visit` for a 1-to-1. There is one major problem: `flat_map_stmt`. While all other default implementations of `flat_map`s are 1-to-1 conversion, as they either only call visits or a internal 1-to-many conversions are natural, `flat_map_stmt` doesn't follow this pattern. `flat_map_stmt`'s default implementation is a 1-to-n conversion that panics if n > 1 (effectively being a 1-to-[0;1]). This means that it cannot be used as is for a default `visit_stmt`, which would be required to be a 1-to-1. Implementing `visit_stmt` without runtime checks would require it to reach over a potential `flat_map_item` or `filter_map_expr` overrides and call for their `visit` counterparts directly. Other than that, if we want to keep the behavior of `flat_map_stmt` it cannot call `visit_stmt` internally. To me, it seems reasonable to make all default implementations 1-to-1 conversions and let implementers handle `visit_stmt` if they need it, but I don't know if calling `visit` directly when a 1-to-1 is required is ok or not. related to rust-lang#128974 & rust-lang#127615 r? ``@petrochenkov``
This is a PR to work on #127615