There are 4 different new tests, to check some different scenarios for
what the parse context is at the time of recovery, becasue our
compile-fail infrastructure does not appear to handle verifying
error-recovery situations.
Differentiate between unit-like struct definition item and unit-like
struct construction in the error message.
----
More generally, outlines a more generic strategy for parse error
recovery: By committing to an expression/statement at set points in
the parser, we can then do some look-ahead to catch common mistakes
and skip over them.
One detail about this strategy is that you want to avoid emitting the
"helpful" message unless the input is reasonably close to the case of
interest. (E.g. do not warn about a potential unit struct for an
input of the form `let hmm = do foo { } { };`)
To accomplish this, I added (partial) last_token tracking; used for
`commit_stmt` support.
The check_for_erroneous_unit_struct_expecting fn returns bool to
signal whether it "made progress"; currently unused; this is meant for
use to compose several such recovery checks together in a loop.
According to #7887, we've decided to use the syntax of `fn map<U>(f: &fn(&T) -> U) -> U`, which passes a reference to the closure, and to `fn map_move<U>(f: &fn(T) -> U) -> U` which moves the value into the closure. This PR adds these `.map_move()` functions to `Option` and `Result`.
In addition, it has these other minor features:
* Replaces a couple uses of `option.get()`, `result.get()`, and `result.get_err()` with `option.unwrap()`, `result.unwrap()`, and `result.unwrap_err()`. (See #8268 and #8288 for a more thorough adaptation of this functionality.
* Removes `option.take_map()` and `option.take_map_default()`. These two functions can be easily written as `.take().map_move(...)`.
* Adds a better error message to `result.unwrap()` and `result.unwrap_err()`.
The two deletions are because the test cases are very old (still using `class` and modes!), and, as far as I can tell (since they are so old), the areas they test are well tested by other rpass tests.
Some general clean-up relating to deriving:
- `TotalOrd` was too eager, and evaluated the `.cmp` call for every field, even if it could short-circuit earlier.
- the pointer types didn't have impls for `TotalOrd` or `TotalEq`.
- the Makefiles didn't reach deep enough into libsyntax for dependencies.
(Split out from https://github.com/mozilla/rust/pull/8258.)
FromHex ignores whitespace and parses either upper or lower case hex
digits. ToHex outputs lower case hex digits with no whitespace. Unlike
ToBase64, ToHex doesn't allow you to configure the output format. I
don't feel that it's super useful in this case.
This results in throwing away alias analysis information, because LLVM
does *not* implement reasoning about these conversions yet.
We specialize zero-size types since a `getelementptr` offset will
return us the same pointer, making it broken as a simple counter.
This module provided adaptors for the old internal iterator protocol,
but they proved to be quite unreadable and are not generic enough to
handle borrowed pointers well.
Since Rust no longer defines an internal iteration protocol, I don't
think there's going to be any reuse via these adaptors.
This lazily initializes the taskgroup structs for ```spawn_unlinked``` tasks. If such a task never spawns another task linked to it (or a descendant of it), its taskgroup is simply never initialized at all. Also if an unlinked task spawns another unlinked task, neither of them will need to initialize their taskgroups. This works for the main task too.
I benchmarked this with the following test case and observed a ~~21% speedup (average over 4 runs: 7.85 sec -> 6.20 sec, 2.5 GHz)~~ 11% speedup, see comment below.
```
use std::task;
use std::cell::Cell;
use std::rt::comm;
static NUM: uint = 1024*256;
fn run(f: ~fn()) {
let mut t = task::task();
t.unlinked();
t.spawn(f);
}
fn main() {
do NUM.times {
let (p,c) = comm::oneshot();
let c = Cell::new(c);
do run { c.take().send(()); }
p.recv();
}
}
```
Encoding should really only be done from [u8]<->str. The extra
convenience implementations don't really have a place, especially since
they're so trivial.
Also improved error messages in FromBase64.
The overhead of str::push_char is high enough to cripple the performance
of these two functions. I've switched them to build the output in a
~[u8] and then convert to a string later. Since we know exactly the
bytes going into the vector, we can use the unsafe version to avoid the
is_utf8 check.
I could have riced it further with vec::raw::get, but it only added
~10MB/s so I didn't think it was worth it. ToHex is still ~30% slower
than FromHex, which is puzzling.
Before:
```
test base64::test::from_base64 ... bench: 1000 ns/iter (+/- 349) = 204 MB/s
test base64::test::to_base64 ... bench: 2390 ns/iter (+/- 1130) = 63 MB/s
...
test hex::tests::bench_from_hex ... bench: 884 ns/iter (+/- 220) = 341 MB/s
test hex::tests::bench_to_hex ... bench: 2453 ns/iter (+/- 919) = 61 MB/s
```
After:
```
test base64::test::from_base64 ... bench: 1271 ns/iter (+/- 600) = 160 MB/s
test base64::test::to_base64 ... bench: 759 ns/iter (+/- 286) = 198 MB/s
...
test hex::tests::bench_from_hex ... bench: 875 ns/iter (+/- 377) = 345 MB/s
test hex::tests::bench_to_hex ... bench: 593 ns/iter (+/- 240) = 254 MB/s
```
FromHex ignores whitespace and parses either upper or lower case hex
digits. ToHex outputs lower case hex digits with no whitespace. Unlike
ToBase64, ToHex doesn't allow you to configure the output format. I
don't feel that it's super useful in this case.