Fix syntax error in the compiler
Currently `rustc` accepts the following code: `fn f<'a>() where 'a {}`. This should be a syntax error, shouldn't it?
Not sure if my changes actually compile, waiting for the LLVM to build.
On fmt string with unescaped `{` note how to escape
On cases of malformed format strings where a `{` hasn't been properly escaped, like `println!("{");`, present a NOTE explaining how to escape the `{` char.
Fix#34300.
Add foreign formatting directive detection.
This teaches `format_args!` how to interpret format printf- and
shell-style format directives. This is used in cases where there are
unused formatting arguments, and the reason for that *might* be because
the programmer is trying to use the wrong kind of formatting string.
This was prompted by an issue encountered by simulacrum on the #rust IRC
channel. In short: although `println!` told them that they weren't using
all of the conversion arguments, the problem was in using printf-syle
directives rather than ones `println!` would undertand.
Where possible, `format_args!` will tell the programmer what they should
use instead. For example, it will suggest replacing `%05d` with `{:0>5}`,
or `%2$.*3$s` with `{1:.3$}`. Even if it cannot suggest a replacement,
it will explicitly note that Rust does not support that style of directive,
and direct the user to the `std::fmt` documentation.
-----
**Example**: given:
```rust
fn main() {
println!("%.*3$s %s!\n", "Hello,", "World", 4);
println!("%1$*2$.*3$f", 123.456);
}
```
The compiler outputs the following:
```text
error: multiple unused formatting arguments
--> local/fmt.rs:2:5
|
2 | println!("%.*3$s %s!\n", "Hello,", "World", 4);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: argument never used
--> local/fmt.rs:2:30
|
2 | println!("%.*3$s %s!\n", "Hello,", "World", 4);
| ^^^^^^^^
note: argument never used
--> local/fmt.rs:2:40
|
2 | println!("%.*3$s %s!\n", "Hello,", "World", 4);
| ^^^^^^^
note: argument never used
--> local/fmt.rs:2:49
|
2 | println!("%.*3$s %s!\n", "Hello,", "World", 4);
| ^
= help: `%.*3$s` should be written as `{:.2$}`
= help: `%s` should be written as `{}`
= note: printf formatting not supported; see the documentation for `std::fmt`
= note: this error originates in a macro outside of the current crate
error: argument never used
--> local/fmt.rs:6:29
|
6 | println!("%1$*2$.*3$f", 123.456);
| ^^^^^^^
|
= help: `%1$*2$.*3$f` should be written as `{0:1$.2$}`
= note: printf formatting not supported; see the documentation for `std::fmt`
```
Move all Linux/OSX CI infastructure to Travis
This commit configures our `.travis.yml` to test the full suite of tests we have
on Buildbot right now. A whole mess of docker images are added to the `src/ci`
directory which represent all the build environments for each configuration.
Each of these environments is then configured in `.travis.yml` to run on the
auto branch.
Note that the full matrix of tests aren't intended to be run on all PRs.
Instead, we continue to run only one entry in the matrix, forcing all others to
finish quickly. Only the `auto` branch should run the full matrix of builds.
Also note that the infrastructure hasn't quite been allocated yet to the
rust-lang/rust repository, so everything is disabled for now except for the one
build that happens on PRs. Once that infrastructure is allocated though we can
enable this and let it fly!
Notable modifications from the current test suite today:
* Android tests are run in rustbuild instead of the makefiles, for whatever
reason I couldn't get the makefiles to work on Travis.
* A debuginfo test was updated to work with the current version of the Android
NDK.
* Some dependencies in `mk/tests.mk` were fixed to allow running tests in
parallel.
Don't provide hint to add lifetime on impl items
``` rust
use std::str::FromStr;
pub struct Foo<'a> {
field: &'a str,
}
impl<'a> FromStr for Foo<'a> {
type Err = ();
fn from_str(path: &str) -> Result<Self, ()> {
Ok(Foo { field: path })
}
}
```
would give the following hint:
``` nocode
help: consider using an explicit lifetime parameter as shown: fn from_str(path: &'a str) -> Result<Self, ()>
--> <anon>:9:5
|
9 | fn from_str(path: &str) -> Result<Self, ()> {
| ^
```
which is never correct, since then there will be a lifetime mismatch between the `impl` and the trait.
Remove this hint for all `impl` items.
Re: #37363.
rustdoc: add line breaks to where clauses a la rustfmt
Much like my last PR for rustdoc (#36679), this adds line breaks to certain statements based on their line length. Here the focus was on where clauses.
Some examples:
- [Where clause in a trait function](https://shiva.icesoldier.me/custom-std/std/iter/trait.Iterator.html?search=#method.unzip) (also in the trait header block at the top of the page)
- [Where clause on a bare function](https://shiva.icesoldier.me/doc-custom2/petgraph/visit/fn.depth_first_search.html)
- [Where clauses in trait impls on a struct](https://shiva.icesoldier.me/custom-std/std/collections/struct.HashMap.html) (scroll to the bottom) These are regularly not on their own line, but will be given their own line now if their "prefix text" doesn't give them enough room to sensibly print their constraints. HashMap's trait impls provide some examples of both behaviors.
The libstd links above are the whole docs rendered with this, and the "bare function" link above is in another set that pulls some notable crates together. `petgraph` was the one that brought this request up, and that collection also includes [itertools](https://shiva.icesoldier.me/doc-custom2/itertools/trait.Itertools.html) which provided an easy sample to test with.
r? @GuillaumeGomez
On cases of malformed format strings where a `{` hasn't been properly
escaped, like `println!("{");`, present a note explaining how to escape
the `{` char.
Group unused import warnings per import list
Given a file
``` rust
use std::collections::{BinaryHeap, BTreeMap, BTreeSet};
fn main() {}
```
Show a single warning, instead of three for each unused import:
``` nocode
warning: unused imports, #[warn(unused_imports)] on by default
--> file2.rs:1:24
|
1 | use std::collections::{BinaryHeap, BTreeMap, BTreeSet};
| ^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^
```
Include support for lints pointing at `MultilineSpan`s, instead of just
`Span`s.
Fixes#16132.
This commit configures our `.travis.yml` to test the full suite of tests we have
on Buildbot right now. A whole mess of docker images are added to the `src/ci`
directory which represent all the build environments for each configuration.
Each of these environments is then configured in `.travis.yml` to run on the
auto branch.
Note that the full matrix of tests aren't intended to be run on all PRs.
Instead, we continue to run only one entry in the matrix, forcing all others to
finish quickly. Only the `auto` branch should run the full matrix of builds.
Also note that the infrastructure hasn't quite been allocated yet to the
rust-lang/rust repository, so everything is disabled for now except for the one
build that happens on PRs. Once that infrastructure is allocated though we can
enable this and let it fly!
Notable modifications from the current test suite today:
* Android tests are run in rustbuild instead of the makefiles, for whatever
reason I couldn't get the makefiles to work on Travis.
* A debuginfo test was updated to work with the current version of the Android
NDK.
* Some dependencies in `mk/tests.mk` were fixed to allow running tests in
parallel.
Show one error for duplicated type definitions
For the following code:
``` rustc
struct Bar;
struct Bar;
fn main () {
}
```
show
``` nocode
error[E0428]: a type named `Bar` has already been defined in this module
--> src/test/compile-fail/E0428.rs:12:1
|
11 | struct Bar;
| ----------- previous definition of `Bar` here
12 | struct Bar;
| ^^^^^^^^^^^
error: aborting due to previous error
```
instead of
``` nocode
error[E0428]: a type named `Bar` has already been defined in this module
--> src/test/compile-fail/E0428.rs:12:1
|
11 | struct Bar;
| ----------- previous definition of `Bar` here
12 | struct Bar;
| ^^^^^^^^^^^
error[E0428]: a value named `Bar` has already been defined in this module
--> src/test/compile-fail/E0428.rs:12:1
|
11 | struct Bar;
| ----------- previous definition of `Bar` here
12 | struct Bar;
| ^^^^^^^^^^^
error: aborting due to 2 previous errors
```
Fixes#35767.
Don't spin expanding stmt macros.
If we can't make progress when parsing a macro expansion as a statement then we should just bail.
This alleviates the symptoms shown in e.g. #37113 and #37234 but it doesn't fix the problem that parsing invalid enum bodies (and others) leaves the parser in a crappy state.
I'm not sold on this strategy (checking `tokens_consumed`), so if anyone has a better idea, I'm all ears!
Make E0243/E0244 message consistent with E0107
E0243/E0233 prints `expected {}, found {}` on the span note, while E0107 prints it on the first line. This is confusing when both error occur simultaneously.
This PR makes E0243/E0233 print `expected {}, found {}` on the first line.
Code:
``` rust
struct Foo<'a, 'b> {
s: &'a str,
t: &'b str,
}
type Bar<T, U> = Foo<T, U>;
```
rustc output (before):
```
error[E0107]: wrong number of lifetime parameters: expected 2, found 0
--> test.rs:6:18
|
6 | type Bar<T, U> = Foo<T, U>;
| ^^^^^^^^^ expected 2 lifetime parameters
error[E0244]: wrong number of type arguments
--> test.rs:6:18
|
6 | type Bar<T, U> = Foo<T, U>;
| ^^^^^^^^^ expected no type arguments, found 2
```
rustc output (after):
```
error[E0107]: wrong number of lifetime parameters: expected 2, found 0
--> /tmp/test.rs:6:18
|
6 | type Bar<T, U> = Foo<T, U>;
| ^^^^^^^^^ expected 2 lifetime parameters
error[E0244]: wrong number of type arguments: expected 0, found 2
--> /tmp/test.rs:6:18
|
6 | type Bar<T, U> = Foo<T, U>;
| ^^^^^^^^^ expected no type arguments
```
This teaches `format_args!` how to interpret format printf- and
shell-style format directives. This is used in cases where there are
unused formatting arguments, and the reason for that *might* be because
the programmer is trying to use the wrong kind of formatting string.
This was prompted by an issue encountered by simulacrum on the #rust IRC
channel. In short: although `println!` told them that they weren't using
all of the conversion arguments, the problem was in using printf-syle
directives rather than ones `println!` would undertand.
Where possible, `format_args!` will tell the programmer what they should
use instead. For example, it will suggest replacing `%05d` with `{:0>5}`,
or `%2$.*3$s` with `{1:.3$}`. Even if it cannot suggest a replacement,
it will explicitly note that Rust does not support that style of directive,
and direct the user to the `std::fmt` documentation.
Don't provide hint to add lifetime on impl items that implement a trait.
```rust
use std::str::FromStr;
pub struct Foo<'a> {
field: &'a str,
}
impl<'a> FromStr for Foo<'a> {
type Err = ();
fn from_str(path: &str) -> Result<Self, ()> {
Ok(Foo { field: path })
}
}
```
would give the following hint:
```nocode
help: consider using an explicit lifetime parameter as shown: fn from_str(path: &'a str) -> Result<Self, ()>
--> <anon>:9:5
|
9 | fn from_str(path: &str) -> Result<Self, ()> {
| ^
```
which is never correct, since then there will be a lifetime mismatch
between the impl and the trait.
Remove this hint for impl items that implement a trait.
Fix regression involving custom derives on items with `$crate`
The regression was introduced in #37213.
I believe we cannot make the improvements from #37213 work with the current custom derive setup (c.f. https://github.com/rust-lang/rust/issues/37637#issuecomment-258959145) -- we'll have to wait for `TokenStream`'s API to improve.
Fixes#37637.
r? @nrc
For the following code:
```rustc
struct Bar;
struct Bar;
fn main () {
}
```
show
```nocode
error[E0428]: a type named `Bar` has already been defined in this module
--> src/test/compile-fail/E0428.rs:12:1
|
11 | struct Bar;
| ----------- previous definition of `Bar` here
12 | struct Bar;
| ^^^^^^^^^^^
error: aborting due to previous error
```
instead of
```nocode
error[E0428]: a type named `Bar` has already been defined in this module
--> src/test/compile-fail/E0428.rs:12:1
|
11 | struct Bar;
| ----------- previous definition of `Bar` here
12 | struct Bar;
| ^^^^^^^^^^^
error[E0428]: a value named `Bar` has already been defined in this module
--> src/test/compile-fail/E0428.rs:12:1
|
11 | struct Bar;
| ----------- previous definition of `Bar` here
12 | struct Bar;
| ^^^^^^^^^^^
error: aborting due to 2 previous errors
```
_match: correct max_slice_length logic
The logic used to be wildly wrong, but before the HAIR patch its wrongness was in most cases hidden by another bug.
Fixes#37598.
r? @nikomatsakis
macros 1.1: Allow proc_macro functions to declare attributes to be mark as used
This PR allows proc macro functions to declare attribute names that should be marked as used when attached to the deriving item. There are a few questions for this PR.
- Currently this uses a separate attribute named `#[proc_macro_attributes(..)]`, is this the best choice?
- In order to make this work, the `check_attribute` function had to be modified to not error on attributes marked as used. This is a pretty large change in semantics, is there a better way to do this?
- I've got a few clones where I don't know if I need them (like turning `item` into a `TokenStream`), can these be avoided?
- Is switching to `MultiItemDecorator` the right thing here?
Also fixes https://github.com/rust-lang/rust/issues/37563.
Point to type argument span when used as trait
Given the following code:
``` rust
struct Foo<T: Clone>(T);
use std::ops::Add;
impl<T: Clone, Add> Add for Foo<T> {
type Output = usize;
fn add(self, rhs: Self) -> Self::Output {
unimplemented!();
}
}
```
present the following output:
``` nocode
error[E0404]: `Add` is not a trait
--> file3.rs:5:21
|
5 | impl<T: Clone, Add> Add for Okok<T> {
| --- ^^^ expected trait, found type parameter
| |
| type parameter defined here
```
Fixes#35987.
Include type of missing trait methods in error
Provide either a span pointing to the original definition of missing
trait items, or a message with the inferred definitions.
Fixes#24626. Follow up to PR #36371.
If PR #37369 lands, missing trait items that present a multiline span will be able to show the entirety of the item definition on the error itself, instead of just the first line.
Partially stabilize RFC 1506 "Clarify relationships between ADTs"
Lifted restrictions on tuple structs/variants are stabilized, i.e. `S{..}` can be used with any structs and empty tuple structs are permitted without feature gate.
Numeric fields in struct expressions/patterns `S { 0: a, 1: b }` are **NOT** stabilized.
This was implemented 1.5 months ago in Rust 1.12, but this is a tiny technical change that could probably go even without RFC/stabilization period.
cc https://github.com/rust-lang/rust/issues/35626https://github.com/rust-lang/rust/pull/36871
r? @nikomatsakis
Reword error when data-less enum variant called as function
Given a file like:
``` rust
enum Test {
Variant,
Variant2 {a: u32},
}
fn main(){
let x = Test::Variant("Hello");
let y = Test::Variant2("World");
}
```
Both errors now look similar:
``` bash
error[E0423]: `Test::Variant2` is the name of a struct or struct variant, but this expression uses it like a function name
--> file3.rs:10:13
|
10 | let y = Test::Variant2("Hello");
| ^^^^^^^^^^^^^^ struct called like a function
|
= help: did you mean to write: `Test::Variant2 { /* fields */ }`?
error: `Test::Variant` is the name of a data-less enum, but this expression uses it like a function name
--> file3.rs:9:13
|
9 | let x = Test::Variant("World");
| ^^^^^^^^^^^^^^^^^^^^^^ data-less enum called like a function
|
= help: did you mean to write: `Test::Variant`?
note: defined here
--> file3.rs:2:5
|
2 | Variant,
| ^^^^^^^
error: aborting due to previous error
```
Re: #28533
Given a file
```rust
use std::collections::{BinaryHeap, BTreeMap, BTreeSet};
fn main() {}
```
Show a single warning, instead of three for each unused import:
```nocode
warning: unused imports, #[warn(unused_imports)] on by default
--> foo.rs:1:24
|
1 | use std::collections::{BinaryHeap, BTreeMap, BTreeSet};
| ^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^
```
Include support for lints pointing at `MultilineSpan`s, instead of just
`Span`s.
Given the following code:
```rust
struct Foo<T: Clone>(T);
use std::ops::Add;
impl<T: Clone, Add> Add for Foo<T> {
type Output = usize;
fn add(self, rhs: Self) -> Self::Output {
unimplemented!();
}
}
```
present the following output:
```nocode
error[E0404]: `Add` is not a trait
--> file3.rs:5:21
|
5 | impl<T: Clone, Add> Add for Okok<T> {
| --- ^^^ expected trait, found type parameter
| |
| type parameter defined here
```