Commit graph

223 commits

Author SHA1 Message Date
Jules Bertholet
2a4624ddd1
Rename BindingAnnotation to BindingMode 2024-04-17 09:34:39 -04:00
bors
4e1f5d90bc Auto merge of #123468 - compiler-errors:precise-capturing, r=oli-obk
Implement syntax for `impl Trait` to specify its captures explicitly (`feature(precise_capturing)`)

Implements `impl use<'a, 'b, T, U> Sized` syntax that allows users to explicitly list the captured parameters for an opaque, rather than inferring it from the opaque's bounds (or capturing *all* lifetimes under 2024-edition capture rules). This allows us to exclude some implicit captures, so this syntax may be used as a migration strategy for changes due to #117587.

We represent this list of captured params as `PreciseCapturingArg` in AST and HIR, resolving them between `rustc_resolve` and `resolve_bound_vars`. Later on, we validate that the opaques only capture the parameters in this list.

We artificially limit the feature to *require* mentioning all type and const parameters, since we don't currently have support for non-lifetime bivariant generics. This can be relaxed in the future.

We also may need to limit this to require naming *all* lifetime parameters for RPITIT, since GATs have no variance. I have to investigate this. This can also be relaxed in the future.

r? `@oli-obk`

Tracking issue:

- https://github.com/rust-lang/rust/issues/123432
2024-04-16 11:22:35 +00:00
León Orell Valerian Liehr
c5665990c5
Rollup merge of #123462 - fmease:rn-mod-sep-to-path-sep, r=nnethercote
Cleanup: Rename `ModSep` to `PathSep`

`::` is usually referred to as the *path separator* (citation needed).

The existing name `ModSep` for *module separator* is a bit misleading since it in fact separates the segments of arbitrary path segments, not only ones resolving to modules. Let me just give a shout-out to associated items (`T::Assoc`, `<Ty as Trait>::function`) and enum variants (`Option::None`).

Motivation: Reduce friction for new contributors, prevent potential confusion.

cc `@petrochenkov`
r? nnethercote or compiler
2024-04-16 01:12:37 +02:00
Michael Goulet
52c6b101ea Use a path instead of an ident (and stop manually resolving) 2024-04-15 16:45:26 -04:00
Michael Goulet
42ba57c013 Validation and other things 2024-04-15 16:45:01 -04:00
Michael Goulet
a076eae0d2 Parsing , pre-lowering support for precise captures 2024-04-15 16:45:01 -04:00
Oli Scherer
fc27a91880 Add pattern types to ast 2024-04-08 11:54:22 +00:00
León Orell Valerian Liehr
3cbc9e9560
Rename ModSep to PathSep 2024-04-04 19:44:04 +02:00
Jules Bertholet
e0da13f25f
Implement mut ref/mut ref mut 2024-03-27 09:53:23 -04:00
Michael Goulet
2d633317f3 Implement macro-based deref!() syntax for deref patterns
Stop using `box PAT` syntax for deref patterns, as it's misleading and
also causes their semantics being tangled up.
2024-03-21 11:42:49 -04: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
Nicholas Nethercote
69f2c9c101 Move gather_comments.
To the module where it is used, so it doesn't have to be `pub`.
2024-03-01 08:34:42 +11:00
Gary Guo
93fa8579c6 Add asm label support to AST and HIR 2024-02-24 18:49:39 +00:00
clubby789
06d6c62f80 Add newtype for raw idents 2024-02-20 13:13:29 +00:00
Guillaume Gomez
c73aa787f6
Rollup merge of #121109 - nnethercote:TyKind-Err-guar-2, r=oli-obk
Add an ErrorGuaranteed to ast::TyKind::Err (attempt 2)

This makes it more like `hir::TyKind::Err`, and avoids a `has_errors` assertion in `LoweringContext::lower_ty_direct`.

r? ```@oli-obk```
2024-02-16 00:27:32 +01:00
Nicholas Nethercote
25ed6e43b0 Add ErrorGuaranteed to ast::LitKind::Err, token::LitKind::Err.
This mostly works well, and eliminates a couple of delayed bugs.

One annoying thing is that we should really also add an
`ErrorGuaranteed` to `proc_macro::bridge::LitKind::Err`. But that's
difficult because `proc_macro` doesn't have access to `ErrorGuaranteed`,
so we have to fake it.
2024-02-15 14:46:08 +11:00
Nicholas Nethercote
5233bc91da Add an ErrorGuaranteed to ast::TyKind::Err.
This makes it more like `hir::TyKind::Err`, and avoids a
`span_delayed_bug` call in `LoweringContext::lower_ty_direct`.

It also requires adding `ast::TyKind::Dummy`, now that
`ast::TyKind::Err` can't be used for that purpose in the absence of an
error emission.

There are a couple of cases that aren't as neat as I would have liked,
marked with `FIXME` comments.
2024-02-15 09:35:11 +11:00
Frank King
879a1e5713 Lower anonymous structs or unions to HIR 2024-02-12 12:47:23 +08:00
Michael Goulet
0eb2adb7e8 Add async bound modifier to enable async Fn bounds 2024-01-31 16:59:19 +00:00
Nicholas Nethercote
1fbabeeb2e Fix some cases in space_between.
There are a number of cases where we erroneously omit the space between
two tokens, all involving an exception to a more general case. The
affected tokens are `$`, `!`, `.`, `,`, and `let` followed by a
parenthesis.

This fixes a lot of FIXME comments.
2024-01-22 20:19:17 +11:00
Nicholas Nethercote
41e4a3e086 Don't insert spaces before most semicolons in print_tts.
This gives better output for code produced by proc macros.
2024-01-22 20:14:59 +11:00
Lieselotte
7889e99b55
Add PatKind::Err 2024-01-17 03:14:16 +01:00
bors
89e2160c4c Auto merge of #119105 - dtolnay:paren, r=WaffleLapkin
Fix parenthesization of subexprs containing statement boundary

This PR fixes a multitude of false negatives and false positives in the AST pretty printer's parenthesis insertion related to statement boundaries &mdash; statements which terminate unexpectedly early if there aren't parentheses.

Without this fix, the AST pretty printer (including both `stringify!` and `rustc -Zunpretty=expanded`) is prone to producing output which is not syntactically valid Rust. Invalid output is problematic because it means Rustfmt is unable to parse the output of `cargo expand`, for example, causing friction by forcing someone trying to debug a macro into reading poorly formatted code.

I believe the set of bugs fixed in this PR account for the most prevalent reason that `cargo expand` produces invalid output in real-world usage.

Fixes #98790.

## False negatives

The following is a correct program &mdash; `cargo check` succeeds.

```rust
macro_rules! m {
    ($e:expr) => {
        match () { _ => $e }
    };
}

fn main() {
    m!({ 1 } - 1);
}
```

But `rustc -Zunpretty=expanded main.rs` produces output that is invalid Rust syntax, because parenthesization is needed and not being done by the pretty printer.

```rust
fn main() { match () { _ => { 1 } - 1, }; }
```

Piping this expanded code to rustfmt, it fails to parse.

```console
error: unexpected `,` in pattern
 --> <stdin>:1:38
  |
1 | fn main() { match () { _ => { 1 } - 1, }; }
  |                                      ^
  |
help: try adding parentheses to match on a tuple...
  |
1 | fn main() { match () { _ => { 1 } (- 1,) }; }
  |                                   +    +
help: ...or a vertical bar to match on multiple alternatives
  |
1 | fn main() { match () { _ => { 1 } - 1 | }; }
  |                                   ~~~~~
```

Fixed output after this PR:

```rust
fn main() { match () { _ => ({ 1 }) - 1, }; }
```

## False positives

Less problematic, but worth fixing (just like #118726).

```rust
fn main() {
    let _ = match () { _ => 1 } - 1;
}
```

Output of `rustc -Zunpretty=expanded lib.rs` before this PR. There is no reason parentheses would need to be inserted there.

```rust
fn main() { let _ = (match () { _ => 1, }) - 1; }
```

After this PR:

```rust
fn main() { let _ = match () { _ => 1, } - 1; }
```

## Alternatives considered

In this PR I opted to parenthesize only the leading subexpression causing the statement boundary, rather than the entire statement. Example:

```rust
macro_rules! m {
    ($e:expr) => {
        $e
    };
}

fn main() {
    m!(loop { break [1]; }[0] - 1);
}
```

This PR produces the following pretty-printed contents for fn main:

```rust
(loop { break [1]; })[0] - 1;
```

A different equally correct output would be:

```rust
(loop { break [1]; }[0] - 1);
```

I chose the one I did because it is the *only* approach used by handwritten code in the standard library and compiler. There are 4 places where parenthesization is being used to prevent a statement boundary, and in all 4, the developer has chosen to parenthesize the smallest subexpression rather than the whole statement:

b37d43efd9/compiler/rustc_codegen_cranelift/example/alloc_system.rs (L102)

b37d43efd9/compiler/rustc_parse/src/errors.rs (L1021-L1029)

b37d43efd9/library/core/src/future/poll_fn.rs (L151)

b37d43efd9/library/core/src/ops/range.rs (L824-L828)
2023-12-27 21:27:26 +00:00
León Orell Valerian Liehr
3eb48a35c8
Introduce const Trait (always-const trait bounds) 2023-12-27 12:51:32 +01: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
León Orell Valerian Liehr
5e4f12b41a
Refactor AST trait bound modifiers 2023-12-20 19:39:46 +01:00
David Tolnay
17239d9b64
Fix parenthesization of subexprs containing statement boundary 2023-12-18 22:40:48 -08:00
Ross Smyth
663bea5a96 Add better ICE messages for some undescriptive panics 2023-12-15 00:50:55 -05:00
Matthias Krüger
3a0562b93c
Rollup merge of #118726 - dtolnay:matchguardlet, r=compiler-errors
Do not parenthesize exterior struct lit inside match guards

Before this PR, the AST pretty-printer injects parentheses around expressions any time parens _could_ be needed depending on what else is in the code that surrounds that expression. But the pretty-printer did not pass around enough context to understand whether parentheses really _are_ needed on any particular expression. As a consequence, there are false positives where unneeded parentheses are being inserted.

Example:

```rust
#![feature(if_let_guard)]

macro_rules! pp {
    ($e:expr) => {
        stringify!($e)
    };
}

fn main() {
    println!("{}", pp!(match () { () if let _ = Struct {} => {} }));
}
```

**Before:**

```console
match () { () if let _ = (Struct {}) => {} }
```

**After:**

```console
match () { () if let _ = Struct {} => {} }
```

This PR introduces a bit of state that is passed across various expression printing methods to help understand accurately whether particular situations require parentheses injected by the pretty printer, and it fixes one such false positive involving match guards as shown above.

There are other parenthesization false positive cases not fixed by this PR. I intend to address these in follow-up PRs. For example here is one: the expression `{ let _ = match x {} + 1; }` is pretty-printed as `{ let _ = (match x {}) + 1; }` despite there being no reason for parentheses to appear there.
2023-12-11 20:46:49 +01: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
David Tolnay
8997215a24
Fix tidy ```ignore error
tidy error: /git/rust/compiler/rustc_ast_pretty/src/pprust/state.rs:1165: unexplained "```ignore" doctest; try one:

    * make the test actually pass, by adding necessary imports and declarations, or
    * use "```text", if the code is not Rust code, or
    * use "```compile_fail,Ennnn", if the code is expected to fail at compile time, or
    * use "```should_panic", if the code is expected to fail at run time, or
    * use "```no_run", if the code should type-check but not necessary linkable/runnable, or
    * explain it like "```ignore (cannot-test-this-because-xxxx)", if the annotation cannot be avoided.

    tidy error: /git/rust/compiler/rustc_ast_pretty/src/pprust/state.rs:1176: unexplained "```ignore" doctest; try one:

    * make the test actually pass, by adding necessary imports and declarations, or
    * use "```text", if the code is not Rust code, or
    * use "```compile_fail,Ennnn", if the code is expected to fail at compile time, or
    * use "```should_panic", if the code is expected to fail at run time, or
    * use "```no_run", if the code should type-check but not necessary linkable/runnable, or
    * explain it like "```ignore (cannot-test-this-because-xxxx)", if the annotation cannot be avoided.
2023-12-08 15:15:44 -08:00
David Tolnay
6f1d7631fb
Do not parenthesize exterior struct lit inside match guards 2023-12-08 15:15:42 -08:00
David Tolnay
7f314acc34
Delete special handling of some expr kinds from print_let
In all four of Break, Closure, Ret, Yeet, the needs_par_as_let_scrutinee
is guaranteed to return true because the .precedence().order() of those
expr kinds is <= AssocOp::LAnd.precedence().

The relevant functions in rustc_ast::util::parser are:

    fn needs_par_as_let_scrutinee(order: i8) -> bool {
        order <= prec_let_scrutinee_needs_par() as i8
    }

    fn prec_let_scrutinee_needs_par() -> usize {
        AssocOp::LAnd.precedence()
    }

The .precedence().order() of Closure is PREC_CLOSURE (-40) and of Break,
Ret, Yeet is PREC_JUMP (-30).

The value of AssocOp::LAnd.precedence() is 6.

So this commit causes no change in behavior, only potentially
performance by doing a redundant call to contains_exterior_struct_lit in
those four cases. This is fine because Break, Closure, Ret, Yeet should
be exceedingly rare in the position of a let scrutinee.
2023-12-08 15:14:44 -08:00
David Tolnay
dc5ec724c0
Rearrange logic of needs_par computation in print_let
True || needs_par_as_let_scrutinee(...) is always true.
2023-12-08 15:14:44 -08:00
David Tolnay
8d64961589
Inline cond_needs_par into print_let 2023-12-08 15:14:44 -08:00
David Tolnay
d2b7bd4774
Inline npals closure 2023-12-08 15:14:44 -08:00
Michael Goulet
a208bae00e Support async gen fn 2023-12-08 17:23:26 +00:00
Michael Goulet
2806c2df7b coro_kind -> coroutine_kind 2023-12-08 17:23:25 +00:00
Eric Holk
f9d1f922dc
Option<CoroutineKind> 2023-12-04 13:03:37 -08:00
Eric Holk
48d5f1f0f2
Merge Async and Gen into CoroutineKind 2023-12-04 12:48:01 -08:00
Matthias Krüger
c03f8917ee
Rollup merge of #118157 - Nadrieril:never_pat-feature-gate, r=compiler-errors
Add `never_patterns` feature gate

This PR adds the feature gate and most basic parsing for the experimental `never_patterns` feature. See the tracking issue (https://github.com/rust-lang/rust/issues/118155) for details on the experiment.

`@scottmcm` has agreed to be my lang-team liaison for this experiment.
2023-11-29 12:34:47 +01:00
Nadrieril
a3838c8550 Add never_patterns feature gate 2023-11-29 03:58:29 +01:00
Nicholas Nethercote
566df2722a Fix some backticks in comments. 2023-11-27 09:38:58 +11:00
Deadbeef
16040a1628 Add Span to TraitBoundModifier 2023-11-24 14:32:05 +00:00
bors
cc4bb0de20 Auto merge of #117928 - nnethercote:rustc_ast_pretty, r=fee1-dead
`rustc_ast_pretty` cleanups

Some improvements I found while looking at this code.

r? `@fee1-dead`
2023-11-22 05:09:33 +00:00
Nicholas Nethercote
9fe6bb4a10 Add some comments. 2023-11-22 11:06:16 +11:00
Nicholas Nethercote
10c8b56af1 Factor out common code in PrintState.
The AST and HIR versions of `State::print_ident` are textually
identical, but the types differ slightly. This commit factors out the
common code they both have by replacing `print_ident` with `ann_post`,
which is a smaller function that still captures the type difference.
2023-11-22 08:13:21 +11:00