They are disallowed because they have different precedence than
expressions. I assume parenthesis in pattern will be soon stabilized and
thus write that as suggestion directly.
(Meanwhile, a couple of parse-fail tests are moved to UI tests so that
the reader can see the new output, and an existing UI test is given a
more evocative name.)
Warn about ignored generic bounds in `for`
This adds a new lint to fix#42181. For consistency and to avoid code duplication, I also moved the existing "bounds in type aliases are ignored" here.
Questions to the reviewer:
* Is it okay to just remove a diagnostic error code like this? Should I instead keep the warning about type aliases where it is? The old code provided a detailed explanation of what's going on when asked, that information is now lost. On the other hand, `span_warn!` seems deprecated (after this patch, it has exactly one user left!).
* Did I miss any syntactic construct that can appear as `for` in the surface syntax? I covered function types (`for<'a> fn(...)`), generic traits (`for <'a> Fn(...)`, can appear both as bounds as as trait objects) and bounds (`for<'a> F: ...`).
* For the sake of backwards compatibility, this adds a warning, not an error. @nikomatsakis suggested an error in https://github.com/rust-lang/rust/issues/42181#issuecomment-306924389, but I feel that can only happen in a new epoch -- right?
Cc @eddyb
Programmers used to working in some other languages (such as Python or
Go) might expect to be able to destructure values with comma-separated
identifiers but no parentheses on the left side of an assignment.
Previously, the first name in such code would get parsed as a
single-indentifier pattern—recognizing, for example, the
`let a` in `let a, b = (1, 2);`—whereupon we would have a fatal syntax
error on seeing an unexpected comma rather than the expected semicolon
(all the way nearer to the end of `parse_full_stmt`).
Instead, let's look for that comma when parsing the pattern, and if we
see it, momentarily make-believe that we're parsing the remaining
elements in a tuple pattern, so that we can suggest wrapping it all in
parentheses. We need to do this in a separate wrapper method called on
the top-level pattern (or `|`-patterns) in a `let` statement, `for`
loop, `if`- or `while let` expression, or match arm rather than within
`parse_pat` itself, because `parse_pat` gets called recursively to parse
the sub-patterns within a tuple pattern.
Resolves#48492.
Also move the check for not having type parameters into ast_validation.
I was not sure what to do with compile-fail/issue-23046.rs: The issue looks like
maybe the bounds actually played a role in triggering the ICE, but that seems
unlikely given that the compiler seems to entirely ignore them. However, I
couldn't find a testcase without the bounds, so I figured the best I could do is
to just remove the bounds and make sure at least that keeps working.
When unnecessarily using a fat arrow after an if condition, suggest the
removal of it.
When finding an if statement with no block, point at the `if` keyword to
provide more context.
When finding:
```rust
match &Some(3) {
&None => 1
&Some(2) => { 3 }
_ => 2
}
```
provide the following diagnostic:
```
error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
--> $DIR/missing-comma-in-match.rs:15:18
|
X | &None => 1
| -- - help: missing comma
| |
| while parsing the match arm starting here
X | &Some(2) => { 3 }
| ^^ expected one of `,`, `.`, `?`, `}`, or an operator here
```
Fix span of visibility
This PR
1. adds a closing parenthesis to the span of `Visibility::Crate` (e.g. `pub(crate)`). The current span only covers `pub(crate`.
2. adds a `span` field to `Visibility::Restricted`. This span covers the entire visibility expression (e.g. `pub (in self)`). Currently all we can have is a span for `Path`.
This PR is motivated by the bug found in rustfmt (https://github.com/rust-lang-nursery/rustfmt/issues/2398).
The first change is a strict improvement IMHO. The second change may not be desirable, as it adds a field which is currently not used by the compiler.
When encountering a variadic argument in a function definition that
doesn't accept it, if immediately after there's a closing paren,
continue parsing as normal. Otherwise keep current behavior of emitting
error and stopping.
Add filtering options to `rustc_on_unimplemented`
- Add filtering options to `rustc_on_unimplemented` for local traits, filtering on `Self` and type arguments.
- Add a way to provide custom notes.
- Tweak binops text.
- Add filter to detect wether `Self` is local or belongs to another crate.
- Add filter to `Iterator` diagnostic for `&str`.
Partly addresses #44755 with a different syntax, as a first approach. Fixes#46216, fixes#37522, CC #34297, #46806.
- filter error on the evaluated value of `Self`
- filter error on the evaluated value of the type arguments
- add argument to include custom note in diagnostic
- allow the parser to parse `Self` when processing attributes
- add custom message to binops
syntax: Lower priority of `+` in `impl Trait`/`dyn Trait`
Now you have to write `Fn() -> (impl A + B)` instead of `Fn() -> impl A + B`, this is consistent with priority of `+` in trait objects (`Fn() -> A + B` means `(Fn() -> A) + B`).
To make this viable I changed the syntax to also permit `+` in return types in function declarations
```
fn f() -> dyn A + B { ... } // OK, don't have to write `-> (dyn A + B)`
// This is acceptable, because `dyn A + B` here is an isolated type and
// not part of a larger type with various operator priorities in play
// like `dyn A + B` in `Fn() -> dyn A + B` despite syntax similarities.
```
but you still have to use `-> (dyn A + B)` in function types and function-like trait object types (see this PR's tests for examples).
This can be a breaking change for code using `impl Trait` on nightly. The thing that is most likely to break is `&impl A + B`, it needs to be rewritten as `&(impl A + B)`.
cc https://github.com/rust-lang/rust/issues/34511https://github.com/rust-lang/rust/issues/44662https://github.com/rust-lang/rfcs/pull/438
Correctly format `extern crate` conflict resolution help
Closes#45799. Follow up to @Cldfire's #45820.
If the `extern` statement that will have a suggestion ends on a `;`, synthesize a new span that doesn't include it.
Avoid overlapping spans by only pointing at the arguments that are not
being used in the argument string. Enable libsyntax to have diagnostics
with multiple primary spans by accepting `Into<MultiSpan>` instead of
`Span`.
Properly parse impls for the never type `!`
Recover from missing `for` in `impl Trait for Type`
Prohibit inherent default impls and default impls of auto traits
Change wording in more diagnostics to use "auto traits"
Some minor code cleanups in the parser
No longer parse it.
Remove AutoTrait variant from AST and HIR.
Remove backwards compatibility lint.
Remove coherence checks, they make no sense for the new syntax.
Remove from rustdoc.
`struct` pattern parsing and diagnostic tweaks
- Recover from struct parse error on match and point out missing match
body.
- Point at struct when finding non-identifier while parsing its fields.
- Add label to "expected identifier, found {}" error.
Fix#15980.
Treat #[path] files as mod.rs files
Fixes https://github.com/rust-lang/rust/issues/46936, cc @briansmith, @SergioBenitez, @nikomatsakis.
This (insta-stable) change treats files included via `#[path = "bla.rs"] mod foo;` as though they were `mod.rs` files. Namely, it allows them to include `mod` statements and looks for the child modules in sibling directories, rather than in relative `modname/childmodule.rs` files as happens for non-`mod.rs` files.
This change makes the `non_modrs_mods` feature backwards compatible with the existing usage in https://github.com/briansmith/ring, several versions of which are currently broken in beta. If we decide to merge, this change should be backported to beta.
cc https://github.com/rust-lang/rust/issues/37872
r? @jseyfried
Add help message for incorrect pattern syntax
When I was getting started with rust I often made the mistake of using `||` instead of `|` to match multiple patterns and spent a long time staring at my code wondering what was wrong.
for example:
```
fn main() {
let x = 1;
match x {
1 || 2 => println!("1 or 2"),
_ => println!("Something else"),
}
}
```
If you compile this with current rustc you will see
```
error: expected one of `...`, `..=`, `..`, `=>`, `if`, or `|`, found `||`
--> test.rs:5:11
|
5 | 1 || 2 => println!("1 or 2"),
| -^^ unexpected token
| |
| expected one of `...`, `..=`, `..`, `=>`, `if`, or `|` here
error: aborting due to previous error
```
With my proposed change it will show:
```
error: unexpected token `||` after pattern
--> test.rs:5:11
|
5 | 1 || 2 => println!("1 or 2"),
| ^^
|
= help: did you mean to use `|` to specify multiple patterns instead?
error: aborting due to previous error
```
- Recover from struct parse error on match and point out missing match
body.
- Point at struct when finding non-identifier while parsing its fields.
- Add label to "expected identifier, found {}" error.
Allow lifetimes in macros
This is a resurrection of PR #41927 which was a resurrection of #33135, which is intended to fix#34303.
In short, this allows macros_rules! to use :lifetime as a matcher to match 'lifetimes.
Still to do:
- [x] Feature gate
Do not emit type errors on recovered blocks
When a parse error occurs on a block, the parser will recover and create
a block with the statements collected until that point. Now a flag
stating that a recovery has been performed in this block is propagated
so that the type checker knows that the type of the block (which will be
identified as `()`) shouldn't be checked against the expectation to
reduce the amount of irrelevant diagnostic errors shown to the user.
Fix#44579.
When a parse error occurs on a block, the parser will recover and create
a block with the statements collected until that point. Now a flag
stating that a recovery has been performed in this block is propagated
so that the type checker knows that the type of the block (which will be
identified as `()`) shouldn't be checked against the expectation to
reduce the amount of irrelevant diagnostic errors shown to the user.
Generics refactoring (groundwork for const generics)
These changes were suggested by @eddyb.
After this change, the `Generics` contain one `Vec` of an enum for the generic parameters, rather than two separate `Vec`s for lifetime and type parameters. Type params and const params will need to be in a shared `Vec` to preserve their ordering, and moving lifetimes into the same `Vec` should simplify the code that processes `Generics`.
The Generics now contain one Vec of an enum for the generic parameters,
rather than two separate Vec's for lifetime and type parameters.
Additionally, places that previously used Vec<LifetimeDef> now use
Vec<GenericParam> instead.
syntax: Follow-up to the incorrect qpath recovery PR
cc https://github.com/rust-lang/rust/pull/46788
Add tests checking that "priority" of qpath recovery is higher than priority of unary and binary operators
Fix regressed parsing of paths with fn-like generic arguments
r? @estebank
Implement non-mod.rs mod statements
Fixes https://github.com/rust-lang/rust/issues/45385, cc https://github.com/rust-lang/rust/issues/44660
This will fail tidy right now because it doesn't recognize my UI tests as feature-gate tests. However, I'm not sure if compile-fail will work out either because compile-fail usually requires there to be error patterns in the top-level file, which isn't possible with this feature. What's the recommended way to handle this?
Generic Associated Types Parsing & Name Resolution
Hi!
This PR adds parsing for generic associated types! 🎉🎉🎉
Tracking Issue: #44265
## Notes For Reviewers
* [x] I still need to add the stdout and stderr files to my ui tests. It takes me a *long* time to compile the compiler locally, so I'm going to add this as soon as possible in the next day or so.
* [ ] My current ui tests aren't very good or very thorough. I'm reusing the `parse_generics` and `parse_where_clause` methods from elsewhere in the parser, so my changes work without being particularly complex. I'm not sure if I should duplicate all of the generics test cases for generic associated types. It might actually be appropriate to duplicate everything here, since we don't want to rely on an implementation detail in case it changes in the future. If you think so too, I'll adapt all of the generics test cases into the generic associated types test cases.
* [ ] There is still more work required to make the run-pass tests pass here. In particular, we need to make the following errors disappear:
```
error[E0110]: lifetime parameters are not allowed on this type
--> ./src/test/run-pass/rfc1598-generic-associated-types/streaming_iterator.rs:23:41
|
23 | bar: <T as StreamingIterator>::Item<'static>,
| ^^^^^^^ lifetime parameter not allowed on this type
```
```
error[E0261]: use of undeclared lifetime name `'a`
--> ./src/test/run-pass/rfc1598-generic-associated-types/iterable.rs:15:47
|
15 | type Iter<'a>: Iterator<Item = Self::Item<'a>>;
| ^^ undeclared lifetime
```
There is a FIXME comment in streaming_iterator. If you uncomment that line, you get the following:
```
error: expected one of `!`, `+`, `,`, `::`, or `>`, found `=`
--> ./src/test/run-pass/rfc1598-generic-associated-types/streaming_iterator.rs:29:45
|
29 | fn foo<T: for<'a> StreamingIterator<Item<'a>=&'a [i32]>>(iter: T) { /* ... */ }
| ^ expected one of `!`, `+`, `,`, `::`, or `>` here
```
r? @nikomatsakis
When encountering `pub ident`, attempt to identify the code that comes
afterwards, wether it is a brace block (assume it is a struct), a paren
list followed by a colon (assume struct) or a paren list followed by a
block (assume a fn). Consume those blocks to avoid any further parser
errors and return a `Placeholder` item in order to allow the parser to
continue. In the case of unenclosed blocks, the behavior is the same as
it is currently: no further errors are processed.
Add error for `...` in expressions
Follow-up to https://github.com/rust-lang/rust/pull/44709
Tracking issue: https://github.com/rust-lang/rust/issues/28237
* Using `...` in expressions was a warning, now it's an error
* The error message suggests using `..` or `..=` instead, and explains the difference
* Updated remaining occurrences of `...` to `..=`
r? petrochenkov
Detect `=` -> `:` typo in let bindings
When encountering a let binding type error, attempt to parse as
initializer instead. If successful, it is likely just a typo:
```rust
fn main() {
let x: Vec::with_capacity(10);
}
```
```
error: expected type, found `10`
--> file.rs:3:31
|
3 | let x: Vec::with_capacity(10, 20);
| -- ^^
| ||
| |help: did you mean assign here?: `=`
| while parsing the type for `x`
```
Fix#43703.
Add a nicer error message for missing in for loop, fixes#40782.
As suggested by @estebank in issue #40782, this works in the same way as #42578: if the in keyword is missing, we continue parsing the expression and if this works correctly an adapted error message is produced. Otherwise we return the old error.
A specific test case has also been added.
This is my first PR on rust-lang/rust so any feedback is very welcome.
When encountering a let binding type error, attempt to parse as
initializer instead. If successful, it is likely just a typo:
```rust
fn main() {
let x: Vec::with_capacity(10);
}
```
```
error: expected type, found `10`
--> file.rs:3:31
|
3 | let x: Vec::with_capacity(10, 20);
| -- ^^
| ||
| |help: did you mean assign here?: `=`
| while parsing the type for `x`
```
DefaultImpl is a highly confusing name for what we now call auto impls,
as in `impl Send for ..`. The name auto impl is not formally decided
but for sanity anything is better than `DefaultImpl` which refers
neither to `default impl` nor to `impl Default`.
Implement RFC 1861: Extern types
A few notes :
- Type parameters are not supported. This was an unresolved question from the RFC. It is not clear how useful this feature is, and how variance should be treated. This can be added in a future PR.
- `size_of_val` / `align_of_val` can be called with extern types, and respectively return 0 and 1. This differs from the RFC, which specified that they should panic, but after discussion with @eddyb on IRC this seems like a better solution.
If/when a `DynSized` trait is added, this will be disallowed statically.
- Auto traits are not implemented by default, since the contents of extern types is unknown. This means extern types are `!Sync`, `!Send` and `!Freeze`. This seems like the correct behaviour to me.
Manual `unsafe impl Sync for Foo` is still possible.
- This PR allows extern type to be used as the tail of a struct, as described by the RFC :
```rust
extern {
type OpaqueTail;
}
#[repr(C)]
struct FfiStruct {
data: u8,
more_data: u32,
tail: OpaqueTail,
}
```
However this is undesirable, as the alignment of `tail` is unknown (the current PR assumes an alignment of 1). Unfortunately we can't prevent it in the general case as the tail could be a type parameter :
```rust
#[repr(C)]
struct FfiStruct<T: ?Sized> {
data: u8,
more_data: u32,
tail: T,
}
```
Adding a `DynSized` trait would solve this as well, by requiring tail fields to be bound by it.
- Despite being unsized, pointers to extern types are thin and can be casted from/to integers. However it is not possible to write a `null<T>() -> *const T` function which works with extern types, as I've explained here : https://github.com/rust-lang/rust/issues/43467#issuecomment-321678621
- Trait objects cannot be built from extern types. I intend to support it eventually, although how this interacts with `DynSized`/`size_of_val` is still unclear.
- The definition of `c_void` is unmodified
Improve diagnostics when list of tokens has incorrect separators
Make `parse_seq_to_before_tokens` more resilient to error conditions. Where possible it is better if it can consume up to the final bracket before returning. This change improves the diagnostics in a couple of situations:
```
struct S(pub () ()); // omitted separator
use std::{foo. bar}; // used a similar but wrong separator
```
Fixes#44339
r? @petrochenkov
While an inner attribute here is in fact erroneous, that error ("inner
attribute is not permitted in this context") successfully gets set earlier;
this further admonition is nonsensical.
Resolves#45296.
Better error message for comma after base struct
#41834
This adds a better error for commas after the base struct:
```
let foo = Foo {
one: 111,
..Foo::default(), // This comma is a syntax error
};
```
The current error is a generic `expected one of ...` which isn't beginner-friendly. My error looks like this:
```
error: cannot use a comma after the base struct
--> tmp/example.rs:26:9
|
26 | ..Foo::default(),
| ^^^^^^^^^^^^^^^^- help: remove this comma
|
= note: the base struct expansion must always be the last field
```
I even added a note for people who don't know why this isn't allowed.
Initial support for `..=` syntax
#28237
This PR adds `..=` as a synonym for `...` in patterns and expressions.
Since `...` in expressions was never stable, we now issue a warning.
cc @durka
r? @aturon
Add ..= to the parser
Add ..= to libproc_macro
Add ..= to ICH
Highlight ..= in rustdoc
Update impl Debug for RangeInclusive to ..=
Replace `...` to `..=` in range docs
Make the dotdoteq warning point to the ...
Add warning for ... in expressions
Updated more tests to the ..= syntax
Updated even more tests to the ..= syntax
Updated the inclusive_range entry in unstable book
Parse nested closure with two consecutive parameter lists properly
This is a followup of #44332.
---
Currently, in nightly, this does not compile:
```rust
fn main() {
let f = |_||x, y| x+y;
println!("{}", f(())(1, 2)); // should print 3
}
```
`|_||x, y| x+y` should be parsed as `|_| (|x, y| x+y)`, but the parser didn't accept `||` between `_` and `x`. This patch fixes the problem.
r? @petrochenkov
Point out missing if conditional
On a case where an else conditional is missing, point this out
instead of the token immediately after the (incorrect) else block:
```
error: missing condition for `if` statemementt push fork -f
--> $DIR/issue-13483.rs:16:5
|
13 | } else if {
| ^ expected if condition here
```
instead of
```
error: expected `{`, found `else`
--> ../../src/test/ui/issue-13483.rs:14:7
|
14 | } else {
| ^^^^
```
Fix#13483.
syntax: Relax path grammar
TLDR: Accept the disambiguator `::` in "type" paths (`Type::<Args>`), accept the disambiguator `::` before parenthesized generic arguments (`Fn::(Args)`).
The "turbofish" disambiguator `::<>` in expression paths is a necessary evil required for path parsing to be both simple and to give reasonable results.
Since paths in expressions usually refer to values (but not necessarily, e.g. `Struct::<u8> { field: 0 }` is disambiguated, but refers to a type), people often consider `::<>` to be inherent to *values*, and not *expressions* and want to write disambiguated paths for values even in contexts where disambiguation is not strictly necessary, for example when a path is passed to a macro `m!(Vec::<i32>::new)`.
The problem is that currently, if the disambiguator is not *required*, then it's *prohibited*. This results in confusion - see https://github.com/rust-lang/rust/issues/41740, https://internals.rust-lang.org/t/macro-path-uses-novel-syntax/5561.
This PR makes the disambiguator *optional* instead of prohibited in contexts where it's not strictly required, so people can pass paths to macros in whatever form they consider natural (e.g. disambiguated form for value paths).
This PR also accepts the disambiguator in paths with parenthesized arguments (`Fn::(Args)`) for consistency and to simplify testing of stuff like https://github.com/rust-lang/rust/pull/41856#issuecomment-301219194.
Closes https://github.com/rust-lang/rust/issues/41740
cc @rust-lang/lang
r? @nikomatsakis
On a case where an else conditional is missing, point this out
instead of the token immediately after the (incorrect) else block:
```
error: missing condition for `if` statemementt push fork -f
--> $DIR/issue-13483.rs:16:5
|
13 | } else if {
| ^ expected if condition here
```
instead of
```
error: expected `{`, found `else`
--> ../../src/test/ui/issue-13483.rs:14:7
|
14 | } else {
| ^^^^
```
Add Span to ast::WhereClause
This PR adds `Span` field to `ast::WhereClause`. The motivation here is to make rustfmt's life easier when recovering comments before and after where clause.
r? @nrc
This is then later used by `proc_macro` to generate a new
`proc_macro::TokenTree` which preserves span information. Unfortunately this
isn't a bullet-proof approach as it doesn't handle the case when there's still
other attributes on the item, especially inner attributes.
Despite this the intention here is to solve the primary use case for procedural
attributes, attached to functions as outer attributes, likely bare. In this
situation we should be able to now yield a lossless stream of tokens to preserve
span information.
This commit adds a new field to the `Item` AST node in libsyntax to optionally
contain the original token stream that the item itself was parsed from. This is
currently `None` everywhere but is intended for use later with procedural
macros.