This is a follow-up to #5761. Its purpose is to make core::libc more consistent - it currently only defines SIGKILL and SIGTERM, because they are the only values that happen to be needed by libcore.
This adds all the posix signal value constants, except for those that have different values on different architectures.
The output of the command `man 7 signal` was used to compile these signal values.
value constants, except for those that have different values
on different architectures.
The output of the command `man 7 signal` was used to
compile these signal values.
The foldl based implementation allocates lots of unneeded vectors.
iter::map_to_vec is already optimized to avoid these.
One place that benefits quite a lot from this is the metadata decoder, helping with compile times for tiny programs.
The current protocol is very comparable to Python, where `.__iter__()` returns an iterator object which implements `.__next__()` and throws `StopIteration` on completion. `Option` is much cleaner than using a exceptions as a flow control hack though. It requires that the container is frozen so there's no worry about invalidating them.
Advantages over internal iterators, which are functions that are passed closures and directly implement the iteration protocol:
* Iteration is stateful, so you can interleave iteration over arbitrary containers. That's needed to implement algorithms like zip, merge, set union, set intersection, set difference and symmetric difference. I already used this internally in the `TreeMap` and `TreeSet` implementations, but regions and traits weren't solid enough to make it generic yet.
* They provide a universal, generic interface. The same trait is used for a forward/reverse iterator, an iterator over a range, etc. Internal iterators end up resulting in a trait for each possible way you could iterate.
* They can be composed with adaptors like `ZipIterator`, which also implement the same trait themselves.
The disadvantage is that they're a pain to write without support from the compiler for compiling something like `yield` to a state machine. :)
This can coexist alongside internal iterators since both can use the current `for` protocol. It's easier to write an internal iterator, but external ones are far more powerful/useful so they should probably be provided whenever possible by the standard library.
## Current issues
#5801 is somewhat annoying since explicit type hints are required.
I just wanted to get the essentials working well, so I haven't put much thought into making the naming concise (free functions vs. static `new` methods, etc.).
Making an `Iterable` trait seems like it will have to be a long-term goal, requiring type system extensions. At least without resorting to objects which would probably be unacceptably slow.
This restores the trait that was lost in 216e85fadf. It will eventually be broken up into a more fine-grained trait hierarchy in the future once a design can be agreed upon.
As proposed in issue #5632.
I added some new stuff to libc - hopefully correctly. I only added a single signal constant (SIGKILL) because adding more seems complicated by differences between platforms - and since it is not required for issue #5632 then I figure that I can use a further pull request to flesh out the SIG* constants more.
This refactors much of the ast generation required for `deriving` instances into a common interface, so that new instances only need to specify what they do with the actual data, rather than worry about naming function arguments and extracting fields from structs and enum. (This all happens in `generic.rs`. I've tried to make sure it was well commented and explained, since it's a little abstract at points, but I'm sure it's still a little confusing.)
It makes instances like the comparison traits and `Clone` short and easy to write.
Caveats:
- Not surprisingly, this slows the expansion pass (in some cases, dramatically, specifically deriving Ord or TotalOrd on enums with many variants). However, this shouldn't be too concerning, since in a more realistic case (compiling `core.rc`) the time increased by 0.01s, which isn't worth mentioning. And, it possibly slows type checking very slightly (about 2% worst case), but I'm having trouble measuring it (and I don't understand why this would happen). I think this could be resolved by using traits and encoding it all in the type system so that monomorphisation handles everything, but that would probably be a little tricky to arrange nicely, reduce flexibility and make compiling rustc take longer. (Maybe some judicious use of `#[inline(always)]` would help too; I'll have a bit of a play with it.)
- The abstraction is not currently powerful enough for:
- `IterBytes`: doesn't support arguments of type other than `&Self`.
- `Encodable`/`Decodable` (#5090): doesn't support traits with parameters.
- `Rand` & `FromStr`; doesn't support static functions and arguments of type other than `&Self`.
- `ToStr`: I don't think it supports returning `~str` yet, but I haven't actually tried.
(The last 3 are traits that might be nice to have: the derived `ToStr`/`FromStr` could just read/write the same format as `fmt!("%?", x)`, like `Show` and `Read` in Haskell.)
I have ideas to resolve all of these, but I feel like it would essentially be a simpler version of the `mt` & `ty_` parts of `ast.rs`, and I'm not sure if the simplification is worth having 2 copies of similar code.
Also, makes Ord, TotalOrd and TotalEq derivable (closes#4269, #5588 and #5589), although a snapshot is required before they can be used in the rust repo.
If there is anything that is unclear (or incorrect) either here or in the code, I'd like to get it pointed out now, so I can explain/fix it while I'm still intimately familiar with the code.
This adds an example for most of the methods in Rng.
As a total newcomer to Rust, it took a while to figure out how to do basic things like use library functions, because there aren't many usage examples, and most examples that Google turns up are out of date. Something like this would have saved me a bit of time.
This might be a bit verbose. Some alternative options would be to consolidate all the examples into one section, or to only have code for the specific function call inline.
signature. In a nutshell, the idea is to (1) report an error if, for
a region pointer `'a T`, the lifetime `'a` is longer than any
lifetimes that appear in `T` (in other words, if a borrowed pointer
outlives any portion of its contents) and then (2) use this to assume
that in a function like `fn(self: &'a &'b T)`, the relationship `'a <=
'b` holds. This is needed for #5656. Fixes#5728.
rather than a tuple. The current setup iterates over
`BaseIter<(&'self K, &'self V)>` where 'self is a lifetime declared
*in the each method*. You can't place such a type in
the impl declaration. The compiler currently allows it,
but this will not be legal under #5656 and I'm pretty sure
it's not sound now.
It was simpler to just give the variants a value instead of listing out all the cases for (*self, *other) in a match statement or writing spaghetti code. This makes the `cmp` method easier to use with FFI too, since you're a cast away from an idiomatic C comparator function. It would be fine implemented another way though.
This removes some of the easier instances of mutable fields where the explicit self can just become `&mut self` along with removing some unsafe blocks which aren't necessary any more now that purity is gone.
Most of #4568 is done, except for [one case](https://github.com/alexcrichton/rust/blob/less-mut-fields/src/libcore/vec.rs#L1754) where it looks like it has to do with it being a `const` vector. Removing the unsafe block yields:
```
/Users/alex/code/rust2/src/libcore/vec.rs:1755:12: 1755:16 error: illegal borrow unless pure: creating immutable alias to const vec content
/Users/alex/code/rust2/src/libcore/vec.rs:1755 for self.each |e| {
^~~~
/Users/alex/code/rust2/src/libcore/vec.rs:1757:8: 1757:9 note: impure due to access to impure function
/Users/alex/code/rust2/src/libcore/vec.rs:1757 }
^
error: aborting due to previous error
```
I also didn't delve too much into removing mutable fields with `Cell` or `transmute` and friends.
Performing a deep copy isn't ever desired for a persistent data
structure, and it requires a more complex implementation to do
correctly. A deep copy needs to check for cycles to avoid an infinite
loop.
Performing a deep copy isn't ever desired for a persistent data
structure, and it requires a more complex implementation to do
correctly. A deep copy needs to check for cycles to avoid an infinite
loop.
A number like 0b1_1111_1111 == 511 would be parsed to Some(255u8) rather than None
by from_str_common, since 255 * 2 + 1 == 255 (mod 256) so the overflow wasn't detected.
Only applied to conversions where the radix was a power of 2, and where all digits
repeated.
Closes#5770.
bare function store (which is not in fact a kind of value) but rather
ty::TraitRef. Removes many uses of fail!() and other telltale signs of
type-semantic mismatch.
cc #4183 (not a fix, but related)
This pull request removes some mut-fields from at_vec, str, vec, unstable, and cell. Sadly in case of Cell this required using either transmute_mut (2 instances) or changing the interface. I chose the former. Perhaps it would be a good idea to merge Cell and Option, and take that opportunity to change the interface to use '&mut self' instead of '&self' (which would enable removing the transmutations) for take and put_back.
r?
This naming is free now that `oldmap` has finally been removed, so this is a search-and-replace to take advantage of that. It might as well be called `HashMap` instead of being named after the specific implementation, since there's only one.
SipHash distributes keys so well that I don't think there will ever be much need to use anything but a simple hash table with open addressing. If there *is* a better way to do it, it will probably be better in all cases and can just be the default implementation.
A cuckoo-hashing implementation combining a weaker hash with SipHash could be useful, but that won't be as general purpose - you would need to write a separate fast hash function specialized for the type to really take advantage of it (like taking a page from libstdc++/libc++ and just using the integer value as the "hash"). I think a more specific naming for a truly alternative implementation like that would be fine, with the nice naming reserved for the general purpose container.
When I submitted #5659, it apparently caused some test failures. Then, because I left it in my incoming rather than making a new branch, I deleted my commit.
Let's try this again, this time, with its own branch so that I don't screw it up.
r?
It seems nobody can figure out whether this is _supposed to_ make a difference anymore, and in testing it seems to work either way, so I removed it. One less alarming warning during a fresh build.
@nikomatsakis and I were talking about how the serializers were a bit too complicated. None of the users of With the `emit_option` and `read_option` functions, the serializers are now moving more high level. This patch series continues that trend. I've removed support for emitting specific string and vec types, and added support for emitting mapping types.
I believe this patch incorporates all expected syntax changes from extern
function reform (#3678). You can now write things like:
extern "<abi>" fn foo(s: S) -> T { ... }
extern "<abi>" mod { ... }
extern "<abi>" fn(S) -> T
The ABI for foreign functions is taken from this syntax (rather than from an
annotation). We support the full ABI specification I described on the mailing
list. The correct ABI is chosen based on the target architecture.
Calls by pointer to C functions are not yet supported, and the Rust type of
crust fns is still *u8.
Before it wouldn't warn about unused imports in the list if something in the list was used. These commits fix that case, add a test, and remove all unused imports in lists of imports throughout the compiler.
As far as I can tell, this doesn't make rust compile any
faster, but it does at least remove one level of indirection
on malloc, which might help speed up some operations.
@nikomatsakis pointed out that `fn read_option<T>(&self, f: &fn() -> T) -> Option<T>` should have this syntax so it can work with custom option types: `fn read_option<T>(&self, f: &fn(bool) -> T) -> T`.
Also, this also includes some `#[inline(always)]` on the memory functions in `src/libcore/unstable/lang.rs` to reduce one level of indirection when allocating memory.
As far as I can tell, this doesn't make rust compile any
faster, but it does at least remove one level of indirection
on malloc, which might help speed up some operations.
This is needed so that hash tables can require strict equality but not require types to be ordered. It's a subset of the functionality of `TotalOrd` so I made that inherit from `TotalEq`.
- Most functions that used to return `~[~str]` for a list of substrings got turned into iterators over `&str` slices
- Some cleanup of apis, docs and code layout
This currently requires workarounds for the borrow checker not being flow-sensitive for `LinearMap` and `TrieMap`, but it can already be expressed for `TreeMap` and `SmallIntMap` without that.
Kills some warnings, and implements str::each_char_reverse so that it actually iterates. The test case wasn't detecting a failure, since the loop body was never executed.
This is a minor step towards #3571, although I'm sure there's still more work to be done. Previously, `fmt!` collected a bunch of strings in a vector and then called `str::concat`. This changes the behavior by maintaining only one buffer and appending directly into that buffer. This avoids doubly-allocating memory, and it has the added bonus of reducing some allocations in `core::unstable::extfmt`
One of the unfortunate side effects of this is that the `rt` module in `extfmt.rs` had to be duplicated to avoid `stage0` errors. Dealing with the change in conversion functions may require a bit of a dance when a snapshot happens, but I think it's doable.
If the second speedup commit isn't deemed necessary, I got about a 15% speedup with just the first patch which doesn't require any modification of `extfmt.rs`, so no snapshot weirdness.
Here's some other things I ran into when looking at `fmt!`:
* I don't think that #2249 is relevant any more except for maybe removing one of `%i` or `%d`
* I'm not sure what was in mind for using traits with #3571, but I thought that formatters like `%u` could invoke the `to_uint()` method on the `NumCast` trait, but I ran into some problems like those in #5462
I'm having trouble thinking of other wins for `fmt!`, but if there's some suggestions I'd be more than willing to look into if they'd work out or not.
The `each_line` function in `ReaderUtil` acts very differently to equivalent functions in Python, Ruby, Clojure etc. E.g. given a file `t` with contents `trailing\nnew line\n` and `n` containing `no trailing\nnew line`:
Rust:
```Rust
t: ~[~"trailing", ~"new line", ~""]
n: ~[~"no trailing", ~"new line"]
```
Python:
```Python
>>> open('t').readlines()
['trailing\n', 'new line\n']
>>> open('n').readlines()
['no trailing\n', 'new line']
```
Ruby:
```Ruby
irb(main):001:0> File.readlines('t')
=> ["trailing\n", "new line\n"]
irb(main):002:0> File.readlines('n')
=> ["no trailing\n", "new line"]
```
Clojure
```Clojure
user=> (read-lines "t")
("trailing" "new line")
user=> (read-lines "n")
("no trailing" "new line")
```
The extra string that rust includes at the end is inconsistent, and means that it is impossible to distinguish between the "real" empty line a file that ends `...\n\n`, and the "fake" one after the last `\n`.
The code attached makes Rust's `each_line` act like Clojure (and PHP, i.e. not including the `\n`), as well as adjusting `str::lines` to fix the trailing empty line problem.
Also, add a convenience `read_lines` method to read all the lines in a file into a vector.
Specifically, `lines` and `each_line` will not emit a trailing empty string
when given "...\n". Also, add `read_lines`, which just collects all of
`each_line` into a vector, and `split_*_no_trailing` which will is the
generalised version of `lines`.
This makes the `trim` and `substr` functions return a slice instead of an `~str`, and removes the unnecessary `Trimmable` trait (`StrSlice` already contains the same functionality).
Also moves the `ToStr` implementations for the three str types into the str module in anticipation of further untangling.
The old string benchmarks weren't very useful because the strings weren't long enough, so I just threw those out for now. I left out benchmarks of `oldmap` because it's clear that it's 30-40% slower and it doesn't implement the `Map` trait.
This also cleanly divides up `insert`, `search` and `remove`.
Adds an assert_eq! macro that asserts that its two arguments are equal. Error messages can therefore be somewhat more informative than a simple assert, because the error message includes "expected" and "given" values.
A slice now always refers to something that returns an borrowed pointer, views don't exist anymore. If you want to have an explictit copy of a slice, use `to_owned()`
For bootstrapping purposes, this commit does not remove all uses of
the keyword "pure" -- doing so would cause the compiler to no longer
bootstrap due to some syntax extensions ("deriving" in particular).
Instead, it makes the compiler ignore "pure". Post-snapshot, we can
remove "pure" from the language.
There are quite a few (~100) borrow check errors that were essentially
all the result of mutable fields or partial borrows of `@mut`. Per
discussions with Niko I think we want to allow partial borrows of
`@mut` but detect obvious footguns. We should also improve the error
message when `@mut` is erroneously reborrowed.
r?
I want to use this function as a method. There's probably a better way to design this but the existing `ToBytes` trait is not what I am looking for (it has a parameter to indicate the byte order).
adjusting a few foreign functions that were declared with by-ref
mode. This also allows us to remove by-val mode in the near future.
With copy mode, though, we have to be careful because Rust will implicitly pass
somethings by pointer but this may not be the C ABI rules. For example, rust
will pass a struct Foo as a Foo*. So I added some code into the adapters to
fix this (though the C ABI rules may put the pointer back, oh well).
This patch also includes a lint mode for the use of by-ref mode
in foreign functions as the semantics of this have changed.
r? @graydon
This removes `log` from the language. Because we can't quite implement it as a syntax extension (probably need globals at the least) it simply renames the keyword to `__log` and hides it behind macros.
After this the only way to log is with `debug!`, `info!`, etc. I figure that if there is demand for `log!` we can add it back later.
I am not sure that we ever agreed on this course of action, though I *think* there is consensus that `log` shouldn't be a statement.
The correct opendir/readdir to use appear to be the 64-bit versions called
opendir$INODE64, etc. but for some reason I can't get them to link properly
on i686. Putting them in librustrt and making gcc figure it out works.
This mystery will have to wait for another day.
This will allow you to use the `+` operator to add together any two
Options, assuming that the contents of each Option likewise implement
`+`. So Some(4) + Some(1) == Some(5), and adding with None leaves the
other value unchanged.
This might be monoidic? I don't know what that word means!
This will allow you to use the + operator to add together any two
Options, assuming that the contents of each Option likewise implement
+. So Some(4) + Some(1) == Some(5), and adding with None leaves the
other value unchanged.
This might be monoidic? I don't know what that word means!
Two changes:
- The first fixes an inconsistency in coherence whereby extension methods were added to the inherent methods table, but only in cross-crate scenarios. This causes some minor fallout in tests and so forth. In one case (comm) I added inherent and trait methods so as to avoid the need to import traits like `GenericPort` just to use a port.
- The second makes objects not implement the associated trait, as discussed in #5087.
r? @pcwalton
When parsing bytes from a wire, there is a need to parse floating-point bytes to float values ([u8*4] to f32, [u8*8] to f64). This can be done via cast::transmute, but there is no way to do it safely.
It's quite common, so I think I't better to support it in core library.
7.3x speedup in string map search speed on a microbenchmark of pure hashmap
searching against a constant string, due to the lack of allocations.
I ran into a few snags.
1. The way the coherence check is set up, I can't implement `Equiv<@str>` and
`Equiv<~str>` for `&str` simultaneously.
2. I wanted to implement `Equiv<T>` for all `T:Eq` (i.e. every type can be
compared to itself if it implements `Eq`), but the coherence check didn't
like that either.
3. I couldn't add this to the `Map` trait because `LinearMap` needs special
handling for its `Q` type parameter: it must not only implement `Equiv<T>`
but also `Hash` and `Eq`.
4. `find_equiv(&&"foo")` doesn't parse, because of the double ampersand. It has
to be written `find_equiv(& &"foo")`. We can probably just fix this.
Nevertheless, this is a huge win; it should address a major source of
performance problems, including the one here:
http://maniagnosis.crsr.net/2013/02/creating-letterpress-cheating-program.html
I've found that unused imports can often start cluttering a project after a long time, and it's very useful to keep them under control. I don't like how Go forces a compiler error by default and it can't be changed, but I certainly want to know about them so I think that a warn is a good default.
Now that the `unused_imports` lint option is a bit smarter, I think it's possible to change the default level to warn. This commit also removes all unused imports throughout the compiler and libraries (500+).
The only odd things that I ran into were that some `use` statements had to have `#[cfg(notest)]` or `#[cfg(test)]` based on where they were. The ones with `notest` were mostly in core for modules like `cmp` whereas `cfg(test)` was for tests that weren't part of a normal `mod test` module.
This is an implementation of a map and set for integer keys. It's an ordered container (by byte order, which is sorted order for integers and byte strings when done in the right direction) with O(1) worst-case lookup, removal and insertion. There's no rebalancing or rehashing so it's actually O(1) without amortizing any costs.
The fanout can be adjusted in multiples of 2 from 2-ary through 256-ary, but it's hardcoded at 16-ary because there isn't a way to expose that in the type system yet. To keep things simple, it also only allows `uint` keys, but later I'll expand it to all the built-in integer types and byte arrays.
There's quite a bit of room for performance improvement, along with the boost that will come with dropping the headers on `Owned` `~` and getting rid of the overhead from the stack switches to the allocator. It currently does suffix compression for a single node and then splits into two n-ary trie nodes, which could be replaced with an array for at least 4-8 suffixes before splitting it. There's also the option of doing path compression, which may be a good or a bad idea and depends a lot on the data stored.
I want to share the test suite with the other maps so that's why I haven't duplicated all of the existing integer key tests in this file. I'll send in another pull request to deal with that.
Current benchmark numbers against the other map types:
TreeMap:
Sequential integers:
insert: 0.798295
search: 0.188931
remove: 0.435923
Random integers:
insert: 1.557661
search: 0.758325
remove: 1.720527
LinearMap:
Sequential integers:
insert: 0.272338
search: 0.141179
remove: 0.190273
Random integers:
insert: 0.293588
search: 0.162677
remove: 0.206142
TrieMap:
Sequential integers:
insert: 0.0901
search: 0.012223
remove: 0.084139
Random integers:
insert: 0.392719
search: 0.261632
remove: 0.470401
@graydon is using an earlier version of this for the garbage collection implementation, so that's why I added this to libcore. I left out the `next` and `prev` methods *for now* because I just wanted the essentials first.
This allows `TreeMap`/`TreeSet` to fully express their requirements and reduces the comparisons from ~1.5 per level to 1 which really helps for string keys.
I also added `ReverseIter` to the prelude exports because I forgot when I originally added it.
The fix is straight-forward, but there are several changes
while fixing the issue.
1) disallow `mut` keyword when making a new struct
In code base, there are following code,
```rust
struct Foo { mut a: int };
let a = Foo { mut a: 1 };
```
This is because of structural record, which is
deprecated corrently (see issue #3089) In structural
record, `mut` keyword should be allowd to control
mutability. But without structural record, we don't
need to allow `mut` keyword while constructing struct.
2) disallow structural records in parser level
This is related to 1). With structural records, there
is an ambiguity between empty block and empty struct
To solve the problem, I change parser to stop parsing
structural records. I think this is not a problem,
because structural records are not compiled already.
Misc. issues
There is an ambiguity between empty struct vs. empty match stmt.
with following code,
```rust
match x{} {}
```
Two interpretation is possible, which is listed blow
```rust
match (x{}) {} // matching with newly-constructed empty struct
(match x{}) {} // matching with empty enum(or struct) x
// and then empty block
```
It seems that there is no such code in rust code base, but
there is one test which uses empty match statement:
https://github.com/mozilla/rust/blob/incoming/src/test/run-pass/issue-3037.rs
All other cases could be distinguished with look-ahead,
but this can't be. One possible solution is wrapping with
parentheses when matching with an uninhabited type.
```rust
enum what { }
fn match_with_empty(x: what) -> ~str {
match (x) { //use parentheses to remove the ambiguity
}
}
```