Currently the parser will interpret any label/lifetime in certain
positions as a mistyped char literal, on the assumption that the
trailing single quote was accidentally omitted. This is reasonable for a
something like 'a (because 'a' would be valid) but not reasonable for a
something like 'abc (because 'abc' is not valid).
This commit restricts this behaviour only to labels/lifetimes that would
be valid char literals, via the new `could_be_unclosed_char_literal`
function. The commit also augments the `label-is-actually-char.rs` test
in a couple of ways:
- Adds testing of labels/lifetimes with identifiers longer than one
char, e.g. 'abc.
- Adds a new match with simpler patterns, because the
`recover_unclosed_char` call in `parse_pat_with_range_pat` was not
being exercised (in this test or any other ui tests).
Fixes#120397, an assertion failure, which was caused by this behaviour
in the parser interacting with some new stricter char literal checking
added in #120329.
Properly recover from trailing attr in body
When encountering an attribute in a body, we try to recover from an attribute on an expression (as opposed to a statement). We need to properly clean up when the attribute is at the end of the body where a tail expression would be.
Fix#118164, fix#118575.
When encountering an attribute in a body, we try to recover from an
attribute on an expression (as opposed to a statement). We need to
properly clean up when the attribute is at the end of the body where a
tail expression would be.
Fix#118164.
Change the implicit `Sized` `Obligation` `Span` for call expressions to
include the whole expression. This aids the existing deduplication
machinery to reduce the number of errors caused by a single unsized
expression.
Remove special handling of `box` expressions from parser
#108471 added a temporary hack to parse `box expr`. It's been almost a year since then, so I think it's safe to remove the special handling.
As a drive-by cleanup, move `parser/removed-syntax*` tests to their own directory.
Recover parentheses in range patterns
Before:
```rs
match n {
(0).. => (),
_ => ()
}
```
```
error: expected one of `=>`, `if`, or `|`, found `..`
--> src/lib.rs:3:12
|
3 | (0).. => (),
| ^^ expected one of `=>`, `if`, or `|`
```
After:
```
error: range pattern bounds cannot have parentheses
--> main.rs:3:5
|
3 | (0).. => (),
| ^ ^
|
help: remove these parentheses
|
3 - (0).. => (),
3 + 0.. => (),
|
```
This sets the groundwork for #118625, which will extend the recovery to expressions like `(0 + 1)..` where users may tend to add parentheses to avoid dealing with precedence.
---
```@rustbot``` label +A-parser +A-patterns +A-diagnostics
Introduce `const Trait` (always-const trait bounds)
Feature `const_trait_impl` currently lacks a way to express “always const” trait bounds. This makes it impossible to define generic items like fns or structs which contain types that depend on const method calls (\*). While the final design and esp. the syntax of effects / keyword generics isn't set in stone, some version of “always const” trait bounds will very likely form a part of it. Further, their implementation is trivial thanks to the `effects` backbone.
Not sure if this needs t-lang sign-off though.
(\*):
```rs
#![feature(const_trait_impl, effects, generic_const_exprs)]
fn compute<T: const Trait>() -> Type<{ T::generate() }> { /*…*/ }
struct Store<T: const Trait>
where
Type<{ T::generate() }>:,
{
field: Type<{ T::generate() }>,
}
```
Lastly, “always const” trait bounds are a perfect fit for `generic_const_items`.
```rs
#![feature(const_trait_impl, effects, generic_const_items)]
const DEFAULT<T: const Default>: T = T::default();
```
Previously, we (oli, fee1-dead and I) wanted to reinterpret `~const Trait` as `const Trait` in generic const items which would've been quite surprising and not very generalizable.
Supersedes #117530.
---
cc `@oli-obk`
As discussed
r? fee1-dead (or compiler)
Properly reject `default` on free const items
Fixes#117791.
Technically speaking, this is a breaking change but I doubt it will lead to any real-world regressions (maybe in some macro-trickery crates?). Doing a crater run probably isn't worth it.
Add inline const and other possible curly brace expressions to expr_trailing_brace
Add tests for `}` before `else` in `let...else` error
Change to explicit cases for expressions with optional values when being checked for trailing braces
Add tests for more complex cases of `}` before `else` in `let..else` statement
Move other possible `}` cases into separate arm and add FIXME for future reference
Correctly gate the parsing of match arms without body
https://github.com/rust-lang/rust/pull/118527 accidentally allowed the following to parse on stable:
```rust
match Some(0) {
None => { foo(); }
#[cfg(FALSE)]
Some(_)
}
```
This fixes that oversight. The way I choose which error to emit is the best I could think of, I'm open if you know a better way.
r? `@petrochenkov` since you're the one who noticed
Attribute values must be literals. The error you get when that doesn't
hold is pretty bad, e.g.:
```
unexpected expression: 1 + 1
```
You also get the same error if the attribute value is a literal, but an
invalid literal, e.g.:
```
unexpected expression: "foo"suffix
```
This commit does two things.
- Changes the error message to "attribute value must be a literal",
which gives a better idea of what the problem is and how to fix it. It
also no longer prints the invalid expression, because the carets below
highlight it anyway.
- Separates the "not a literal" case from the "invalid literal" case.
Which means invalid literals now get the specific error at the literal
level, rather than at the attribute level.
never_patterns: Parse match arms with no body
Never patterns are meant to signal unreachable cases, and thus don't take bodies:
```rust
let ptr: *const Option<!> = ...;
match *ptr {
None => { foo(); }
Some(!),
}
```
This PR makes rustc accept the above, and enforces that an arm has a body xor is a never pattern. This affects parsing of match arms even with the feature off, so this is delicate. (Plus this is my first non-trivial change to the parser).
~~The last commit is optional; it introduces a bit of churn to allow the new suggestions to be machine-applicable. There may be a better solution? I'm not sure.~~ EDIT: I removed that commit
r? `@compiler-errors`
Tweak unclosed generics errors
Remove unnecessary span label for parse errors that already have a suggestion.
Provide structured suggestion to close generics in more cases.
Because a macro invocation can expand to a never pattern, we can't rule
out a `arm!(),` arm at parse time. Instead we detect that case at
expansion time, if the macro tries to output a pattern followed by `=>`.