Specifically: all enums with two variants, where one has zero size (and thus at most one inhabitant) and the other has a field where the null value would not be allowed (such as a safe pointer), are now represented by storing a null pointer in the field in question.
This is a generalization of representing `Option<~T>`, `Option<@T>`, and `Option<&T>` with nullable pointers, thus fixing Tony Hoare's “billion dollar mistake”.
```rust
use core::cell;
fn main() {
let x = cell::Cell(Some(~"foo"));
let y = x.value.get_ref().get_ref();
do x.with_mut_ref |z| { *z = None; }
println(*y) // boom!
}
```
use core::cell;
fn main() {
let x = cell::Cell(Some(~"foo"));
let y = x.value.get_ref().get_ref();
do x.with_mut_ref |z| { *z = None; }
println(*y) // boom!
}
This renaming, proposed in the [Numeric Bikeshed](https://github.com/mozilla/rust/wiki/Bikeshed-Numeric-Traits#rename-modulo-into-rem-or-remainder-in-traits-and-docs), will allow us to implement div and and modulo methods that follow the conventional mathematical definitions for negative numbers without altering the definitions of the operators (and confusing systems programmers). Here is a useful answer on StackOverflow that explains the difference between `div`/`mod` and `quot`/`rem` in Haskell: (When is the difference between quotRem and divMod useful?)[http://stackoverflow.com/a/339823/679485].
This is part of the numeric trait reforms tracked in issue #4819.
Partial fix for #5985
shootout-fasta-redux.rs was calling fwrite with u64 arguments that should have been size_t, which broke on 32-bit systems. I replaced the casts to u64 by casts to size_t.
r?
As the name suggests this replaces many instances of cast::reinterpret_cast by cast::transmute. It's essentially the boring part of fixing #5163, the remaining reinterpret_casts should be more tricky to remove (unless I missed a boring case).
r? @catamorphism
This implements the fixed_stack_segment for items with the rust-intrinsic abi, and then uses it to make f32 and f64 use intrinsics where appropriate, but without overflowing stacks and killing canaries (cf. #5686 and #5697). Hopefully.
@pcwalton, the fixed_stack_segment implementation involved mirroring its implementation in `base.rs` in `trans_closure`, but without adding the `set_no_inline` (reasoning: that would defeat the purpose of intrinsics), which is possibly incorrect.
I'm a little hazy about how the underlying structure works, so I've annotated the 4 that have caused problems so far, but there's no guarantee that the other intrinsics are entirely well-behaved.
Anyway, it has good results (the following are just summing the result of each function for 1 up to 100 million):
```
$ ./intrinsics-perf.sh f32
func new old speedup
sin 0.80 2.75 3.44
cos 0.80 2.76 3.45
sqrt 0.56 2.73 4.88
ln 1.01 2.94 2.91
log10 0.97 2.90 2.99
log2 1.01 2.95 2.92
exp 0.90 2.85 3.17
exp2 0.92 2.87 3.12
pow 6.95 8.57 1.23
geometric mean: 2.97
$ ./intrinsics-perf.sh f64
func new old speedup
sin 12.08 14.06 1.16
cos 12.04 13.67 1.14
sqrt 0.49 2.73 5.57
ln 4.11 5.59 1.36
log10 5.09 6.54 1.28
log2 2.78 5.10 1.83
exp 2.00 3.97 1.99
exp2 1.71 3.71 2.17
pow 5.90 7.51 1.27
geometric mean: 1.72
```
So about 3x faster on average for f32, and 1.7x for f64. This isn't exactly apples to apples though, since this patch also adds #[inline(always)] to all the function definitions too, which possibly gives a speedup.
(fwiw, GitHub is showing 93c0888 after d9c54f8 (since I cherry-picked the latter from #5697), but git's order is the other way.)
Achieves at least 5x speed up for some functions!
Also, reorganise the delegation code so that the delegated function wrappers
have the #[inline(always)] annotation, and reduce the repetition of
delegate!(..).
@thestinger r?
~~The 2 `_unlimited` functions are marked `unsafe` since they may not terminate.~~
The `state` fields of the `Unfoldr` and `Scan` iterators are public, since being able to access the final state after the iteration has finished seems reasonable/possibly useful.
~~Lastly, I converted the tests to use `.to_vec`, which halves the amount of code for them, but it means that a `.transform(|x| *x)` call is required on each iterator.~~
(removed the 2 commits with `to_vec` and `foldl`.)
This allows one to write
```rust
let x = function_with_complicated_return_type();
let size = size_of_val(&x);
```
instead of
```rust
let x = function_with_complicated_return_type();
let size = size_of::<ComplicatedReturnType<Foo, Bar>>();
```
This closes#4364. I came into rust after modes had begun to be phased out, so I'm not exactly sure what they all did. My strategy was basically to turn on the compilation warnings and then when everything compiles and passes all the tests it's all good.
In most cases, I just dropped the mode, but in others I converted things to use `&` pointers when otherwise a move would happen.
This depends on #5963. When running the tests, everything passed except for a few compile-fail tests. These tests leaked memory, causing the task to abort differently. By suppressing the ICE from #5963, no leaks happen and the tests all pass. I would have looked into where the leaks were coming from, but I wasn't sure where or how to debug them (I found `RUSTRT_TRACK_ALLOCATIONS`, but it wasn't all that useful).
I ran across this when working on some other changes, and it looked like it wasn't too hard to "fix". I'm not very familiar with this code, but it looks like if an error was already generated there's no need to generate and ICE as well when parts of the program can just be ignored for more incorrectness.
This switches the unicode functions in core to use static character-range tables and a binary search helper rather than open-coded switch statements. It adds about 50k of read only data to the libcore binary but cuts out a similar amount of compiled IR. Would have done it this way in the first place but we didn't have structured statics for a long time.
vec::windowed fails if given window size is greater than vector length + 1.
```rust
for vec::windowed(7, &[1,2,3,4,5,6]) |vs| { fail!(); } // => do nothing
for vec::windowed(8, &[1,2,3,4,5,6]) |vs| { fail!(); } // => assertion failure in vec::slice
```