Implement negative bounds for internal testing purposes
Implements partial support the `!` negative polarity on trait bounds. This is incomplete, but should allow us to at least be able to play with the feature.
Not even gonna consider them as a public-facing feature, but I'm implementing them because would've been nice to have in UI tests, for example in #110671.
Currently a `{D,Subd}iagnosticMessage` can be created from any type that
impls `Into<String>`. That includes `&str`, `String`, and `Cow<'static,
str>`, which are reasonable. It also includes `&String`, which is pretty
weird, and results in many places making unnecessary allocations for
patterns like this:
```
self.fatal(&format!(...))
```
This creates a string with `format!`, takes a reference, passes the
reference to `fatal`, which does an `into()`, which clones the
reference, doing a second allocation. Two allocations for a single
string, bleh.
This commit changes the `From` impls so that you can only create a
`{D,Subd}iagnosticMessage` from `&str`, `String`, or `Cow<'static,
str>`. This requires changing all the places that currently create one
from a `&String`. Most of these are of the `&format!(...)` form
described above; each one removes an unnecessary static `&`, plus an
allocation when executed. There are also a few places where the existing
use of `&String` was more reasonable; these now just use `clone()` at
the call site.
As well as making the code nicer and more efficient, this is a step
towards possibly using `Cow<'static, str>` in
`{D,Subd}iagnosticMessage::{Str,Eager}`. That would require changing
the `From<&'a str>` impls to `From<&'static str>`, which is doable, but
I'm not yet sure if it's worthwhile.
My type ascription
Oh rip it out
Ah
If you think we live too much then
You can sacrifice diagnostics
Don't mix your garbage
Into my syntax
So many weird hacks keep diagnostics alive
Yet I don't even step outside
So many bad diagnostics keep tyasc alive
Yet tyasc doesn't even bother to survive!
This resolves an inconsistency in naming style for functions
on the parser, between functions parsing specific kinds of items
and those for expressions, favoring the parse_item_[sth] style
used by functions for items. There are multiple advantages
of that style:
* functions of both categories are collected in the same place
in the rustdoc output.
* it helps with autocompletion, as you can narrow down your
search for a function to those about expressions.
* it mirrors rust's path syntax where less specific things
come first, then it gets more specific, i.e.
std::collections::hash_map::Entry
The disadvantage is that it doesn't "read like a sentence"
any more, but I think the advantages weigh more greatly.
This change was mostly application of this command:
sed -i -E 's/(fn |\.)parse_([[:alnum:]_]+)_expr/\1parse_expr_\2/' compiler/rustc_parse/src/parser/*.rs
Plus very minor fixes outside of rustc_parse, and an invocation
of x fmt.
`Parser::parse_bottom_expr` currently constructs an empty `attrs` and
then passes it to a large number of other functions. This makes the code
harder to read than it should be, because it's not clear that many
`attrs` arguments are always empty.
This commit removes `attrs` and the passing, simplifying a lot of
functions. The commit also renames `Parser::mk_expr` (which takes an
`attrs` argument) as `mk_expr_with_attrs`, and introduces a new
`mk_expr` which creates an expression with no attributes, which is the
more common case.
Improve parser diagnostics
This pr fixes https://github.com/rust-lang/rust/issues/93867 and contains a couple of diagnostics related changes to the parser.
Here is a short list with some of the changes:
- don't suggest the same thing that is the current token
- suggest removing the current token if the following token is one of the suggestions (maybe incorrect)
- tell the user to put a type or lifetime after where if there is none (as a warning)
- reduce the amount of tokens suggested (via the new eat_noexpect and check_noexpect methods)
If any of these changes are undesirable, i can remove them, thanks!
By heap allocating the argument within `NtPath`, `NtVis`, and `NtStmt`.
This slightly reduces cumulative and peak allocation amounts, most
notably on `deep-vector`.
When encountering an inproperly terminated type parameter list, provide
a suggestion to close it after the last non-constraint type parameter
that was successfully parsed.
Fix#94058.
Let qpath contain NtTy: `<$:ty as $:ty>::…`
Example:
```rust
macro_rules! m {
(<$type:ty as $trait:ty>::$name:ident) => {
<$type as $trait>::$name
};
}
fn main() {
let _: m!(<str as ToOwned>::Owned);
}
```
Previous behavior:
```console
error: expected identifier, found `ToOwned`
--> src/main.rs:3:19
|
3 | <$type as $trait>::$name
| ^^^^^^ expected identifier
...
8 | let _: m!(<str as ToOwned>::Owned);
| ---------------------------
| |
| this macro call doesn't expand to a type
| in this macro invocation
```
The <code>expected identifier, found \`ToOwned\`</code> error is particularly silly. I think it should be fine to accept this code as long as $trait is of the form `TyKind::Path(None, path)`; if it is any other kind of `NtTy`, we'll keep the same behavior as before.
ProjectionPredicate should be able to handle both associated types and consts so this adds the
first step of that. It mainly just pipes types all the way down, not entirely sure how to handle
consts, but hopefully that'll come with time.