This extends cfg-gating to attributes.
```rust
#[cfg_attr(<cfg pattern>, <attr>)]
```
will expand to
```rust
#[<attr>]
```
if the `<cfg pattern>` matches the current cfg environment, and nothing
if it does not. The grammar for the cfg pattern has a simple
recursive structure:
* `value` and `key = "value"` are cfg patterns,
* `not(<cfg pattern>)` is a cfg pattern and matches if `<cfg pattern>`
does not.
* `all(<cfg pattern>, ...)` is a cfg pattern and matches if all of the
`<cfg pattern>`s do.
* `any(<cfg pattern>, ...)` is a cfg pattern and matches if any of the
`<cfg pattern>`s do.
Examples:
```rust
// only derive Show for assert_eq! in tests
#[cfg_attr(test, deriving(Show))]
struct Foo { ... }
// only derive Show for assert_eq! in tests and debug builds
#[cfg_attr(any(test, not(ndebug)), deriving(Show))]
struct Foo { ... }
// ignore a test in certain cases
#[test]
#[cfg_attr(all(not(target_os = "linux"), target_endian = "big"), ignore)]
fn test_broken_thing() { ... }
// Avoid duplication when fixing staging issues in rustc
#[cfg_attr(not(stage0), lang="iter")]
pub trait Iterator<T> { ... }
```
Cyclic pub-use chains triggered infinite recursion, and this commit adds a hash
set to guard against cyclic recursion. This will cause one of the reexports to
render as a `pub use` instead of inlining the documentation.
Closes#16274
This breaks code like:
struct Foo {
...
}
pub fn make_foo() -> Foo {
...
}
Change this code to:
pub struct Foo { // note `pub`
...
}
pub fn make_foo() -> Foo {
...
}
The `visible_private_types` lint has been removed, since it is now an
error to attempt to expose a private type in a public API. In its place
a `#[feature(visible_private_types)]` gate has been added.
Closes#16463.
RFC #48.
[breaking-change]
Closes#17185.
The stability lint will now check code generated by macro expansion. It will allow to detect :
- arguments passed to macros using deprecated (and others) items
- macro expansion generating code using deprecated items due to its arguments (hence the second commit, fixing such issue found in libcollections)
Checking is still done at expansion, but it will also detect a macro explicitly using a deprecated item in its definition.
- Don't attempt to autoderef `!`. The `Deref`/`DerefMut` trait lookup would generate a bunch of unhelpful error spew.
- Don't allow explicit deref of `!`, since later passes just ICE. This closes issue #17373
- Don't allow explicit index of `!`, since later passes just ICE. There does not seem to be an issue associated with this
The following methods, types, and names have become stable:
* Vec
* Vec::as_mut_slice
* Vec::as_slice
* Vec::capacity
* Vec::clear
* Vec::default
* Vec::grow
* Vec::insert
* Vec::len
* Vec::new
* Vec::pop
* Vec::push
* Vec::remove
* Vec::set_len
* Vec::shrink_to_fit
* Vec::truncate
* Vec::with_capacity
* vec::raw
* vec::raw::from_buf
* vec::raw::from_raw_parts
The following have become unstable:
* Vec::dedup // naming
* Vec::from_fn // naming and unboxed closures
* Vec::get_mut // will be removed for IndexMut
* Vec::grow_fn // unboxed closures and naming
* Vec::retain // unboxed closures
* Vec::swap_remove // uncertain naming
* Vec::from_elem // uncertain semantics
* vec::unzip // should be generic for all collections
The following have been deprecated
* Vec::append - call .extend()
* Vec::append_one - call .push()
* Vec::from_slice - call .to_vec()
* Vec::grow_set - call .grow() and then .push()
* Vec::into_vec - move the vector instead
* Vec::move_iter - renamed to iter_move()
* Vec::push_all - call .extend()
* Vec::to_vec - call .clone()
* Vec:from_raw_parts - moved to raw::from_raw_parts
This is a breaking change in terms of the signature of the `Vec::grow` function.
The argument used to be taken by reference, but it is now taken by value. Code
must update by removing a leading `&` sigil or by calling `.clone()` to create a
value.
[breaking-change]
Display an explicit message about items missing after sugared doc
comment attributes. References #2789.
* I tried looking through `parser.rs` for an appropriate location for `expected_item_err` and ended up putting it just above the first use. Is there a better location?
* Did I add enough test cases? Too many? Should I add more cases for the original error message?
Change to resolve and update compiler and libs for uses.
[breaking-change]
Enum variants are now in both the value and type namespaces. This means that
if you have a variant with the same name as a type in scope in a module, you
will get a name clash and thus an error. The solution is to either rename the
type or the variant.
Part of issue #16640. I am leaving this issue open to handle parsing of
higher-rank lifetimes in traits.
This change breaks code that used unboxed closures:
* Instead of `F:|&: int| -> int`, write `F:Fn(int) -> int`.
* Instead of `F:|&mut: int| -> int`, write `F:FnMut(int) -> int`.
* Instead of `F:|: int| -> int`, write `F:FnOnce(int) -> int`.
[breaking-change]
This breaks code that looked like:
mymacro!(static::foo);
... where `mymacro!` expects a path or expression. Change such macros to
not accept keywords followed by `::`.
Closes#17298.
[breaking-change]
The implementation essentially desugars during type collection and AST
type conversion time into the parameter scheme we have now. Only fully
qualified names--e.g. `<T as Foo>::Bar`--are supported.
RUST_LOG supports regex filtering of log messages with a syntax like
`RUST_LOG=main/foo` to use the regex filter 'foo'. Unfortunately, the
filter was inverted, so `RUST_LOG=main/foo` would actually show all
messages except the ones containing 'foo'.
RUST_LOG supports regex filtering of log messages with a syntax like
`RUST_LOG=main/foo` to use the regex filter 'foo'. Unfortunately, the
filter was inverted, so `RUST_LOG=main/foo` would actually show all
messages except the ones containing 'foo'.
Recursive items are currently detected in the `check_const` pass which runs after type checking. This means a recursive static item used as an array length will cause type checking to blow the stack. This PR separates the recursion check out into a separate pass which is run before type checking.
Closes issue #17252
r? @nick29581
This is part of the migration of crates into the Cargo ecosystem. There
is now an external repository https://github.com/rust-lang/num for bignums.
The single use of libnum elsewhere in the repository is for a shootout
benchmark, which is being moved into the external crate.
Due to deprecation, this is a:
[breaking-change]
lifetime bounds. This doesn't really cause any difficulties, because
we already had to accommodate the fact that multiple implicit bounds
could accumulate. Object types still require precisely one lifetime
bound. This is a pre-step towards generalized where clauses (once you
have lifetime bounds in where clauses, it is harder to restrict them
to exactly one).
This patch does not make many functional changes, but does a lot of restructuring towards the goals of #5527. This is the biggest patch, basically, that should enable most of the other patches in a relatively straightforward way.
Major changes:
- Do not track impls through trans, instead recompute as needed.
- Isolate trait matching code into its own module, carefully structure to distinguish various phases (selection vs confirmation vs fulfillment)
- Consider where clauses in their more general form
- Integrate checking of builtin bounds into the trait matching process, rather than doing it separately in kind.rs (important for opt-in builtin bounds)
What is not included:
- Where clauses are still not generalized. This should be a straightforward follow-up patch.
- Caching. I did not include much caching. I have plans for various kinds of caching we can do. Should be straightforward. Preliminary perf measurements suggested that this branch keeps compilation times roughly what they are.
- Method resolution. The initial algorithm I proposed for #5527 does not work as well as I hoped. I have a revised plan which is much more similar to what we do today.
- Deref vs deref-mut. The initial fix I had worked great for autoderef, but not for explicit deref.
- Permitting blanket impls to overlap with specific impls. Initial plan to consider all nested obligations before considering an impl to match caused many compilation errors. We have a revised plan but it is not implemented here, should be a relatively straightforward extension.
Replaces Gc<T> in the AST with a custom owned smart pointer, P<T>. Fixes#7929.
## Benefits
* **Identity** (affinity?): sharing AST nodes is bad for the various analysis passes (e.g. one could bypass borrowck with a shared `ExprAddrOf` node taking a mutable borrow), the only reason we haven't hit any serious issues with it is because of inefficient folding passes which will always deduplicate any such shared nodes. Even if we were to switch to an arena, this would still hold, i.e. we wouldn't just use `&'a T` in the AST, but rather an wrapper (`P<'a, T>`?).
* **Immutability**: `P<T>` disallows mutating its inner `T` (unless that contains an `Unsafe` interior, which won't happen in the AST), unlike `~T`.
* **Efficiency**: folding can reuse allocation space for `P<T>` and `Vec<T>`, the latter even when the input and output types differ (as it would be the case with arenas or an AST with type parameters to toggle macro support). Also, various algorithms have been changed from copying `Gc<T>` to using `&T` and iterators.
* **Maintainability**: there is another reason I didn't just replace `Gc<T>` with `~T`: `P<T>` provides a fixed interface (`Deref`, `and_then` and `map`) which can remain fully functional even if the implementation changes (using a special thread-local heap, for example). Moreover, switching to, e.g. `P<'a, T>` (for a contextual arena) is easy and mostly automated.
When checking for an existing crate, compare against the `crate_metadata::name` field, which is the crate name which was requested during resolution, rather than the result of the `crate_metadata::name()` method, which is the crate name within the crate metadata, as these may not match when using the --extern option to `rustc`.
This fixes spurious "multiple crate version" warnings under the following scenario:
- The crate `foo`, is referenced multiple times
- `--extern foo=./path/to/libbar.rlib` is specified to rustc
- The internal crate name of `libbar.rlib` is not `foo`
The behavior surrounding `Context::should_match_name` and the comments in `loader.rs` both lead me to believe that this scenario is intended to work.
Fixes#17186
type they provide an implementation for.
This breaks code like:
mod foo {
struct Foo { ... }
}
impl foo::Foo {
...
}
Change this code to:
mod foo {
struct Foo { ... }
impl Foo {
...
}
}
Additionally, if you used the I/O path extension methods `stat`,
`lstat`, `exists`, `is_file`, or `is_dir`, note that these methods have
been moved to the the `std::io::fs::PathExtensions` trait. This breaks
code like:
fn is_it_there() -> bool {
Path::new("/foo/bar/baz").exists()
}
Change this code to:
use std::io::fs::PathExtensions;
fn is_it_there() -> bool {
Path::new("/foo/bar/baz").exists()
}
Closes#17059.
RFC #155.
[breaking-change]
The other extension types already worked this way and it can be useful to track some state along with the extension.
I also removed the `BasicMacroExpander` and `BasicIdentMacroExpander` since the span inside of them was never used. The expander function types now directly implement the relevant trait.
This PR creates a new lint : ``unused_extern_crate``, which do pretty much the same thing as ``unused_import``, but for ``extern crate`` statements. It is related to feature request #10385.
I adapted the code tracking used imports so that it tracks extern crates usage as well. This was mainly trial and error and while I believe all cases are covered, there might be some code I added that is useless (long compile times didn't give me the opportunity to check this in detail).
Also, I removed some unused ``extern crate`` statements from the libs, that where spotted by this new lint.
Avoid ever constructing cyclic types in the first place, rather than detecting them in resolve. This simplifies logic elsewhere in the compiler, in particular on the trait reform branch.
r? @pnkfelix or @pcwalton
cc #5527
The pointer in the slice must not be null, because enum representations
make that assumption. The `exchange_malloc` function returns a non-null
sentinel for the zero size case, and it must not be passed to the
`exchange_free` lang item.
Since the length is always equal to the true capacity, a branch on the
length is enough for most types. Slices of zero size types are
statically special cased to never attempt deallocation. This is the same
implementation as `Vec<T>`.
Closes#14395
This allows code to access the fields of tuples and tuple structs behind the feature gate `tuple_indexing`:
```rust
#![feature(tuple_indexing)]
let x = (1i, 2i);
assert_eq!(x.1, 2);
struct Point(int, int);
let origin = Point(0, 0);
assert_eq!(origin.0, 0);
assert_eq!(origin.1, 0);
```
Implements [RFC 53](https://github.com/rust-lang/rfcs/blob/master/active/0053-tuple-accessors.md). Closes#16950.
For convenience, the traits are implemented for the respective bare
functions. Change code from this:
```rust
ItemDecorator(some_function)
// or
ItemModifier(some_other_function)
```
to
```rust
ItemDecorator(box some_function)
// or
ItemModifier(box some_other_function)
```
[breaking-change]
Based on an observation that strings and arguments are always interleaved, thanks to #15832. Additionally optimize invocations where formatting parameters are unspecified for all arguments, e.g. `"{} {:?} {:x}"`, by emptying the `__STATIC_FMTARGS` array. Next, `Arguments::new` replaces an empty slice with `None` so that passing empty `__STATIC_FMTARGS` generates slightly less machine code when `Arguments::new` is inlined. Furthermore, formatting itself treats these cases separately without making redundant copies of formatting parameters.
All in all, this adds a single mov instruction per `write!` in most cases. That's why code size has increased.
This allows code to access the fields of tuples and tuple structs:
let x = (1i, 2i);
assert_eq!(x.1, 2);
struct Point(int, int);
let origin = Point(0, 0);
assert_eq!(origin.0, 0);
assert_eq!(origin.1, 0);
The pointer in the slice must not be null, because enum representations
make that assumption. The `exchange_malloc` function returns a non-null
sentinel for the zero size case, and it must not be passed to the
`exchange_free` lang item.
Since the length is always equal to the true capacity, a branch on the
length is enough for most types. Slices of zero size types are
statically special cased to never attempt deallocation. This is the same
implementation as `Vec<T>`.
Closes#14395
instead of prefix `..`.
This breaks code that looked like:
match foo {
[ first, ..middle, last ] => { ... }
}
Change this code to:
match foo {
[ first, middle.., last ] => { ... }
}
RFC #55.
Closes#16967.
[breaking-change]
This breaks code that uses the `..xs` form anywhere but at the end of a
slice. For example:
match foo {
[ 1, ..xs, 2 ]
[ ..xs, 1, 2 ]
}
Add the `#![feature(advanced_slice_patterns)]` gate to reenable the
syntax.
RFC #54.
Closes#16951.
[breaking-change]
itself.
This breaks code like:
for &x in my_vector.iter() {
my_vector[2] = "wibble";
...
}
Change this code to not invalidate iterators. For example:
for i in range(0, my_vector.len()) {
my_vector[2] = "wibble";
...
}
The `for-loop-does-not-borrow-iterators` test for #8372 was incorrect
and has been removed.
Closes#16820.
[breaking-change]
This code used to produce the following ICE:
error: internal compiler error: get_unique_type_id_of_type() -
unexpected type: closure,
ty_unboxed_closure(syntax::ast::DefId{krate: 0u32, node: 66u32},
ReScope(63u32))
This is a regression test for issue #17021.
Closes#16813
r? @nikomatsakis I feel like I should be checking more things in check_rvalues, but not sure what - I don't properly understand expr_use_visitor
This code used to produce an ICE on the definition of trait Bar
with the following message:
Type parameter out of range when substituting in region 'a (root
type=fn(Self) -> 'astr) (space=FnSpace, index=0)
Closes#16218.
This branch adds support for running LLVM optimization and codegen on different parts of a crate in parallel. Instead of translating the crate into a single LLVM compilation unit, `rustc` now distributes items in the crate among several compilation units, and spawns worker threads to optimize and codegen each compilation unit independently. This improves compile times on multicore machines, at the cost of worse performance in the compiled code. The intent is to speed up build times during development without sacrificing too much optimization.
On the machine I tested this on, `librustc` build time with `-O` went from 265 seconds (master branch, single-threaded) to 115s (this branch, with 4 threads), a speedup of 2.3x. For comparison, the build time without `-O` was 90s (single-threaded). Bootstrapping `rustc` using 4 threads gets a 1.6x speedup over the default settings (870s vs. 1380s), and building `librustc` with the resulting stage2 compiler takes 1.3x as long as the master branch (44s vs. 55s, single threaded, ignoring time spent in LLVM codegen).
The user-visible changes from this branch are two new codegen flags:
* `-C codegen-units=N`: Distribute items across `N` compilation units.
* `-C codegen-threads=N`: Spawn `N` worker threads for running optimization and codegen. (It is possible to set `codegen-threads` larger than `codegen-units`, but this is not very useful.)
Internal changes to the compiler are described in detail on the individual commit messages.
Note: The first commit on this branch is copied from #16359, which this branch depends on.
r? @nick29581
- Ensures the propagated negation sign is properly utilized during type
checking.
- Removed redundant type checking, specifically regarding the out of bounds checking
on a bounded type.
- Closes#16684
Use '^' to specify center alignment in format strings.
```
fmt!( "[{:^5s}]", "Hi" ) -> "[ Hi ]"
fmt!( "[{:^5s}]", "H" ) -> "[ H ]"
fmt!( "[{:^5d}]", 1i ) -> "[ 1 ]"
fmt!( "[{:^5d}]", -1i ) -> "[ -1 ]"
fmt!( "[{:^6d}]", 1i ) -> "[ 1 ]"
fmt!( "[{:^6d}]", -1i ) -> "[ -1 ]"
```
If the padding is odd then the padding on the right will be one
character longer than the padding on the left.
Use '^' to specify center alignment in format strings.
fmt!( "[{:^5s}]", "Hi" ) -> "[ Hi ]"
fmt!( "[{:^5s}]", "H" ) -> "[ H ]"
fmt!( "[{:^5d}]", 1i ) -> "[ 1 ]"
fmt!( "[{:^5d}]", -1i ) -> "[ -1 ]"
fmt!( "[{:^6d}]", 1i ) -> "[ 1 ]"
fmt!( "[{:^6d}]", -1i ) -> "[ -1 ]"
If the padding is odd then the padding on the right will be one
character longer than the padding on the left.
Tuples squashed