Retry of PR #8471
Replace the remaining functions marked for issue #8228 with similar functions that are iterator-based.
Change `either::{lefts, rights}` to be iterator-filtering instead of returning a vector.
Replace `map_vec`, `map_vec2`, `iter_vec2` in std::result with three functions:
* `result::collect` gathers `Iterator<Result<V, U>>` to `Result<~[V], U>`
* `result::fold` folds `Iterator<Result<T, E>>` to `Result<V, E>`
* `result::fold_` folds `Iterator<Result<T, E>>` to `Result<(), E>`
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, ...) { ... }
LLVMConstStringInContext() doesn't need a null-terminated string. It
takes a length instead. Using .to_c_str() here triggers an ICE whenever
the string literal embeds a null, as in "\x00".
.with_c_str() is a replacement for the old .as_c_str(), to avoid
unnecessary boilerplate.
Replace all usages of .to_c_str().with_ref() with .with_c_str().
Previous dicussions about CString suggested that interior nulls should
throw an error. This was never implemented. Add this now, using a
condition (named null_byte) to allow for recovery.
Add method .to_c_str_unchecked() that skips this check.
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).
Replace these with three functions based on iterators: collect, fold,
and fold_. The mapping part is replaced by iterator .map(), so the part
that these functions do is to accumulate the final Result<,> value.
* `result::collect` gathers `Iterator<Result<V, U>>` to `Result<~[V], U>`
* `result::fold` folds `Iterator<Result<T, E>>` to `Result<V, E>`
* `result::fold_` folds `Iterator<Result<T, E>>` to `Result<(), E>`
Remove the only use of either::partition since it was better
accomplished with vector methods.
Update either::partition so that it sizes the vectors correctly before
it starts.
- 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, ...) { ... }