Fixes#7722
I had a couple of queries:
- Should this return an array or an iterator?
- Should this be a method on iterators or on the rng? I implemented it in RngUtils as it seemed to belong with shuffle().
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