Commit Graph

152 Commits

Author SHA1 Message Date
Nicholas Nethercote
84ac80f192 Reformat use declarations.
The previous commit updated `rustfmt.toml` appropriately. This commit is
the outcome of running `x fmt --all` with the new formatting options.
2024-07-29 08:26:52 +10:00
Nicholas Nethercote
4158a1c48f Only check force_collect in collect_tokens_trailing_token.
There are three places where we currently check `force_collect` and call
`collect_tokens_no_attrs` for `ForceCollect::Yes` and a vanilla parsing
function for `ForceCollect::No`.

But we can instead just pass in `force_collect` and let
`collect_tokens_trailing_token` do the appropriate thing.
2024-07-19 08:42:33 +10:00
Nicholas Nethercote
7d7e2a173a Don't always force collect tokens in recover_stmt_local_after_let.
Use a parameter to decide whether to force collect, as is done for the
closely related `parse_local_mk` method.
2024-07-19 08:24:53 +10:00
Nicholas Nethercote
487802d6c8 Remove TrailingToken.
It's used in `Parser::collect_tokens_trailing_token` to decide whether
to capture a trailing token. But the callers actually know whether to
capture a trailing token, so it's simpler for them to just pass in a
bool.

Also, the `TrailingToken::Gt` case was weird, because it didn't result
in a trailing token being captured. It could have been subsumed by the
`TrailingToken::MaybeComma` case, and it effectively is in the new code.
2024-07-18 17:28:49 +10:00
Trevor Gross
fa1303662a
Rollup merge of #127806 - nnethercote:parser-improvements, r=spastorino
Some parser improvements

I was looking closely at attribute handling in the parser while debugging some issues relating to #124141, and found a few small improvements.

``@spastorino``
2024-07-17 19:53:27 -05:00
Nicholas Nethercote
d247489ac2 Reorder Parser::parse_expr_dot_or_call_with arguments.
Put `attrs` before `e0` because that matches the order in the source
code, where outer attributes appear before expressions.
2024-07-16 15:54:34 +10:00
Esteban Küber
692bc344d5 Make parse error suggestions verbose and fix spans
Go over all structured parser suggestions and make them verbose style.

When suggesting to add or remove delimiters, turn them into multiple suggestion parts.
2024-07-12 03:02:57 +00:00
Nicholas Nethercote
8170acb197 Refactor parse_expr_res.
This removes the final `Option<AttrWrapper>` argument.
2024-06-19 19:12:02 +10:00
Nicholas Nethercote
25523ba382 Refactor LhsExpr.
Combine `NotYetParsed` and `AttributesParsed` into a single variant,
because (a) that reflects the structure of the code that consumes
`LhsExpr`, and (b) because that variant will have the `Option` removed
in a later commit.
2024-06-19 18:53:25 +10:00
Nicholas Nethercote
95b4c07ef8 Reduce pub exposure. 2024-06-06 08:26:54 +10:00
León Orell Valerian Liehr
5b485f04de
Rollup merge of #125049 - dtolnay:castbrace, r=compiler-errors
Disallow cast with trailing braced macro in let-else

This fixes an edge case I noticed while porting #118880 and #119062 to syn.

Previously, rustc incorrectly accepted code such as:

```rust
let foo = &std::ptr::null as &'static dyn std::ops::Fn() -> *const primitive! {
    8
} else {
    return;
};
```

even though a right curl brace `}` directly before `else` in a `let...else` statement is not supposed to be valid syntax.
2024-05-22 19:04:44 +02:00
ardi
1f6d271527 Clarify that the diff_marker is talking about version control system
conflicts specifically and a few more improvements.
2024-05-17 15:45:50 +02:00
David Tolnay
a36b94d088
Disallow cast with trailing braced macro in let-else 2024-05-12 21:50:14 -07:00
Nicholas Nethercote
fd91925bce Add ErrorGuaranteed to Recovered::Yes and use it more.
The starting point for this was identical comments on two different
fields, in `ast::VariantData::Struct` and `hir::VariantData::Struct`:
```
    // FIXME: investigate making this a `Option<ErrorGuaranteed>`
    recovered: bool
```
I tried that, and then found that I needed to add an `ErrorGuaranteed`
to `Recovered::Yes`. Then I ended up using `Recovered` instead of
`Option<ErrorGuaranteed>` for these two places and elsewhere, which
required moving `ErrorGuaranteed` from `rustc_parse` to `rustc_ast`.

This makes things more consistent, because `Recovered` is used in more
places, and there are fewer uses of `bool` and
`Option<ErrorGuaranteed>`. And safer, because it's difficult/impossible
to set `recovered` to `Recovered::Yes` without having emitted an error.
2024-05-09 20:12:07 +10:00
Nicholas Nethercote
095722214d Use better variable names in some maybe_whole! calls. 2024-03-21 10:18:34 +11:00
Nicholas Nethercote
0de050bd6d Use maybe_whole! to streamline parse_stmt_without_recovery. 2024-03-21 10:18:33 +11:00
Guillaume Gomez
ca9f0630a9 Rename ast::StmtKind::Local into ast::StmtKind::Let 2024-03-14 12:42:04 +01:00
Matthias Krüger
d774fbea7c
Rollup merge of #119365 - nbdd0121:asm-goto, r=Amanieu
Add asm goto support to `asm!`

Tracking issue: #119364

This PR implements asm-goto support, using the syntax described in "future possibilities" section of [RFC2873](https://rust-lang.github.io/rfcs/2873-inline-asm.html#asm-goto).

Currently I have only implemented the `label` part, not the `fallthrough` part (i.e. fallthrough is implicit). This doesn't reduce the expressive though, since you can use label-break to get arbitrary control flow or simply set a value and rely on jump threading optimisation to get the desired control flow. I can add that later if deemed necessary.

r? ``@Amanieu``
cc ``@ojeda``
2024-03-08 08:19:17 +01:00
clubby789
8e45d0fe49 Cancel parsing ever made during recovery 2024-03-06 21:59:03 +00:00
Nicholas Nethercote
80d2bdb619 Rename all ParseSess variables/fields/lifetimes as psess.
Existing names for values of this type are `sess`, `parse_sess`,
`parse_session`, and `ps`. `sess` is particularly annoying because
that's also used for `Session` values, which are often co-located, and
it can be difficult to know which type a value named `sess` refers to.
(That annoyance is the main motivation for this change.) `psess` is nice
and short, which is good for a name used this much.

The commit also renames some `parse_sess_created` values as
`psess_created`.
2024-03-05 08:11:45 +11:00
Esteban Küber
bde2dfb127 Detect more cases of = to : typo
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span
arround and mention it. If the type could continue being parsed as an
expression, suggest replacing the `:` with a `=`.

```
error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
 --> file.rs:2:32
  |
2 |     let _: std::env::temp_dir().join("foo");
  |          -                     ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
  |          |
  |          while parsing the type for `_`
  |          help: use `=` if you meant to assign
```

Fix #119665.
2024-03-01 02:03:00 +00:00
Nicholas Nethercote
899cb40809 Rename DiagnosticBuilder as Diag.
Much better!

Note that this involves renaming (and updating the value of)
`DIAGNOSTIC_BUILDER` in clippy.
2024-02-28 08:55:35 +11:00
Nicholas Nethercote
a8a486c846 Refactor take_for_recovery call sites.
To make them more concise and similar to each other.
2024-02-27 16:40:15 +11:00
Lieselotte
c440a5b814
Add ErrorGuaranteed to ast::ExprKind::Err 2024-02-25 22:24:31 +01:00
Gary Guo
93fa8579c6 Add asm label support to AST and HIR 2024-02-24 18:49:39 +00:00
clubby789
4850ae8442 Add newtype for parser recovery 2024-02-20 13:13:30 +00:00
clubby789
06d6c62f80 Add newtype for raw idents 2024-02-20 13:13:29 +00:00
Michael Goulet
ec263df5e4 Suggest wrapping mac args in parens rather than the whole expression 2024-01-18 00:01:13 +00:00
Nicholas Nethercote
b1b9278851 Make DiagnosticBuilder::emit consuming.
This works for most of its call sites. This is nice, because `emit` very
much makes sense as a consuming operation -- indeed,
`DiagnosticBuilderState` exists to ensure no diagnostic is emitted
twice, but it uses runtime checks.

For the small number of call sites where a consuming emit doesn't work,
the commit adds `DiagnosticBuilder::emit_without_consuming`. (This will
be removed in subsequent commits.)

Likewise, `emit_unless` becomes consuming. And `delay_as_bug` becomes
consuming, while `delay_as_bug_without_consuming` is added (which will
also be removed in subsequent commits.)

All this requires significant changes to `DiagnosticBuilder`'s chaining
methods. Currently `DiagnosticBuilder` method chaining uses a
non-consuming `&mut self -> &mut Self` style, which allows chaining to
be used when the chain ends in `emit()`, like so:
```
    struct_err(msg).span(span).emit();
```
But it doesn't work when producing a `DiagnosticBuilder` value,
requiring this:
```
    let mut err = self.struct_err(msg);
    err.span(span);
    err
```
This style of chaining won't work with consuming `emit` though. For
that, we need to use to a `self -> Self` style. That also would allow
`DiagnosticBuilder` production to be chained, e.g.:
```
    self.struct_err(msg).span(span)
```
However, removing the `&mut self -> &mut Self` style would require that
individual modifications of a `DiagnosticBuilder` go from this:
```
    err.span(span);
```
to this:
```
    err = err.span(span);
```
There are *many* such places. I have a high tolerance for tedious
refactorings, but even I gave up after a long time trying to convert
them all.

Instead, this commit has it both ways: the existing `&mut self -> Self`
chaining methods are kept, and new `self -> Self` chaining methods are
added, all of which have a `_mv` suffix (short for "move"). Changes to
the existing `forward!` macro lets this happen with very little
additional boilerplate code. I chose to add the suffix to the new
chaining methods rather than the existing ones, because the number of
changes required is much smaller that way.

This doubled chainging is a bit clumsy, but I think it is worthwhile
because it allows a *lot* of good things to subsequently happen. In this
commit, there are many `mut` qualifiers removed in places where
diagnostics are emitted without being modified. In subsequent commits:
- chaining can be used more, making the code more concise;
- more use of chaining also permits the removal of redundant diagnostic
  APIs like `struct_err_with_code`, which can be replaced easily with
  `struct_err` + `code_mv`;
- `emit_without_diagnostic` can be removed, which simplifies a lot of
  machinery, removing the need for `DiagnosticBuilderState`.
2024-01-08 15:24:49 +11:00
Nicholas Nethercote
d51db05d7e Remove ParseSess methods that duplicate DiagCtxt methods.
Also add missing `#[track_caller]` attributes to `DiagCtxt` methods as
necessary to keep tests working.
2023-12-24 07:59:21 +11:00
Nicholas Nethercote
ec9af0d6cb Remove Parser methods that duplicate DiagCtxt methods. 2023-12-24 07:48:47 +11:00
Nicholas Nethercote
757d6f6ef8 Give DiagnosticBuilder a default type.
`IntoDiagnostic` defaults to `ErrorGuaranteed`, because errors are the
most common diagnostic level. It makes sense to do likewise for the
closely-related (and much more widely used) `DiagnosticBuilder` type,
letting us write `DiagnosticBuilder<'a, ErrorGuaranteed>` as just
`DiagnosticBuilder<'a>`. This cuts over 200 lines of code due to many
multi-line things becoming single line things.
2023-12-23 13:23:10 +11:00
Matthias Krüger
20473eba0b
Rollup merge of #118394 - nnethercote:rm-hir-Ops, r=cjgillot
Remove HIR opkinds

`hir::BinOp`, `hir::BinOpKind`, and `hir::UnOp` are identical to `ast::BinOp`, `ast::BinOpKind`, and `ast::UnOp`, respectively. This seems silly, so this PR removes the HIR ones. (A re-export lets the AST ones be referred to using a `hir::` qualifier, which avoids renaming churn.)

r? `@cjgillot`
2023-11-29 04:23:23 +01:00
Nicholas Nethercote
705b484922 Rename BinOpKind::lazy as BinOpKind::is_lazy.
To match `BinOpKind::is_comparison` and `hir::BinOpKind::is_lazy`.
2023-11-28 09:45:40 +11:00
Nicholas Nethercote
0efd2a9d8f Rework ast::BinOpKind::to_string and ast::UnOp::to_string.
- Rename them both `as_str`, which is the typical name for a function
  that returns a `&str`. (`to_string` is appropriate for functions
  returning `String` or maybe `Cow<'a, str>`.)
- Change `UnOp::as_str` from an associated function (weird!) to a
  method.
- Avoid needless `self` dereferences.
2023-11-28 09:42:07 +11:00
Hirochika Matsumoto
acec70de9b Change help message to make some sense in broader context 2023-11-27 22:18:03 +09:00
Hirochika Matsumoto
730d299354 Address review feedbacks
Also addressed merge conflicts upon rebasing.
2023-11-27 22:06:42 +09:00
Hirochika Matsumoto
61c3e4d56e Make tidy test happy 2023-11-27 21:48:10 +09:00
Hirochika Matsumoto
e65c060d78 Detect Python-like slicing and suggest how to fix
Fix #108215
2023-11-27 21:48:10 +09:00
Michael Goulet
e6a3ca0c65
Rollup merge of #117988 - estebank:issue-106020, r=cjgillot
Handle attempts to have multiple `cfg`d tail expressions

When encountering code that seems like it might be trying to have multiple tail expressions depending on `cfg` information, suggest alternatives that will success to parse.

```rust
fn foo() -> String {
    #[cfg(feature = "validation")]
    [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>()
    #[cfg(not(feature = "validation"))]
    String::new()
}
```

```
error: expected `;`, found `#`
  --> $DIR/multiple-tail-expr-behind-cfg.rs:5:64
   |
LL |     #[cfg(feature = "validation")]
   |     ------------------------------ only `;` terminated statements or tail expressions are allowed after this attribute
LL |     [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>()
   |                                                                ^ expected `;` here
LL |     #[cfg(not(feature = "validation"))]
   |     - unexpected token
   |
help: add `;` here
   |
LL |     [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>();
   |                                                                +
help: alternatively, consider surrounding the expression with a block
   |
LL |     { [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() }
   |     +                                                             +
help: it seems like you are trying to provide different expressions depending on `cfg`, consider using `if cfg!(..)`
   |
LL ~     if cfg!(feature = "validation") {
LL ~         [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>()
LL ~     } else if cfg!(not(feature = "validation")) {
LL ~         String::new()
LL +     }
   |
```

Fix #106020.

r? `@oli-obk`
2023-11-19 19:14:34 -08:00
Esteban Küber
a16722d221 Handle attempts to have multiple cfgd tail expressions
When encountering code that seems like it might be trying to have
multiple tail expressions depending on `cfg` information, suggest
alternatives that will success to parse.

```rust
fn foo() -> String {
    #[cfg(feature = "validation")]
    [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>()
    #[cfg(not(feature = "validation"))]
    String::new()
}
```

```
error: expected `;`, found `#`
  --> $DIR/multiple-tail-expr-behind-cfg.rs:5:64
   |
LL |     #[cfg(feature = "validation")]
   |     ------------------------------ only `;` terminated statements or tail expressions are allowed after this attribute
LL |     [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>()
   |                                                                ^ expected `;` here
LL |     #[cfg(not(feature = "validation"))]
   |     - unexpected token
   |
help: add `;` here
   |
LL |     [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>();
   |                                                                +
help: alternatively, consider surrounding the expression with a block
   |
LL |     { [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() }
   |     +                                                             +
help: it seems like you are trying to provide different expressions depending on `cfg`, consider using `if cfg!(..)`
   |
LL ~     if cfg!(feature = "validation") {
LL ~         [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>()
LL ~     } else if cfg!(not(feature = "validation")) {
LL ~         String::new()
LL +     }
   |
```

Fix #106020.
2023-11-16 21:21:26 +00:00
Esteban Küber
4e418805da More detail when expecting expression but encountering bad macro argument
Partially address #71039.
2023-11-16 16:19:04 +00:00
Nicholas Nethercote
f405ce86c2 Minimize pub usage in source_map.rs.
Most notably, this commit changes the `pub use crate::*;` in that file
to `use crate::*;`. This requires a lot of `use` items in other crates
to be adjusted, because everything defined within `rustc_span::*` was
also available via `rustc_span::source_map::*`, which is bizarre.

The commit also removes `SourceMap::span_to_relative_line_string`, which
is unused.
2023-11-02 19:35:00 +11:00
Esteban Küber
20de5c762d Move where doc comment meant as comment check
The new place makes more sense and covers more cases beyond individual
statements.

```
error: expected one of `.`, `;`, `?`, `else`, or an operator, found doc comment `//!foo
  --> $DIR/doc-comment-in-stmt.rs:25:22
   |
LL |     let y = x.max(1) //!foo
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected one of `.`, `;`, `?`, `else`, or an operator
   |
help: add a space before `!` to write a regular comment
   |
LL |     let y = x.max(1) // !foo
   |                        +
```

Fix #65329.
2023-10-20 02:54:45 +00:00
Michael Goulet
b2d2184ede Format all the let chains in compiler 2023-10-13 08:59:36 +00:00
Nicholas Nethercote
d75ee2a6bc Remove MacDelimiter.
It's the same as `Delimiter`, minus the `Invisible` variant. I'm
generally in favour of using types to make impossible states
unrepresentable, but this one feels very low-value, and the conversions
between the two types are annoying and confusing.

Look at the change in `src/tools/rustfmt/src/expr.rs` for an example:
the old code converted from `MacDelimiter` to `Delimiter` and back
again, for no good reason. This suggests the author was confused about
the types.
2023-08-03 09:03:30 +10:00
Matthias Krüger
23815467a2 inline format!() args up to and including rustc_middle 2023-07-30 13:18:33 +02:00
Nicholas Nethercote
781111ef35 Use Cow in {D,Subd}iagnosticMessage.
Each of `{D,Subd}iagnosticMessage::{Str,Eager}` has a comment:
```
// FIXME(davidtwco): can a `Cow<'static, str>` be used here?
```
This commit answers that question in the affirmative. It's not the most
compelling change ever, but it might be worth merging.

This requires changing the `impl<'a> From<&'a str>` impls to `impl
From<&'static str>`, which involves a bunch of knock-on changes that
require/result in call sites being a little more precise about exactly
what kind of string they use to create errors, and not just `&str`. This
will result in fewer unnecessary allocations, though this will not have
any notable perf effects given that these are error paths.

Note that I was lazy within Clippy, using `to_string` in a few places to
preserve the existing string imprecision. I could have used `impl
Into<{D,Subd}iagnosticMessage>` in various places as is done in the
compiler, but that would have required changes to *many* call sites
(mostly changing `&format("...")` to `format!("...")`) which didn't seem
worthwhile.
2023-05-29 09:23:43 +10:00
Dylan DPC
ee26abdafb
Rollup merge of #111054 - cjgillot:cfg-eval-recover, r=b-naber
Do not recover when parsing stmt in cfg-eval.

`parse_stmt` does recovery on its own. When parsing the statement fails, we always get `Ok(None)` instead of an `Err` variant with the diagnostic that we can emit.

To avoid this behaviour, we need to opt-out of recovery for cfg_eval.

Fixes https://github.com/rust-lang/rust/issues/105228
2023-05-18 17:37:08 +05:30
Dylan DPC
8c51701b8a
Rollup merge of #111120 - chenyukang:yukang-suggest-let, r=Nilstrieb
Suggest let for possible binding with ty

Origin from https://github.com/rust-lang/rust/pull/109128#discussion_r1179866137

r? `@Nilstrieb`
2023-05-09 12:33:46 +05:30