Commit Graph

124 Commits

Author SHA1 Message Date
Nicholas Nethercote
573267cf3c Rename SubdiagnosticMessageOp as SubdiagMessageOp. 2024-03-05 12:14:49 +11:00
r0cky
1850ba7f54 Remove unused diagnostic struct 2024-02-29 14:14:21 +08: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
02423a5747 Make some IntoDiagnostic impls generic.
PR #119097 made the decision to make all `IntoDiagnostic` impls generic,
because this allowed a bunch of nice cleanups. But four hand-written
impls were unintentionally overlooked. This commit makes them generic.
2024-02-22 13:47:30 +11:00
Michael Goulet
9c8b107955 Support async trait bounds in macros 2024-02-20 16:09:09 +00:00
Nicholas Nethercote
f6f8779843 Reduce capabilities of Diagnostic.
Currently many diagnostic modifier methods are available on both
`Diagnostic` and `DiagnosticBuilder`. This commit removes most of them
from `Diagnostic`. To minimize the diff size, it keeps them within
`diagnostic.rs` but changes the surrounding `impl Diagnostic` block to
`impl DiagnosticBuilder`. (I intend to move things around later, to give
a more sensible code layout.)

`Diagnostic` keeps a few methods that it still needs, like `sub`,
`arg`, and `replace_args`.

The `forward!` macro, which defined two additional methods per call
(e.g. `note` and `with_note`), is replaced by the `with_fn!` macro,
which defines one additional method per call (e.g. `with_note`). It's
now also only used when necessary -- not all modifier methods currently
need a `with_*` form. (New ones can be easily added as necessary.)

All this also requires changing `trait AddToDiagnostic` so its methods
take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many
mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`.

There are three subdiagnostics -- `DelayedAtWithoutNewline`,
`DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` --
that are created within the diagnostics machinery and appended to
external diagnostics. These are handled at the `Diagnostic` level, which
means it's now hard to construct them via `derive(Diagnostic)`, so
instead we construct them by hand. This has no effect on what they look
like when printed.

There are lots of new `allow` markers for `untranslatable_diagnostics`
and `diagnostics_outside_of_impl`. This is because
`#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic`
modifier methods, but missing from the `DiagnosticBuilder` modifier
methods. They're now present.
2024-02-20 13:22:17 +11:00
Urgau
d988d8f4ba Use better heuristic for printing Cargo specific diagnostics 2024-02-17 16:49:01 +01:00
Nicholas Nethercote
6b175a848d Add SubdiagnosticMessageOp as a trait alias.
It avoids a lot of repetition.
2024-02-08 13:02:44 +11:00
Michael Goulet
54db272cc9 Better error message in ed 2015 2024-01-31 16:59:19 +00: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
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
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
sjwang05
aa8ecd0652
Suggest quoting unquoted idents in attrs 2024-01-12 13:59:47 -08: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
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
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
09bb07e38f
Make offset_of field parsing use metavariable which handles any spacing 2024-01-02 22:18:35 +00:00
León Orell Valerian Liehr
3eb48a35c8
Introduce const Trait (always-const trait bounds) 2023-12-27 12:51:32 +01: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
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
f422dca3ae Rename many DiagCtxt arguments. 2023-12-18 16:06:22 +11:00
Nicholas Nethercote
cde19c016e Rename Handler as DiagCtxt. 2023-12-18 16:06:19 +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
Michael Goulet
a208bae00e Support async gen fn 2023-12-08 17:23:26 +00:00
Matthias Krüger
71a8ca0522
Rollup merge of #116420 - bvanjoi:fix-116203, r=Nilstrieb
discard invalid spans in external blocks

Fixes #116203

This PR has discarded the invalid `const_span`, thereby making the format more neat.

r? ``@Nilstrieb``
2023-12-07 21:38:07 +01:00
bors
1dd4db5062 Auto merge of #118655 - compiler-errors:rollup-vrngyzn, r=compiler-errors
Rollup of 9 pull requests

Successful merges:

 - #117793 (Update variable name to fix `unused_variables` warning)
 - #118123 (Add support for making lib features internal)
 - #118268 (Pretty print `Fn<(..., ...)>` trait refs with parentheses (almost) always)
 - #118346 (Add `deeply_normalize_for_diagnostics`, use it in coherence)
 - #118350 (Simplify Default for tuples)
 - #118450 (Use OnceCell in cell module documentation)
 - #118585 (Fix parser ICE when recovering `dyn`/`impl` after `for<...>`)
 - #118587 (Cleanup error handlers some more)
 - #118642 (bootstrap(builder.rs): Don't explicitly warn against `semicolon_in_expressions_from_macros`)

r? `@ghost`
`@rustbot` modify labels: rollup
2023-12-06 04:20:51 +00:00
Eric Holk
f29b36d03e
Make async gen fn an error 2023-12-04 11:23:07 -08:00
Nicholas Nethercote
b7e18cabd2 De-genericize some IntoDiagnostic impls.
These impls are all needed for just a single `IntoDiagnostic` type, not
a family of them.

Note that `ErrorGuaranteed` is the default type parameter for
`IntoDiagnostic`.
2023-12-04 18:57:42 +11:00
Esteban Küber
c47318983b Account for (pat if expr) => {}
When encountering match arm (pat if expr) => {}, recover and suggest removing parentheses. Fix #100825.
2023-11-29 18:47:32 +00:00
Esteban Küber
075c599188 More accurate span for unnecessary parens suggestion 2023-11-29 18:47:31 +00:00
Matthias Krüger
aab61d0b9a
Rollup merge of #118191 - estebank:let-chain-typo, r=compiler-errors
Suggest `let` or `==` on typo'd let-chain

When encountering a bare assignment in a let-chain, suggest turning the
assignment into a `let` expression or an equality check.

```
error: expected expression, found `let` statement
  --> $DIR/bad-if-let-suggestion.rs:5:8
   |
LL |     if let x = 1 && i = 2 {}
   |        ^^^^^^^^^
   |
   = note: only supported directly in conditions of `if` and `while` expressions
help: you might have meant to continue the let-chain
   |
LL |     if let x = 1 && let i = 2 {}
   |                     +++
help: you might have meant to compare for equality
   |
LL |     if let x = 1 && i == 2 {}
   |                        +
```
2023-11-29 12:34:48 +01:00
Esteban Küber
55e4e3e393 Suggest let or == on typo'd let-chain
When encountering a bare assignment in a let-chain, suggest turning the
assignment into a `let` expression or an equality check.

```
error: expected expression, found `let` statement
  --> $DIR/bad-if-let-suggestion.rs:5:8
   |
LL |     if let x = 1 && i = 2 {}
   |        ^^^^^^^^^
   |
   = note: only supported directly in conditions of `if` and `while` expressions
help: you might have meant to continue the let-chain
   |
LL |     if let x = 1 && let i = 2 {}
   |                     +++
help: you might have meant to compare for equality
   |
LL |     if let x = 1 && i == 2 {}
   |                        +
```
2023-11-28 18:07:52 +00:00
Hirochika Matsumoto
f4c2bdeec9 Suggest swapping the order of ref and box 2023-11-27 21:38:19 +09:00
Michael Goulet
a7f805d277
Rollup merge of #117891 - compiler-errors:recover-for-dyn, r=davidtwco
Recover `dyn` and `impl` after `for<...>`

Recover `dyn` and `impl` after `for<...>` in types. Reuses the logic for parsing bare trait objects, so it doesn't fix cases like `for<'a> dyn Trait + dyn Trait` or anything, but that seems somewhat of a different issue.

Parsing recovery logic is a bit involved, but I couldn't find a way to simplify it.

Fixes #117882
2023-11-19 19:14:33 -08:00
Esteban Küber
1c6bd0b12b Smaller span for unnessary mut suggestion 2023-11-16 16:58:41 +00:00
bohan
4138702621 discard invalid spans in external blocks 2023-11-15 15:28:38 +08:00
Michael Goulet
a8a2ee4e8f Recover dyn and impl after for<...> 2023-11-14 00:15:10 +00:00
bors
187d1afa9d Auto merge of #117297 - clubby789:fn-trait-missing-paren, r=TaKO8Ki
Give a better diagnostic for missing parens in Fn* bounds

Fixes #108109

It would be nice to try and recover here, but I'm not sure it's worth the effort, especially as the bounds on the recovered function would be incorrect.
2023-11-07 13:04:56 +00:00
Matthias Krüger
2b2360abb1
Rollup merge of #117298 - clubby789:fn-missing-params, r=petrochenkov
Recover from missing param list in function definitions

Addresses the other issue mentioned in #108109
2023-11-01 21:40:05 +01:00
clubby789
904aceec7d Give a better diagnostic for missing parens in Fn* bounds 2023-11-01 15:33:46 +00:00
clubby789
ca1bcb6466 Recover from missing param list in function definitions 2023-11-01 14:48:20 +00:00
Oli Scherer
745c600617 Talk about gen fn in diagnostics about gen fn 2023-10-30 10:13:12 +00:00
Oli Scherer
a61cf673cd Reserve gen keyword for gen {} blocks and gen fn in 2024 edition 2023-10-26 06:49:17 +00:00
Esteban Küber
745c1ea438 Detect missing => after match guard during parsing
```
error: expected one of `,`, `:`, or `}`, found `.`
  --> $DIR/missing-fat-arrow.rs:25:14
   |
LL |         Some(a) if a.value == b {
   |                               - while parsing this struct
LL |             a.value = 1;
   |             -^ expected one of `,`, `:`, or `}`
   |             |
   |             while parsing this struct field
   |
help: try naming a field
   |
LL |             a: a.value = 1;
   |             ++
help: you might have meant to start a match arm after the match guard
   |
LL |         Some(a) if a.value == b => {
   |                                 ++
```

Fix #78585.
2023-10-03 21:21:02 +00:00
Esteban Küber
3848ffcee7 Tweak wording of missing angle backets in qualified path 2023-09-28 00:37:20 +00:00