Cleanup substitutions and treatment of generics around traits in a number of ways
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes#4183. Needed for #5656.
r? @catamorphism
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes#4183. Needed for #5656.
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.
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 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.
Changes the parser to parse all streams into token-trees before hitting the parser proper, in preparation for hygiene. As an added bonus, it appears to speed up the parser (albeit by a totally imperceptible 1%).
Also, many comments in the parser.
Also, field renaming in token-trees (readme->forest, cur->stack).
@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.
Hey folks,
This patch series does some work on the json decoder, specifically with auto decoding of enums. Previously, we would take this code:
```
enum A {
B,
C(~str, uint)
}
```
and would encode a value of this enum to either `["B", []]` or `["C", ["D", 123]]`. I've changed this to `"B"` or `["C", "D", 123]`. This matches the style of the O'Caml json library [json-wheel](http://mjambon.com/json-wheel.html). I've added tests to make sure all this work.
In order to make this change, I added passing a `&[&str]` vec to `Decode::emit_enum_variant` so the json decoder can convert the name of a variant into it's position. I also changed the impl of `Encodable` for `Option<T>` to have the right upper casing.
I also did some work on the parser, which allows for `fn foo<T: ::cmp::Eq>() { ... }` statements (#5572), fixed the pretty printer properly expanding `debug!("...")` expressions, and removed `ast::expr_vstore_fixed`, which doesn't appear to be used anymore.
the types. Initially I thought it would be necessary to thread this data
through not only the AST but the types themselves, but then I remembered that
the pretty printer only cares about the AST. Regardless, I have elected to
leave the changes to the types intact since they will eventually be needed. I
left a few FIXMEs where it didn't seem worth finishing up since the code wasn't
crucial yet.
Because the json::Decoder uses the string variant name, we need a
way to correlate the string to the enum index. This passes in a
static &[&str] to read_enum_variant, which allows the json::Decoder
to know which branch it's trying to process.
- 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 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.
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.
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.
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.
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.
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.
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.
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.
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)`
After the removal of the "restricted keyword" feature in 0c82c00dc4 , there's no longer any difference between parse_ident() and parse_value_ident(), and therefore no difference between parse parse_path_without_tps() and parse_value_path(). I've collapsed all of these, removing the redundant functions and eliminating the need for two higher-order arguments.
Macro invocations with path separators (e.g. foo::bar!()) now produce a sensible error message, rather than an assertion failure. Also added compile-fail test case.
Fixes#5218 ?
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.