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.
r? @nikomatsakis The typechecker previously passed around a boolean return flag to
indicate whether it saw something with type _|_ (that is, something
it knows at compile-time will definitely diverge) and also had some
manual checks for the `ty_err` pseudo-type that represents a previous
type error. This was because the typing rules implemented by the
typechecker didn't properly propagate _|_ and ty_err. I fixed it.
This also required changing expected error messages in a few tests,
as now we're printing out fewer derived errors -- in fact, at this
point we should print out no derived errors, so report any that
you see (ones that include "[type error]") as bugs.
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()`
The typechecker previously passed around a boolean return flag to
indicate whether it saw something with type _|_ (that is, something
it knows at compile-time will definitely diverge) and also had some
manual checks for the `ty_err` pseudo-type that represents a previous
type error. This was because the typing rules implemented by the
typechecker didn't properly propagate _|_ and ty_err. I fixed it.
This also required changing expected error messages in a few tests,
as now we're printing out fewer derived errors -- in fact, at this
point we should print out no derived errors, so report any that
you see (ones that include "[type error]") as bugs.
the assert_eq! macro compares its arguments and fails if they're not
equal. It's more informative than fail_unless!, because it explicitly
writes the given and expected arguments on failure.
Removes a lot of instances of `/*bad*/ copy` throughout libsyntax/librustc. On the plus side, this shaves about 2s off of the runtime when compiling `librustc` with optimizations.
Ideally I would have run a profiler to figure out which copies are the most critical to remove, but in reality there was a liberal amount of `git grep`s along with some spot checking and removing the easy ones.
Partial Fix for #5265
- Enabling LLVM ARM ehabi option.
- Add ARM debug information manually for ccall.s
- Compile object file using Android-NDK.
Current LLVM trunk version can generate ARM debug information for assembly files but it is incomplete for object files. Unwinding on ARM can be done with LLVM trunk(the LLVM submodule of rust has problem on generating ARM debug information). See #5368
The Android-NDK detour(0f89eab) can be removed after LLVM has complete feature of generating ARM debug information for object file.
This would close#2761. I figured that if you're supplying your own custom message, you probably don't mind the stringification of the condition to not be in the message.
All current meta items types (word, name-value, list) are now
properly parsed by rustc --cfg command line. Fixes#2399
Signed-off-by: Luca Bruno <lucab@debian.org>
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.
Continuation of #5317. Actually use operands properly now, including any number of output operands.
Which means you can do things like call printf:
```Rust
fn main() {
unsafe {
do str::as_c_str(~"The answer is %d.\n") |c| {
let a = 42;
asm!("mov $0, %rdi\n\t\
mov $1, %rsi\n\t\
xorl %eax, %eax\n\t\
call _printf"
:
: "r"(c), "r"(a)
: "rdi", "rsi", "eax"
: "volatile","alignstack"
);
}
}
}
```
```
% rustc foo.rs
% ./foo
The answer is 42.
```
Or just add 2 numbers:
```Rust
fn add(a: int, b: int) -> int {
let mut c = 0;
unsafe {
asm!("add $2, $0"
: "=r"(c)
: "0"(a), "r"(b)
);
}
c
}
fn main() {
io::println(fmt!("%d", add(1, 2)));
}
```
```
% rustc foo.rs
% ./foo
3
```
Multiple outputs!
```Rust
fn addsub(a: int, b: int) -> (int, int) {
let mut c = 0;
let mut d = 0;
unsafe {
asm!("add $4, $0\n\t\
sub $4, $1"
: "=r"(c), "=r"(d)
: "0"(a), "1"(a), "r"(b)
);
}
(c, d)
}
fn main() {
io::println(fmt!("%?", addsub(5, 1)));
}
```
```
% rustc foo.rs
% ./foo
(6, 4)
```
This also classifies inline asm as RvalueStmtExpr instead of the somewhat arbitrary kind I made it initially. There are a few XXX's regarding what to do in the liveness and move passes.
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).
r? @nikomatsakis
r? @erickt
Before this change, encoding an object containing a codemap::span
using the JSON encodeng produced invalid JSON, for instance:
[{"span":,"global":false,"idents":["abc"]}]
Since the decoder for codemap::span's ignores its argument, I
conjecture that this will not damage decoding, and should improve
it for many decoders.
LLVM could not recognize target-os when target-triple was given as like 'arm-linux-androideabi'.
Normalizing target-triple fill the missing elements.
In the case of 'arm-linux-androideabi', nomalized target-triple will be "arm-unknown-linux-androideabi" and this let llvm recognize the triple correctly. (arch: arm, vendor: unknown, os: linux, environment: android)
Before this change, encoding an object containing a codemap::span
using the JSON encodeng produced invalid JSON, for instance:
[{"span":,"global":false,"idents":["abc"]}]
Since the decoder for codemap::span's ignores its argument, I
conjecture that this will not damage decoding, and should improve
it for many decoders.
This is done in two steps:
First, we make foreign functions not consider modes at all. This is because previously ++ mode was the only way to pass structs to foreign functions and so forth. We also add a lint mode warning if you use `&&` mode in a foreign function, since the semantics of that change (it used to pass a pointer to the C function, now it doesn't).
Then, we remove by value and make it equivalent to `+` mode. At the same time, we stop parsing `-` mode and convert all uses of it to `+` mode (it was already being parsed to `+` mode anyhow).
This obsoletes pull request #5298.
r? @brson
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.
Continuing #5140
For the sake of getting this merged I've disabled debuginfo tests on mac (where running gdb needs root). Please feel free to follow up with further improvements.
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.
The original change bit Servo because rust-harfbuzz includes libharfbuzz.a in its link_args. This works fine in the rust-harfbuzz subdirectory where the static library resides, but when this is propagated to servo_gfx, the lirbrary can no longer be found since it's a relative path.
This is the first in a series of patches I'm working on to clean up the code related to `deriving`. This patch allows
```
#[deriving_eq]
#[deriving_iter_bytes]
#[deriving_clone]
struct Foo { bar: uint }
```
to be replaced with:
```
#[deriving(Eq, IterBytes, Clone)]
struct Foo { bar: uint }
```
It leaves the old attributes alone for the time being.
Eventually I'd like to incorporate the new closest-match-suggestion infrastructure for mistyped trait names, and also pass the sub-attributes to the deriving code, so that the following will be possible:
```
#[deriving(TotalOrd(qux, bar))]
struct Foo { bar: uint, baz: char, qux: int }
```
This says to derive an `impl` in which the objects' `qux` fields are compared first, followed by `bar`, while `baz` is ignored in the comparison. If no fields are specified explicitly, all fields will be compared in the order they're defined in the `struct`. This might also be useful for `Eq`. Coming soon.
Currently the opts_present() function only checks to see if the option is
configured in the match, but doesn't actually check to see if the option
value has been set. This means that opt_present('h') may return false while
opts_present([~'h']) returns true.
Add a test case to catch this condition and fix opts_present() to check
the value before returning true.
Note, there is another API difference between these two functions that this
does not address. Currently if you pass a non-configured option to
opt_present() the program will fail!(), but opts_present() simply returns
false. If it is acceptable to standardize on the fail!() then opts_present()
should probably be implemented in terms of the opt_present() function.
The `local_stage0.sh` script was not updated after commit 7dcbaed renamed
librustsyntax to libsyntax.
Currently, `./configure --enable-local-rust --local-rust-root=FOO && make` will
fail due to the missing libsyntax; this change corrects this.
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!
The local_stage0 script was not updated after commit 7dcbaed renamed
librustsyntax to libsyntax, so builds using local Rust fail due to
missing libsyntax.
These changes make const translation use adjustments (autodereference, autoreference, bare-fn-to-closure), like normal code does, replacing some ad-hoc logic that wasn't always right.
As a convenient side-effect, explicit dereference (both of pointers and of newtypes) is also supported in const expressions.
There is also a “bonus fix” for a bug in the pretty-printer exposed by one of the added tests.
Currently the opts_present() function only checks to see if the option is
configured in the match, but doesn't actually check to see if the option
value has been set. This means that opt_present('h') may return false while
opts_present([~'h']) returns true.
Add a test case to catch this condition and fix opts_present() to check
the value before returning true.
Note, there is another API difference between these two functions that this
does not address. Currently if you pass a non-configured option to
opt_present() the program will fail!(), but opts_present() simply returns
false. If it is acceptable to standardize on the fail!() then opts_present()
should probably be implemented in terms of the opt_present() function.
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 is due to the way different versions of gdb print out structs: older versions have them always spread out with fields on different lines, while newer versions will compactly print them on one line. This makes it hard for the output checker to verify the expected output.
Struct and enum representations have some complicatedness that's no longer needed. Now that everything's in one place and has access to anything we'd want to know about the type, flatten some of that out. Slight changes to representations in some cases.
The only thing we really lose is that C-like enums with one variant and a
non-zero discriminant now take up space, but I do not think this is a
common usage. As previously noted, that was mostly there for
transitional compatibility with the pre-adt.rs codebase.
Out goes the extra layer of struct wrapping; the destructedness flag is
added to the end of the struct. This means that, if the struct
previously had alignment padding at the end, the flag will live there
instead of increasing the struct size.
There were three issues effecting the example in the getopts rustdoc:
1. The blockquote was incorrectly formatted. Fixed by switching to using
an explicit markdown code section with ```.
2. The `fail fail_str(f)` would not compile. Fixed by using `fail!()` instead
of `fail`.
3. The line `matches.free[0]` produced a compile error about moving from
an immutable vector. Fix by using `copy`.
Previous year range of 2011-2013 was based on file creation date. The
check_license python script, however, only accepts copyrights starting
in 2012 or later.
There were three issues effecting the example in the getopts rustdoc:
1. The blockquote was incorrectly formatted. Fixed by switching to using
an explicit markdown code section with ```.
2. The `fail fail_str(f)` would not compile. Fixed by using `fail!()` instead
of `fail`.
3. The line `matches.free[0]` produced a compile error about moving from
an immutable vector. Fix by using `copy`.
Without this change, rust-mode doesn't work if 'cl hasn't been required
by something else, apparently. I'm not entirely sure what changed such
that I started seeing this problem instead of not, but maybe the emacs
world has been making progress towards not loading 'cl at runtime if
it's only needed at compile time.
(This change was previously submitted as e93a58d52 and accidentally reverted by ad8b437ad.)
Changes the ad-hoc closure adjustment into using adjustment info instead
of being separately driven from types, and likewise for autoderef.
Also takes care of autoref (the cases we should be seeing in consts,
at least, since we can't be doing method calls which would need the
ref-to-vec mode), which didn't quite work right previously.
However, "dereference" of a newtype isn't handled yet....
Without this change, rust-mode doesn't work if 'cl hasn't been required
by something else, apparently. I'm not entirely sure what changed such
that I started seeing this problem instead of not, but maybe the emacs
world has been making progress towards not loading 'cl at runtime if
it's only needed at compile time.
r?
`log` can polymorphically log anything, but debug!, etc. requires a format string. With this patch you can equivalently write `debug!(foo)` or `debug!("%?", foo)`.
I'm doing this because I was trying to remove `log` (replacing it with nothing, at least temporarily), but there are a number of logging statements that just want to print an arbitrary value and don't care about the format string.
I'm not entirely convinced this is a good change, since it overloads the implementation of these macros and makes their usage slightly more nuanced.
The one thing `log` can still do is polymorphically log anything,
but debug!, etc. require a format string. With this patch
you can equivalently write `debug!(foo)` or `debug!("%?", foo)`
This series of changes moves the representation details of algebraic datatypes (enums, and special cases like structs and tuples and (until they're fully removed) records) from various places around rustc::middle::trans into a single module, to enable future improvements in this area.
r?(@nikomatsakis), and the core developers in general; this seems like a “super-review” kind of change.