On 11-03-15 10:29 AM, Rafael Avila de Espindola wrote:
When handling
fn foo() {
fn zed(bar z) {
}
tag bar {
nil;
}
fn baz() {
zed(nil);
}
}
we currently do two passes in trans.rs. The first pass collects the tags
so that they can be used when collecting zed.
One way to avoid this is to have ty_tag point to the tag item. The
problem if we do that is that we get a cycle:
item_tag -> vec[variant]
variant -> ann
ann -> middle.ty.t (ty_tag)
middle.ty.t -> item_tag
so we would have to make one of the links mutable :-(
Do you guys think it is worth it? Which link do you prefer? Maybe you
have another idea to avoid the multiple passes without introducing the
cycle?
We discussed this on IRC, but I'll follow up here to summarize (it seems
our IRC network will not be logged any time soon; I'm working on
figuring out whether that can be made so).
My "short answer" was that I'm not interested in making the ast or ty.t
types mutable+cyclic, because it introduces a lot of potential
difficulty elsewhere (moves it to the gc layer, possibly undermines
parallelism, makes other code have to rebuild direct pointers properly,
makes folds complicated-to-impossible, depending on link).
We then had a longer discussion about whether there were any possible
alternatives, in particular trying to devise ways of addressing
potential performance costs of (a) constantly rebuilding the tree and
(b) having to keep it acyclic due to immutability.
For (a) I suggested a visitor for each node but does *not* rebuild, but
looks and possibly builds worklists for interesting subsets of the AST.
Somewhat like fold; in fact fold originally was built with the ability
to function this way; but it involved taking some 20-odd type parameters
to unify the roles and was quite cumbersome. Probably just a separate
module that walks an obj type through a tree will be sufficient.[1]
For (b) I had no ideas, but espindola suggested that a gc root could be
floated out to the maximum acyclic node in a constant structure;
pcwalton pointed out that the freeze/thaw scheme we've been discussing
for the future may well be able to integrate this with a sort of managed
weak pointer for the interior nodes, which immediately made me think of
the const refcount, and the similarity this idea has with the ideas
we've been pushing around for handling single-writer / multi-reader
multithreading as an optimized pattern for large frozen structures.
Ultimately we agreed (I think!) to defer the concept to when we're
implementing 'freeze', with the understanding that it would be very
desirable to be able to freeze not just mutables but *cyclic* mutables
into an immutable structure. So possibly we wind up with the output from
freeze being *const*, with only the root being refcounted-immutable. Or
something along these lines.
Anyway, that's a summary of how I saw the conversation unfold; correct
anything you see as wrong in this summary. It got a little heated and I
don't want to misrepresent anyone's opinion.
-Graydon
[1] Fold should really be an obj eventually; we just didn't have
obj-extension working in rustboot at the time
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev