Commit Graph

1676 Commits

Author SHA1 Message Date
Guillaume Gomez
c00192ae2a
Rollup merge of #120460 - nnethercote:fix-120397, r=compiler-errors
Be more careful about interpreting a label/lifetime as a mistyped char literal.

Currently the parser interprets any label/lifetime in certain positions as a mistyped char literal, on the assumption that the trailing single quote was accidentally omitted. In such cases it gives an error with a suggestion to add the trailing single quote, and then puts the appropriate char literal into the AST. This behaviour was introduced in #101293.

This is reasonable for a case like this:
```
let c = 'a;
```
because `'a'` is a valid char literal. It's less reasonable for a case like this:
```
let c = 'abc;
```
because `'abc'` is not a valid char literal.

Prior to #120329 this could result in some sub-optimal suggestions in error messages, but nothing else. But #120329 changed `LitKind::from_token_lit` to assume that the char/byte/string literals it receives are valid, and to assert if not. This is reasonable because the lexer does not produce invalid char/byte/string literals in general. But in this "interpret label/lifetime as unclosed char literal" case the parser can produce an invalid char literal with contents such as `abc`, which triggers an assertion failure.

This PR changes the parser so it's more cautious about interpreting labels/lifetimes as unclosed char literals.

Fixes #120397.

r? `@compiler-errors`
2024-01-30 11:19:19 +01:00
Dylan DPC
0138151c21
Rollup merge of #118625 - ShE3py:expr-in-pats, r=WaffleLapkin
Improve handling of expressions in patterns

Closes #112593.

Methodcalls' dots in patterns are silently recovered as commas (e.g. `Foo("".len())` -> `Foo("", len())`) so extra diagnostics are emitted:
```rs
struct Foo(u8, String, u8);

fn bar(foo: Foo) -> bool {
    match foo {
        Foo(4, "yippee".yeet(), 7) => true,
        _ => false
    }
}
```
```
error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
 --> main.rs:5:24
  |
5 |         Foo(4, "yippee".yeet(), 7) => true,
  |                        ^
  |                        |
  |                        expected one of `)`, `,`, `...`, `..=`, `..`, or `|`
  |                        help: missing `,`

error[E0531]: cannot find tuple struct or tuple variant `yeet` in this scope
 --> main.rs:5:25
  |
5 |         Foo(4, "yippee".yeet(), 7) => true,
  |                         ^^^^ not found in this scope

error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
 --> main.rs:5:13
  |
1 | struct Foo(u8, String, u8);
  |            --  ------  -- tuple struct has 3 fields
...
5 |         Foo(4, "yippee".yeet(), 7) => true,
  |             ^  ^^^^^^^^ ^^^^^^  ^ expected 3 fields, found 4

error: aborting due to 3 previous errors
```

This PR checks for patterns that ends with a dot and a lowercase ident (as structs/variants should be uppercase):
```
error: expected a pattern, found a method call
 --> main.rs:5:16
  |
5 |         Foo(4, "yippee".yeet(), 7) => true,
  |                ^^^^^^^^^^^^^^^ method calls are not allowed in patterns

error: aborting due to 1 previous error
```

Also check for expressions:
```rs
fn is_idempotent(x: f32) -> bool {
    match x {
        x * x => true,
        _ => false,
    }
}

fn main() {
    let mut t: [i32; 5];
    let t[0] = 1;
}
```
```
error: expected a pattern, found an expression
 --> main.rs:3:9
  |
3 |         x * x => true,
  |         ^^^^^ arbitrary expressions are not allowed in patterns

error: expected a pattern, found an expression
  --> main.rs:10:9
   |
10 |     let t[0] = 1;
   |         ^^^^ arbitrary expressions are not allowed in patterns
```

Would be cool if the compiler could suggest adding a guard for `match`es, but I've no idea how to do it.

---
`@rustbot` label +A-diagnostics +A-parser +A-patterns +C-enhancement
2024-01-29 12:56:51 +00:00
Nicholas Nethercote
306612ea60 Be more careful about interpreting a label/lifetime as a mistyped char literal.
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.
2024-01-29 11:25:09 +11:00
Nicholas Nethercote
5bda589ff3 Tweak comment and naming for recover_unclosed_char.
Because it can be used for a lifetime or a label.
2024-01-29 09:33:49 +11:00
Nicholas Nethercote
5d9dfbd08f Stop using String for error codes.
Error codes are integers, but `String` is used everywhere to represent
them. Gross!

This commit introduces `ErrCode`, an integral newtype for error codes,
replacing `String`. It also introduces a constant for every error code,
e.g. `E0123`, and removes the `error_code!` macro. The constants are
imported wherever used with `use rustc_errors::codes::*`.

With the old code, we have three different ways to specify an error code
at a use point:
```
error_code!(E0123)  // macro call

struct_span_code_err!(dcx, span, E0123, "msg");  // bare ident arg to macro call

\#[diag(name, code = "E0123")]  // string
struct Diag;
```

With the new code, they all use the `E0123` constant.
```
E0123  // constant

struct_span_code_err!(dcx, span, E0123, "msg");  // constant

\#[diag(name, code = E0123)]  // constant
struct Diag;
```

The commit also changes the structure of the error code definitions:
- `rustc_error_codes` now just defines a higher-order macro listing the
  used error codes and nothing else.
- Because that's now the only thing in the `rustc_error_codes` crate, I
  moved it into the `lib.rs` file and removed the `error_codes.rs` file.
- `rustc_errors` uses that macro to define everything, e.g. the error
  code constants and the `DIAGNOSTIC_TABLES`. This is in its new
  `codes.rs` file.
2024-01-29 07:41:41 +11:00
Lieselotte
6f014a81b2
Handle methodcalls & operators in patterns 2024-01-28 16:12:21 +01:00
Matthias Krüger
9a4417659e
Rollup merge of #118182 - estebank:issue-118164, r=davidtwco
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.
2024-01-27 10:48:46 +01:00
Esteban Küber
a5d9def321 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.
2024-01-26 23:11:42 +00:00
Matthias Krüger
7f19365560
Rollup merge of #119342 - sjwang05:issue-112254, r=wesleywiser
Emit suggestion when trying to write exclusive ranges as `..<`

Closes #112254
2024-01-26 23:15:49 +01:00
Matthias Krüger
5f1f6176a5
Rollup merge of #120329 - nnethercote:3349-precursors, r=fee1-dead
RFC 3349 precursors

Some cleanups I found while working on RFC 3349 that are worth landing separately.

r? `@fee1-dead`
2024-01-26 14:43:31 +01:00
clubby789
fd29f74ff8 Remove unused features 2024-01-25 14:01:33 +00:00
Nicholas Nethercote
6be2e5623c Use unescape_unicode for raw C string literals.
They can't contain `\x` escapes, which means they can't contain high
bytes, which means we can used `unescape_unicode` instead of
`unescape_mixed` to unescape them. This avoids unnecessary used of
`MixedUnit`.
2024-01-25 12:28:11 +11:00
Nicholas Nethercote
86f371ed59 Rename the unescaping functions.
`unescape_literal` becomes `unescape_unicode`, and `unescape_c_string`
becomes `unescape_mixed`. Because rfc3349 will mean that C string
literals will no longer be the only mixed utf8 literals.
2024-01-25 12:28:11 +11:00
Guillaume Gomez
8f5f967031
Rollup merge of #120063 - clubby789:remove-box-handling, r=Nilstrieb
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.
2024-01-20 20:06:34 +01:00
Matthias Krüger
2e4c6fc998
Rollup merge of #119062 - compiler-errors:asm-in-let-else, r=davidtwco,est31
Deny braced macro invocations in let-else

Fixes #119057

Pending T-lang decision

cc `@dtolnay`
2024-01-19 08:15:03 +01:00
Matthias Krüger
ff8c7a7816
Rollup merge of #119172 - nnethercote:earlier-NulInCStr, r=petrochenkov
Detect `NulInCStr` error earlier.

By making it an `EscapeError` instead of a `LitError`. This makes it like the other errors produced when checking string literals contents, e.g. for invalid escape sequences or bare CR chars.

NOTE: this means these errors are issued earlier, before expansion, which changes behaviour. It will be possible to move the check back to the later point if desired. If that happens, it's likely that all the string literal contents checks will be delayed together.

One nice thing about this: the old approach had some code in `report_lit_error` to calculate the span of the nul char from a range. This code used a hardwired `+2` to account for the `c"` at the start of a C string literal, but this should have changed to a `+3` for raw C string literals to account for the `cr"`, which meant that the caret in `cr"` nul error messages was one short of where it should have been. The new approach doesn't need any of this and avoids the off-by-one error.

r? ```@fee1-dead```
2024-01-18 10:34:17 +01:00
Michael Goulet
ec263df5e4 Suggest wrapping mac args in parens rather than the whole expression 2024-01-18 00:01:13 +00:00
clubby789
b9ebeee4da Remove box <expr> recovery 2024-01-17 21:16:22 +00:00
bors
aa5f781bd4 Auto merge of #119341 - sjwang05:issue-58462, r=WaffleLapkin
Suggest quoting unquoted idents in attrs

Closes #58462
2024-01-14 04:37:45 +00:00
sjwang05
aa8ecd0652
Suggest quoting unquoted idents in attrs 2024-01-12 13:59:47 -08:00
Bryanskiy
d69cd6473c Delegation implementation: step 1 2024-01-12 14:11:16 +03:00
Nicholas Nethercote
9018d2c455 Detect NulInCStr error earlier.
By making it an `EscapeError` instead of a `LitError`. This makes it
like the other errors produced when checking string literals contents,
e.g. for invalid escape sequences or bare CR chars.

NOTE: this means these errors are issued earlier, before expansion,
which changes behaviour. It will be possible to move the check back to
the later point if desired. If that happens, it's likely that all the
string literal contents checks will be delayed together.

One nice thing about this: the old approach had some code in
`report_lit_error` to calculate the span of the nul char from a range.
This code used a hardwired `+2` to account for the `c"` at the start of
a C string literal, but this should have changed to a `+3` for raw C
string literals to account for the `cr"`, which meant that the caret in
`cr"` nul error messages was one short of where it should have been. The
new approach doesn't need any of this and avoids the off-by-one error.
2024-01-12 16:19:37 +11:00
Nicholas Nethercote
6656413a5c Stop using DiagnosticBuilder::buffer in the parser.
One consequence is that errors returned by
`maybe_new_parser_from_source_str` now must be consumed, so a bunch of
places that previously ignored those errors now cancel them. (Most of
them explicitly dropped the errors before. I guess that was to indicate
"we are explicitly ignoring these", though I'm not 100% sure.)
2024-01-11 18:37:56 +11:00
Nicholas Nethercote
d02150fd45 Fix lifetimes in StringReader.
Two different lifetimes are conflated. This doesn't matter right now,
but needs to be fixed for the next commit to work. And the more
descriptive lifetime names make the code easier to read.
2024-01-11 16:55:10 +11:00
Nicholas Nethercote
d5aafb846b Use struct_fatal in new_parser_from_file.
It's a little more concise, and the standard way to do it.
2024-01-11 16:55:10 +11:00
Nicholas Nethercote
f5c0cd0bd1 Inline and remove three functions.
Each of these has a single call site: `source_file_to_parser`,
`try_file_to_source_file`, `file_to_source_file`. Having them separate
just makes the code longer and harder to read.

Also, `maybe_file_to_stream` doesn't need to be `pub`.
2024-01-11 16:55:10 +11:00
Nicholas Nethercote
ed76b0b882 Rename consuming chaining methods on DiagnosticBuilder.
In #119606 I added them and used a `_mv` suffix, but that wasn't great.

A `with_` prefix has three different existing uses.
- Constructors, e.g. `Vec::with_capacity`.
- Wrappers that provide an environment to execute some code, e.g.
  `with_session_globals`.
- Consuming chaining methods, e.g. `Span::with_{lo,hi,ctxt}`.

The third case is exactly what we want, so this commit changes
`DiagnosticBuilder::foo_mv` to `DiagnosticBuilder::with_foo`.

Thanks to @compiler-errors for the suggestion.
2024-01-10 07:40:00 +11:00
Nicholas Nethercote
3c4f1d85af Rename {create,emit}_warning as {create,emit}_warn.
For consistency with `warn`/`struct_warn`, and also `{create,emit}_err`,
all of which use an abbreviated form.
2024-01-10 07:33:06 +11:00
Nicholas Nethercote
4864cb8aef Rename struct_span_err! as struct_span_code_err!.
Because it takes an error code after the span. This avoids the confusing
overlap with the `DiagCtxt::struct_span_err` method, which doesn't take
an error code.
2024-01-10 07:33:04 +11:00
sjwang05
6dd0772707
Emit suggestion when trying to write exclusive ranges as ..< 2024-01-08 16:06:37 -08:00
Nicholas Nethercote
4752a923af Remove DiagnosticBuilder::delay_as_bug_without_consuming.
The existing uses are replaced in one of three ways.
- In a function that also has calls to `emit`, just rearrange the code
  so that exactly one of `delay_as_bug` or `emit` is called on every
  path.
- In a function returning a `DiagnosticBuilder`, use
  `downgrade_to_delayed_bug`. That's good enough because it will get
  emitted later anyway.
- In `unclosed_delim_err`, one set of errors is being replaced with
  another set, so just cancel the original errors.
2024-01-08 16:07:14 +11:00
Nicholas Nethercote
c733a0216d Remove a fourth DiagnosticBuilder::emit_without_consuming call.
The old code was very hard to understand, involving an
`emit_without_consuming` call *and* a `delay_as_bug_without_consuming`
call.

With slight changes both calls can be avoided. Not creating the error
until later is crucial, as is the early return in the `if recovered`
block.

It took me some time to come up with this reworking -- it went through
intermediate states much further from the original code than this final
version -- and it's isn't obvious at a glance that it is equivalent. But
I think it is, and the unchanged test behaviour is good supporting
evidence.

The commit also changes `check_trailing_angle_brackets` to return
`Option<ErrorGuaranteed>`. This provides a stricter proof that it
emitted an error message than asserting `dcx.has_errors().is_some()`,
which would succeed if any error had previously been emitted anywhere.
2024-01-08 16:04:50 +11:00
Nicholas Nethercote
1b6c8e7533 Remove a third DiagnosticBuilder::emit_without_consuming call.
It's not clear why this was here, because the created error is returned
as a normal error anyway.

Nor is it clear why removing the call works. The change doesn't affect
any tests; `tests/ui/parser/issues/issue-102182-impl-trait-recover.rs`
looks like the only test that could have been affected.
2024-01-08 16:03:41 +11:00
Nicholas Nethercote
3ce34f42e1 Remove a second DiagnosticBuilder::emit_without_consuming call.
Instead of taking `seq` as a mutable reference,
`maybe_recover_struct_lit_bad_delims` now consumes `seq` on the recovery
path, and returns `seq` unchanged on the non-recovery path. The commit
also combines an `if` and a `match` to merge two identical paths.

Also change `recover_seq_parse_error` so it receives a `PErr` instead of
a `PResult`, because all the call sites now handle the `Ok`/`Err`
distinction themselves.
2024-01-08 16:01:22 +11:00
Nicholas Nethercote
1881055000 Remove a DiagnosticBuilder::emit_without_consuming call.
In this parsing recovery function, we only need to emit the previously
obtained error message and mark `expr` as erroneous in the case where we
actually recover.
2024-01-08 16:01:22 +11:00
Nicholas Nethercote
6682f243dc Remove all eight DiagnosticBuilder::*_with_code methods.
These all have relatively low use, and can be perfectly emulated with
a simpler construction method combined with `code` or `code_mv`.
2024-01-08 16:00:34 +11:00
Nicholas Nethercote
bd4e623485 Use chaining for DiagnosticBuilder construction and emit.
To avoid the use of a mutable local variable, and because it reads more
nicely.
2024-01-08 15:45:29 +11:00
Nicholas Nethercote
589591efde Use chaining in DiagnosticBuilder construction.
To avoid the use of a mutable local variable, and because it reads more
nicely.
2024-01-08 15:43:07 +11: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
Matthias Krüger
1d6ab69ab1
Rollup merge of #119624 - petrochenkov:dialoc4, r=compiler-errors
rustc_span: More consistent span combination operations

Also add more tests for using `tt` in addition to `ident`, and some other minor tweaks, see individual commits.

This is a part of https://github.com/rust-lang/rust/pull/119412 that doesn't yet add side tables for metavariable spans.
2024-01-06 16:07:48 +01:00
Vadim Petrochenkov
508d1ff7d8 rustc_span: More consistent span combination operations 2024-01-05 19:41:46 +03:00
Vadim Petrochenkov
fb1cca2937 parser: Tiny refactoring 2024-01-05 19:13:52 +03:00
Michael Goulet
f361b591ef
Rollup merge of #119538 - nnethercote:cleanup-errors-5, r=compiler-errors
Cleanup error handlers: round 5

More rustc_errors cleanups. A sequel to https://github.com/rust-lang/rust/pull/119171.

r? ````@compiler-errors````
2024-01-05 10:57:21 -05:00
bors
f688dd684f Auto merge of #119569 - matthiaskrgr:rollup-4packja, r=matthiaskrgr
Rollup of 10 pull requests

Successful merges:

 - #118521 (Enable address sanitizer for MSVC targets using INFERASANLIBS linker flag)
 - #119026 (std::net::bind using -1 for openbsd which in turn sets it to somaxconn.)
 - #119195 (Make named_asm_labels lint not trigger on unicode and trigger on format args)
 - #119204 (macro_rules: Less hacky heuristic for using `tt` metavariable spans)
 - #119362 (Make `derive(Trait)` suggestion more accurate)
 - #119397 (Recover parentheses in range patterns)
 - #119417 (Uplift some miscellaneous coroutine-specific machinery into `check_closure`)
 - #119539 (Fix typos)
 - #119540 (Don't synthesize host effect args inside trait object types)
 - #119555 (Add codegen test for RVO on MaybeUninit)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-01-04 21:44:14 +00:00
Nicholas Nethercote
8e6bca63f9 Inline and remove StringReader::struct_fatal_span_char.
It has a single call site.
2024-01-04 11:44:16 +11:00
Lieselotte
4e0baddbbf
Recover parentheses in range patterns
Co-authored-by: León Orell Valerian Liehr <me@fmease.dev>
2024-01-03 15:27:58 +01:00
Nicholas Nethercote
505c1371d0 Rename some Diagnostic setters.
`Diagnostic` has 40 methods that return `&mut Self` and could be
considered setters. Four of them have a `set_` prefix. This doesn't seem
necessary for a type that implements the builder pattern. This commit
removes the `set_` prefixes on those four methods.
2024-01-03 19:40:20 +11:00
George Bateman
f0c0a498b8
Update after rebase 2024-01-02 23:13:08 +00:00
George Bateman
09bb07e38f
Make offset_of field parsing use metavariable which handles any spacing 2024-01-02 22:18:35 +00:00
Nilstrieb
ffafcd8819 Update to bitflags 2 in the compiler
This involves lots of breaking changes. There are two big changes that
force changes. The first is that the bitflag types now don't
automatically implement normal derive traits, so we need to derive them
manually.

Additionally, bitflags now have a hidden inner type by default, which
breaks our custom derives. The bitflags docs recommend using the impl
form in these cases, which I did.
2023-12-30 18:17:28 +01:00
DaniPopes
c7a67747d3
Use filter instead of filter_map in Parser::expected_one_of_not_found 2023-12-28 21:19:41 +01:00
Matthias Krüger
e8831b6df8
Rollup merge of #119380 - ShE3py:match-never-pat, r=petrochenkov
Don't suggest writing a bodyless arm if the pattern can never be a never pattern

#118527 enabled arms to be bodyless for never patterns ; this PR removes the `,` and `}` suggestions for patterns that could never be never patterns.
2023-12-28 18:48:02 +01:00
Matthias Krüger
0b6e8f5324
Rollup merge of #119379 - ShE3py:parse-seq-doc, r=compiler-errors
Update `parse_seq` doc

Some doc changes I made while working on an issue.
2023-12-28 18:48:01 +01:00
Matthias Krüger
54bcb07ab1
Rollup merge of #119359 - DaniPopes:ident-or-err, r=compiler-errors
Simplify Parser::ident_or_error

Avoid a nested `Result<T, PResult<T>>`.
2023-12-28 18:48:01 +01:00
Lieselotte
7d6cd6bf1f
Don't expect bodyless arms if the pattern can never be a never pattern 2023-12-28 15:02:17 +01:00
Lieselotte
44bf2a32a5
Update parse_seq doc 2023-12-28 14:06:51 +01:00
DaniPopes
826269eddb
Simplify Parser::ident_or_error
Avoid a nested `Result<T, PResult<T>>`.
2023-12-27 21:18:32 +01:00
bors
88d69b72b4 Auto merge of #119099 - fmease:always-const-trait-bounds, r=fee1-dead
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)
2023-12-27 19:24:31 +00:00
bors
a861c8965e Auto merge of #117303 - sjwang05:issue-117245, r=estebank
Suggest `=>` --> `>=` in comparisons

Fixes #117245
2023-12-27 17:26:12 +00:00
León Orell Valerian Liehr
3eb48a35c8
Introduce const Trait (always-const trait bounds) 2023-12-27 12:51:32 +01:00
sjwang05
97cf1c87bd
Suggest => --> >= in conditions 2023-12-26 20:59:14 -08:00
Nicholas Nethercote
99472c7049 Remove Session methods that duplicate DiagCtxt methods.
Also add some `dcx` methods to types that wrap `TyCtxt`, for easier
access.
2023-12-24 08:05:28 +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
Matthias Krüger
bdc4480914
Rollup merge of #119231 - aDotInTheVoid:PatKind-struct-bool-docs, r=compiler-errors
Clairify `ast::PatKind::Struct` presese of `..` by using an enum instead of a bool

The bool is mainly used for when a `..` is present, but it is also set on recovery to avoid errors. The doc comment not describes both of these cases.

See cee794ee98/compiler/rustc_parse/src/parser/pat.rs (L890-L897) for the only place this is constructed.

r? ``@compiler-errors``
2023-12-23 16:23:54 +01:00
Alona Enraght-Moony
1349d86c72 bool->enum for ast::PatKind::Struct presence of ..
See cee794ee98/compiler/rustc_parse/src/parser/pat.rs (L890-L897) for the only place this is constructed.
2023-12-23 02:50:31 +00: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
bors
208dd2032b Auto merge of #118847 - eholk:for-await, r=compiler-errors
Add support for `for await` loops

This adds support for `for await` loops. This includes parsing, desugaring in AST->HIR lowering, and adding some support functions to the library.

Given a loop like:
```rust
for await i in iter {
    ...
}
```
this is desugared to something like:
```rust
let mut iter = iter.into_async_iter();
while let Some(i) = loop {
    match core::pin::Pin::new(&mut iter).poll_next(cx) {
        Poll::Ready(i) => break i,
        Poll::Pending => yield,
    }
} {
    ...
}
```

This PR also adds a basic `IntoAsyncIterator` trait. This is partly for symmetry with the way `Iterator` and `IntoIterator` work. The other reason is that for async iterators it's helpful to have a place apart from the data structure being iterated over to store state. `IntoAsyncIterator` gives us a good place to do this.

I've gated this feature behind `async_for_loop` and opened #118898 as the feature tracking issue.

r? `@compiler-errors`
2023-12-22 14:17:10 +00:00
bors
aaef5fe497 Auto merge of #119163 - fmease:refactor-ast-trait-bound-modifiers, r=compiler-errors
Refactor AST trait bound modifiers

Instead of having two types to represent trait bound modifiers in the parser / the AST (`parser::ty::BoundModifiers` & `ast::TraitBoundModifier`), only to map one to the other later, just use `parser::ty::BoundModifiers` (moved & renamed to `ast::TraitBoundModifiers`).

The struct type is more extensible and easier to deal with (see [here](https://github.com/rust-lang/rust/pull/119099/files#r1430749981) and [here](https://github.com/rust-lang/rust/pull/119099/files#r1430752116) for context) since it more closely models what it represents: A compound of two kinds of modifiers, constness and polarity. Modeling this as an enum (the now removed `ast::TraitBoundModifier`) meant one had to add a new variant per *combination* of modifier kind, which simply isn't scalable and which lead to a lot of explicit non-DRY matches.

NB: `hir::TraitBoundModifier` being an enum is fine since HIR doesn't need to worry representing invalid modifier kind combinations as those get rejected during AST validation thereby immensely cutting down the number of possibilities.
2023-12-22 02:00:55 +00:00
bors
cee794ee98 Auto merge of #119097 - nnethercote:fix-EmissionGuarantee, r=compiler-errors
Fix `EmissionGuarantee`

There are some problems with the `DiagCtxt` API related to `EmissionGuarantee`. This PR fixes them.

r? `@compiler-errors`
2023-12-22 00:03:57 +00:00
Matthias Krüger
d0d814ff48
Rollup merge of #119145 - aDotInTheVoid:variantdata-struct-struct, r=compiler-errors
Give `VariantData::Struct`  named fields, to clairfy `recovered`.

Implements https://github.com/rust-lang/rust/pull/119121#discussion_r1431467066. Supersedes #119121

This way, it's clear what the bool fields means, instead of having to find where it's generated. Changes both ast and hir.

r? `@compiler-errors`
2023-12-20 21:18:59 +01:00
León Orell Valerian Liehr
5e4f12b41a
Refactor AST trait bound modifiers 2023-12-20 19:39:46 +01:00
Matthias Krüger
f3f9b3043e
Rollup merge of #118691 - chfogelman:improve-cstr-error, r=fmease
Add check for possible CStr literals in pre-2021

Fixes [#118654](https://github.com/rust-lang/rust/issues/118654)

Adds information to errors caused by possible CStr literals in pre-2021.

The lexer separates `c"str"` into two tokens if the edition is less than 2021, which later causes an error when parsing. This error now has a more helpful message that directs them to information about editions. However, the user might also have written `c "str"` in a later edition, so to not confuse people who _are_ using a recent edition, I also added a note about whitespace.

We could probably figure out exactly which scenario has been encountered by examining spans and editions, but I figured it would be better not to overcomplicate the creation of the error too much.

This is my first code PR and I tried to follow existing conventions as much as possible, but I probably missed something, so let me know!
2023-12-20 09:46:10 +01:00
Eric Holk
397f4a15bb
Add additional tests and update existing tests 2023-12-19 16:12:17 -08:00
Alona Enraght-Moony
11337805fb Give VariantData::Struct named fields, to clairfy recovered. 2023-12-20 00:07:34 +00:00
Carter Hunt Fogelman
2c96025874 Improve compiler error for c-strings in pre-2021 2023-12-19 13:28:48 -08:00
Eric Holk
27d6539a46
Plumb awaitness of for loops 2023-12-19 12:26:20 -08:00
Nicholas Nethercote
f5459201e0 Add EmitResult associated type to EmissionGuarantee.
This lets different error levels share the same return type from
`emit_*`.

- A lot of inconsistencies in the `DiagCtxt` API are removed.
- `Noted` is removed.
- `FatalAbort` is introduced for fatal errors (abort via `raise`),
  replacing the `EmissionGuarantee` impl for `!`.
- `Bug` is renamed `BugAbort` (to avoid clashing with `Level::Bug` and
  to mirror `FatalAbort`), and modified to work in the new way with bug
  errors (abort via panic).
- Various diagnostic creators and emitters updated to the new, better
  signatures. Note that `DiagCtxt::bug` no longer needs to call
  `panic_any`, because `emit` handles that.

Also shorten the obnoxiously long
`diagnostic_builder_emit_producing_guarantee` name.
2023-12-19 09:52:02 +11:00
Nicholas Nethercote
e7724a2e31 Add level arg to into_diagnostic.
And make all hand-written `IntoDiagnostic` impls generic, by using
`DiagnosticBuilder::new(dcx, level, ...)` instead of e.g.
`dcx.struct_err(...)`.

This means the `create_*` functions are the source of the error level.
This change will let us remove `struct_diagnostic`.

Note: `#[rustc_lint_diagnostics]` is added to `DiagnosticBuilder::new`,
it's necessary to pass diagnostics tests now that it's used in
`into_diagnostic` functions.
2023-12-19 09:19:25 +11:00
Nicholas Nethercote
cea683c08f Use .into_diagnostic() less.
This commit replaces this pattern:
```
err.into_diagnostic(dcx)
```
with this pattern:
```
dcx.create_err(err)
```
in a lot of places.

It's a little shorter, makes the error level explicit, avoids some
`IntoDiagnostic` imports, and is a necessary prerequisite for the next
commit which will add a `level` arg to `into_diagnostic`.

This requires adding `track_caller` on `create_err` to avoid mucking up
the output of `tests/ui/track-diagnostics/track4.rs`. It probably should
have been there already.
2023-12-18 20:46:13 +11:00
Nicholas Nethercote
f422dca3ae Rename many DiagCtxt arguments. 2023-12-18 16:06:22 +11:00
Nicholas Nethercote
73bac456d4 Rename Parser::span_diagnostic as Parser::dcx. 2023-12-18 16:06:21 +11:00
Nicholas Nethercote
9df1576e1d Rename ParseSess::span_diagnostic as ParseSess::dcx. 2023-12-18 16:06:21 +11:00
Nicholas Nethercote
cde19c016e Rename Handler as DiagCtxt. 2023-12-18 16:06:19 +11:00
bors
3ad8e2d129 Auto merge of #118897 - nnethercote:more-unescaping-cleanups, r=fee1-dead
More unescaping cleanups

More minor improvements I found while working on #118699.

r? `@fee1-dead`
2023-12-16 08:52:06 +00:00
Matthias Krüger
8479945c08 NFC don't convert types to identical types 2023-12-15 23:56:24 +01:00
Jubilee
9e872b7cd8
Rollup merge of #118933 - nnethercote:cleanup-errors-even-more, r=compiler-errors
Cleanup errors handlers even more

A sequel to #118587.

r? `@compiler-errors`
2023-12-14 16:07:48 -08:00
Nicholas Nethercote
9a78412511 Split Handler::emit_diagnostic in two.
Currently, `emit_diagnostic` takes `&mut self`.

This commit changes it so `emit_diagnostic` takes `self` and the new
`emit_diagnostic_without_consuming` function takes `&mut self`.

I find the distinction useful. The former case is much more common, and
avoids a bunch of `mut` and `&mut` occurrences. We can also restrict the
latter with `pub(crate)` which is nice.
2023-12-15 10:13:12 +11:00
Nicholas Nethercote
19d28a4f28 Change msg: impl Into<String> for bug diagnostics.
To `msg: impl Into<DiagnosticMessage>`, like all the other diagnostics.
For consistency.
2023-12-15 09:42:14 +11:00
Nicholas Nethercote
e3b7ecc1ef Remove one use of span_bug_no_panic.
It's unclear why this is used here. All entries in the third column of
`UNICODE_ARRAY` are covered by `ASCII_ARRAY`, so if the lookup fails
it's a genuine compiler bug. It was added way back in #29837, for no
clear reason.

This commit changes it to `span_bug`, which is more typical.
2023-12-14 15:53:55 +11:00
Nicholas Nethercote
7bdb227567 Avoid struct_diagnostic where possible.
It's necessary for `derive(Diagnostic)`, but is best avoided elsewhere
because there are clearer alternatives.

This required adding `Handler::struct_almost_fatal`.
2023-12-14 15:53:55 +11:00
Jubilee
f9078a40ee
Rollup merge of #118891 - compiler-errors:async-gen-blocks, r=eholk
Actually parse async gen blocks correctly

1. I got the control flow in `parse_expr_bottom` messed up, and obviously forgot a test for `async gen`, so we weren't actually ever parsing it correctly.
2. I forgot to gate the span for `async gen {}`, so even if we did parse it, we wouldn't have correctly denied it in `cfg(FALSE)`.

r? eholk
2023-12-12 18:48:55 -08:00
Nicholas Nethercote
423bf4233d Rename the span args to emit_unescape_error.
The `span` arg is described in a comment as "interior span of the
literal, without quotes", which is incorrect. It's actually the span of
the error part of the literal, corresponding to `range`.

This commit renames `span` and `span_without_quotes` to make things
clearer, and fixes the erroneous comment.
2023-12-13 10:05:57 +11:00
Michael Goulet
1d78ce681e Actually parse async gen blocks correctly 2023-12-12 20:13:37 +00:00
Matthias Krüger
d661974017
Rollup merge of #118868 - Nadrieril:correctly-gate-never_patterns-parsing, r=petrochenkov
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
2023-12-12 17:40:56 +01:00
Nadrieril
19e0c984d3 Don't gate the feature twice 2023-12-12 14:52:05 +01:00
Nadrieril
e274372689 Correctly gate the parsing of match arms without body 2023-12-12 14:42:04 +01:00
Nicholas Nethercote
226edf64fa Improve an error involving attribute values.
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.
2023-12-12 15:54:25 +11:00
Nicholas Nethercote
4cfdbd328b Add spacing information to delimiters.
This is an extension of the previous commit. It means the output of
something like this:
```
stringify!(let a: Vec<u32> = vec![];)
```
goes from this:
```
let a: Vec<u32> = vec![] ;
```
With this PR, it now produces this string:
```
let a: Vec<u32> = vec![];
```
2023-12-11 09:36:40 +11:00
Nicholas Nethercote
925f7fad57 Improve print_tts by changing tokenstream::Spacing.
`tokenstream::Spacing` appears on all `TokenTree::Token` instances,
both punct and non-punct. Its current usage:
- `Joint` means "can join with the next token *and* that token is a
  punct".
- `Alone` means "cannot join with the next token *or* can join with the
  next token but that token is not a punct".

The fact that `Alone` is used for two different cases is awkward.
This commit augments `tokenstream::Spacing` with a new variant
`JointHidden`, resulting in:
- `Joint` means "can join with the next token *and* that token is a
  punct".
- `JointHidden` means "can join with the next token *and* that token is a
  not a punct".
- `Alone` means "cannot join with the next token".

This *drastically* improves the output of `print_tts`. For example,
this:
```
stringify!(let a: Vec<u32> = vec![];)
```
currently produces this string:
```
let a : Vec < u32 > = vec! [] ;
```
With this PR, it now produces this string:
```
let a: Vec<u32> = vec![] ;
```
(The space after the `]` is because `TokenTree::Delimited` currently
doesn't have spacing information. The subsequent commit fixes this.)

The new `print_tts` doesn't replicate original code perfectly. E.g.
multiple space characters will be condensed into a single space
character. But it's much improved.

`print_tts` still produces the old, uglier output for code produced by
proc macros. Because we have to translate the generated code from
`proc_macro::Spacing` to the more expressive `token::Spacing`, which
results in too much `proc_macro::Along` usage and no
`proc_macro::JointHidden` usage. So `space_between` still exists and
is used by `print_tts` in conjunction with the `Spacing` field.

This change will also help with the removal of `Token::Interpolated`.
Currently interpolated tokens are pretty-printed nicely via AST pretty
printing. `Token::Interpolated` removal will mean they get printed with
`print_tts`. Without this change, that would result in much uglier
output for code produced by decl macro expansions. With this change, AST
pretty printing and `print_tts` produce similar results.

The commit also tweaks the comments on `proc_macro::Spacing`. In
particular, it refers to "compound tokens" rather than "multi-char
operators" because lifetimes aren't operators.
2023-12-11 09:19:09 +11:00