-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Refactor visit.rs with a Visitor
trait
#7081
Comments
(The original description for this ticket used an @visitor object, but that was not what Niko intended. I'm rewriting the description now to reflect a more generic approach.) |
I don't think we should use objects here. I envision something like this:
and then we implement individual passes follows:
|
Incidentally, @msullivan has been working on fixing bugs in default methods. For all I know this approach may be feasible now, or there may be bugs standing in the way. |
This step 1 in my plan for issue #7081: Refactor visit.rs with a `@Visitor` trait.
Default methods, which block this, are tracked in #2794 |
So apparently we have @pnkfelix working on this problem on branches labelled fsk-issue7081 like this, as well as @Aatch's branch that sanxiyn mentioned above, and now there is also @pcwalton working on a visit-trait branch as well, as he announced in the #rust irc channel. Though I think pcwalton's code is putting in an |
�One detail I meant to include in my last comment: the rewrite from my branch is attempting to support the transition from I saw such incremental development as a virtue of my strategy, but its possible that getting that right is just slowing my progress down. |
Indeed. If we're going to rewrite all the visitor passes, it'd be a shame not to remove the managed boxes! |
I guess having more info is useful: a while ago I used @Aatch's branch to start rewriting |
Okay, I've ported all of the visitor passes in a pretty mechanical fashion. The results of the mechanical rewrites are not pretty, nor are they meant to be. I'm going to land this in a couple of incremental pull requests. The first few will be focused on landing the mechanical rewrites, with an emphasis on diffs that make it semi-obvious that they are refactorings. Code-cleanup will come later, on a file by file basis. |
…r=nikomatsakis Rewriting visit.rs to operate on a borrowed `&mut V` where `<V:Visitor>` r? @nikomatsakis r? @pcwalton This is the first in a planned series of incremental pull requests. (There will probably be five pull requests including this one, though they can be combined or split as necessary.) Part of #7081. (But definitely does *not* complete it, not on its own, and not even after all five parts land; there are still a few loose ends to tie up or trim afterwards.) The bulk of this change for this particular PR is pnkfelix/rust@3d83010, which has the changes necessary to visit.rs to support everything else that comes later. The other commits are illustrating the standard mechanical transformation that I am applying. One important point for nearly *all* of these pull requests: I was deliberately *not* trying to be intelligent in the transformation. * My goal was to minimize code churn, and make the transformation as mechanical as possible. * For example, I kept the separation between the Visitor struct (corresponding to the earlier vtable of functions that were potentially closed over local state) and the explicitly passed (and clones) visitor Env. I am certain that this is almost always unnecessary, and a later task will be to go through an meld the Env's into the Visitors as appropriate. (My original goal had been to make such melding part of this task; that's why I turned them into a (Env, vtable) tuple way back when. But I digress.) * Also, my main goal here was to get rid of the record of `@fn`'s as described by the oldvisit.rs API. (This series gets rid of all but one such case; I'm still investigating that.) There is *still* plenty of `@`-boxing left to be removed, I'm sure, and even still some `@fn`'s too; removing all of those is not the goal here; its just to get rid of the encoded protocol of `@fn`'s in the (old)visit API. To see where things will be going in the future (i.e., to get a sneak-preview of future pull-requests in the series), see: * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step1 (that's this one) * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step2 * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step3 * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step4 * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step5 * Note that between step 4 and step 5 there is just a single commit, but its a doozy because its the only case where my mechanical transformation did not apply, and thus more serious rewriting was necessary. See commit pnkfelix/rust@da902b2
…r=graydon,nikomatsakis r? @nikomatsakis Follow up to #8527 (which was step 1 of 5). See that for overall description Part of #7081
…r=huonw "non-mechanical" : there was lots more hacking than the other more-mechanical ports Felix did. r? @huonw. (Or @nikomatsakis ; I just want someone to sanity-check this. Its not a thing of beauty.) Followup to #8623. (See #8527, which was step 1 of 5, for the full outline. Part of #7081.) Notes on the change follow. There's also a strange pattern that I hacked in to accommodate the Outer/Inner traversal structure of the existing code (which was previously encoding this by untying the Y-combinator style knot of the vtable, and then retying it but superimposing new methods that "stop at items"). I hope either I or someone else can come back in the future and replace this ugliness with something more natural. Added boilerplate macro; all the OuterLint definitions are the same (but must be abstracted over implementing struct, thus the macro). Revised lint.rs use declarations to make ast references explicit. Also removed unused imports.
So is this done now? |
No it turns out there are a couple more oldvisit clients that need to be ported. One I knew about, the others I somehow overlooked before. |
Further followup on #7081. There still remains writeback.rs, but I want to wait to investigate that one because I've seen `make check` issues with it in the past.
…rLoan{Ctxt,Visitor}.
r? anyone Remove some trivial Visitor structs, using their non-trivial Contexts as the Visitor implementation instead. Removed a little bit of `@boxing` as well. Part of ongoing work on #7081.
Is this done now? |
@sanxiyn I think it would be good to first finish unifying as many Ctxt+Visitors as possible, as illustrated in the commits with log messages of the form |
…s, r=alexcrichton r? anyone. Part of #7081. More refactorings of the syntax::visit::Visitor implementations, folding so-called "environments" into the visitor impl when the latter was previously a trivial unit struct. As usual, this refactoring only applies when the environments are not actually carrying state that is meant to be pushed and popped as we traverse the expression. (For an example where the environment *isn't* just passed through, see the `visit_fn` in `liveness.rs`.) Got rid of a bit of @-allocation in borrowck. Both cases should be pure-refactorings.
As a step towards closing this bug, here is a list of impls of
I spent a while this morning/afternoon looking at the typeck/regionck cases below. Unfortunately the assumption that we have a
The lints are a special case; I suspect this code needs a rewrite anyway, and its probably not worth trying to further bandaid it with refactorings like this. Still, here's the list.
|
…ir visitor structs.
…er, r=huonw r? anyone Part of #7081. Removed many unnecessary context arguments, turning them into visitors. Removed some @allocation. If this lands, then I think the only thing left that is unaddressed are: * the various lint visitors, and * middle/privacy.rs, which has `impl<'self> Visitor<&'self method_map> for PrivacyVisitor`
okay, looks like just the privacy.rs and the lints are left. And privacy isn't as hard to deal with as I had thought it would be (I should have tried harder to get it into that last PR). I'll probably close this ticket after I put up a PR for privacy. |
@alexcrichton is going to be mucking with the privacy code, so I'm going to yield that battle ground to him and close this ticket. :) |
Currently
libsyntax/visit.rs
provides a record that holds a collection of@fn
's, using a mix of lambda-lifting and an explicit virtual method table to define traversals over the AST.where
So then a use of the visitor looks like this (taken from
freevars.rs
):where
ignore_item
andwalk_expr
are defined accordingly.The above is awkward. A more natural way to encode this would be via a
Visitor
trait that defined the visit methods; then instances of the trait would correspond to the accumulated state denoted above byE
in the struct definition and1
in the freevars example.(I originally had written a
@Visitor
object, but there is no need to commit to using objects in the Visitor interface.)The text was updated successfully, but these errors were encountered: