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@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@da902b2ff3b1e0bee9fc63cf00c449cceea8abf7
If they are on the trait then it is extremely annoying to use them as
generic parameters to a function, e.g. with the iterator param on the trait
itself, if one was to pass an Extendable<int> to a function that filled it
either from a Range or a Map<VecIterator>, one needs to write something
like:
fn foo<E: Extendable<int, Range<int>> +
Extendable<int, Map<&'self int, int, VecIterator<int>>>
(e: &mut E, ...) { ... }
since using a generic, i.e. `foo<E: Extendable<int, I>, I: Iterator<int>>`
means that `foo` takes 2 type parameters, and the caller has to specify them
(which doesn't work anyway, as they'll mismatch with the iterators used in
`foo` itself).
This patch changes it to:
fn foo<E: Extendable<int>>(e: &mut E, ...) { ... }
Alpha-renamed top-level visit_* functions to walk_*.
(Motivation: Distinguish visit action and recursive traversal.)
Abstract over `&mut self` rather than over `@mut self`.
This required some acrobatics, notably the
`impl<E> Visitor<E> for @mut Visitor<E>`
and corresponding introduction of `@mut Visitor` and some local `let
mut` bindings.
Remove oldvisit reference.
Added default implementations for all of the Visitor trait methods.
Note that both `visit_expr_post` and `visit_ty` are no-op's by
default, just like they are in `oldvisit::default_visitor`.
Refactoring: extract logic to ease swapping visit for oldvisit (hopefully).
- Methodyfied the string ascii extionsion functions - They got added recently, I wrapped them in a trait.
- Added `into_owned()` method for vectors - similar to `Str`'s `into_owned()` function, allows to convert to a owned vector without making a copy if the source is a owned vector.
- Added `or_some` method to option - similar to `unwrap_or_default`, but keeps the values wrapped in an `Option`. Useful for `Option` chains, eg Iterator impls.
- Added `DoubleEndedIterator` impl to `Option` - Just for compatibility with generic Iterator functions.
- Renamed nil.rs to unit.rs - the type got renamed ages ago, it's time the source file is as well.
If they are on the trait then it is extremely annoying to use them as
generic parameters to a function, e.g. with the iterator param on the trait
itself, if one was to pass an Extendable<int> to a function that filled it
either from a Range or a Map<VecIterator>, one needs to write something
like:
fn foo<E: Extendable<int, Range<int>> +
Extendable<int, Map<&'self int, int, VecIterator<int>>>
(e: &mut E, ...) { ... }
since using a generic, i.e. `foo<E: Extendable<int, I>, I: Iterator<int>>`
means that `foo` takes 2 type parameters, and the caller has to specify them
(which doesn't work anyway, as they'll mismatch with the iterators used in
`foo` itself).
This patch changes it to:
fn foo<E: Extendable<int>>(e: &mut E, ...) { ... }
The type of the result of option_env! was not fully specified in the
None case, leading to type check failures in the case where the variable
was not defined (e.g. option_env!("FOO").is_none()).
Also cleaned up some compilation warnings.
While looking over the code for object coercion, I realized that it wasn't quite handling freezing and reborrowing correctly. Tweak the code, adding tests for the relevant cases.
r? @pcwalton
This includes a number of improvements to `ifmt!`
* Implements formatting arguments -- `{:0.5x}` works now
* Formatting now works on all integer widths, not just `int` and `uint`
* Added a large doc block to `std::fmt` which should help explain what `ifmt!` is all about
* Added floating point formatters, although they have the same pitfalls from before (they're just proof-of-concept now)
Closed a couple of issues along the way, yay! Once this gets into a snapshot, I'll start looking into removing all of `fmt`
This pull request re-implements handling of visibility scopes and source code positions in debug info. It should now be very stable and properly handle
+ variable shadowing
+ expanded code (macros and the new for-loop de-sugaring, for example)
+ variables in the middle of nested scopes
+ bindings declared in the head of match statement arms.
all of which did not work at all or did not work reliably before. Those interested in a more detailed description of the problems at hand, I kindly refer to http://michaelwoerister.github.io/2013/08/03/visibility-scopes.html
Why doesn't the `populate_scope_map()` function use `syntax::visit`?
Because it would not improve this particular AST walker (see: 69dc790849 (commitcomment-3781426))
Cheers,
Michael
Since the new runtime landed, the *-nopt builders have increased cycle time by roughly an hour. I have a feeling that this is because the entire runtime is in rust and it's not being optimized at all. In that past with an optimized C++ runtime it looks like things ran faster.
This adds the ability to disable optimizations in tests only, not for the entire compiler. This means that the entire compiler and associated libraries will be built with optimizations, but the tests themselves would be built and run without optimizations.
This isn't quite as good of a guarantee as disabling optimizations everywhere, but hopefully it'll improve cycle time for the *-nopt builds to move the queue along faster.