-
Notifications
You must be signed in to change notification settings - Fork 181
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
introduce a Visit
trait to go with Fold
#333
Comments
One question is how general to make the trait. The trait in rustc hardcodes returning a bool. I was imagining we might want something more general. I actually implemented this once but I can't find the branch. It looked something like: trait Visitor {
type Result: VisitorResult;
fn visit_ty(&mut self, ty; &Ty) -> Self::Result;
fn visit_lifetime(&mut self, ty; &Lifetime) -> Self::Result;
} To actually visit things, you used the trait Visit {
fn visit_with<R>(&self, visitor: &mut dyn Visitor<Result = R>) -> R;
}
trait VisitResult {
fn new() -> Self;
fn and_then(self, op: impl FnOnce() -> Self) -> Self;
} The derive for a struct like
The struct FindAny(bool);
impl VisitResult for FindAny{
fn new() -> FindAny {
FindAny(false)
}
fn and_then(self, op: impl FnOnce() -> FindAny) -> FindAny {
if self.0 { self } else { op() }
}
} You could also implement a counter etc: struct Counter(usize);
impl VisitResult for Counter{
fn new() -> Counter {
Counter(0)
}
fn and_then(self, op: impl FnOnce() -> FindAny) -> Counter {
Counter(self.0 + op().0)
}
} |
The steps to implement this are probably:
|
This seems like a fairly easy issue to try to implement, so I'll mark it as such. |
Hello, From what I could understand the work here involves
Am I misunderstanding anything here? |
I don't know if any of this is relevant to Chalk, but as a bit of "here's another example of a visitor", when I created a visitor for fuzzy-pickles, it had a few components: A trait that each node in the AST implemented. This was the trait that has a corresponding derive macro. Each unique pass implements one of these traits. They have a huge number of methods: two for each corresponding AST node type, one on entry to the node, one on exit. Every method has a default implementation so that a specific implementation only needs to hook into the AST nodes it is interested in. The primary difference in the traits is in the signatures: trait Visit {
fn visit_array(&mut self, &'ast Array) -> Control
}
trait VisitMut {
fn visit_array(&mut self, &mut Array) -> Control
} |
@SuhasHebbar sound about right. Just want to clarify that not all @shepmaster another (more relevant) example would the Visitor in rustc: https://github.com/rust-lang/rust/blob/master/src/librustc/ty/fold.rs#L198 |
I would like to pick this one up, but I am not really sure about the design: what are the benefits of using |
So @jackh726 created a Zulip thread for this discussion. (thanks, I find it hard to keep up with gh notifications for this sort of thing...) |
Right now we have a
Fold
trait that is used to transform types and other bits of IR. But sometimes we don't need to recreate the IR, we instead want to compute a value (e.g., count all the types etc). You can model this as a folder with mutable state, but it'd be more efficient to have a "visitor" trait.Some examples where this would be useful:
UCollector
needs_shift
methodThe text was updated successfully, but these errors were encountered: