Commit Graph

143 Commits

Author SHA1 Message Date
Nicholas Nethercote
332dffb1f9 Remove TreeAndSpacing.
A `TokenStream` contains a `Lrc<Vec<(TokenTree, Spacing)>>`. But this is
not quite right. `Spacing` makes sense for `TokenTree::Token`, but does
not make sense for `TokenTree::Delimited`, because a
`TokenTree::Delimited` cannot be joined with another `TokenTree`.

This commit fixes this problem, by adding `Spacing` to `TokenTree::Token`,
changing `TokenStream` to contain a `Lrc<Vec<TokenTree>>`, and removing the
`TreeAndSpacing` typedef.

The commit removes these two impls:
- `impl From<TokenTree> for TokenStream`
- `impl From<TokenTree> for TreeAndSpacing`

These were useful, but also resulted in code with many `.into()` calls
that was hard to read, particularly for anyone not highly familiar with
the relevant types. This commit makes some other changes to compensate:
- `TokenTree::token()` becomes `TokenTree::token_{alone,joint}()`.
- `TokenStream::token_{alone,joint}()` are added.
- `TokenStream::delimited` is added.

This results in things like this:
```rust
TokenTree::token(token::Semi, stmt.span).into()
```
changing to this:
```rust
TokenStream::token_alone(token::Semi, stmt.span)
```
This makes the type of the result, and its spacing, clearer.

These changes also simplifies `Cursor` and `CursorRef`, because they no longer
need to distinguish between `next` and `next_with_spacing`.
2022-07-29 15:52:15 +10:00
Maybe Waffle
40ae7b5b8e Parse closure binders
This is first step in implementing RFC 3216.
- Parse `for<'a>` before closures in ast
  - Error in lowering
- Add `closure_lifetime_binder` feature
2022-07-12 16:25:16 +04:00
Nixon Enraght-Moony
18ca2946e0 ast: Add span to Extern 2022-07-02 23:30:03 +01:00
David Tolnay
fe9635f7c0
Fix pretty printing of empty type bound lists in where-clause 2022-06-16 17:24:50 -07:00
Nicholas Nethercote
77e1069a5d Revert #96682.
The change was "Show invisible delimiters (within comments) when pretty
printing". It's useful to show these delimiters, but is a breaking
change for some proc macros.

Fixes #97608.
2022-06-02 11:22:16 +10:00
Dylan DPC
b73f1c77a7
Rollup merge of #97254 - jhpratt:remove-crate-vis, r=cjgillot
Remove feature: `crate` visibility modifier

FCP completed in #53120.
2022-05-23 07:43:50 +02:00
Vadim Petrochenkov
8e8fb4f49e rustc_parse: Move AST -> TokenStream conversion logic to rustc_ast 2022-05-22 12:01:07 +03:00
Jacob Pratt
7b987e34c0
Merge crate and restricted visibilities 2022-05-21 17:02:55 -04:00
Jacob Pratt
8cece636b2
Remove feature: crate visibility modifier 2022-05-21 14:22:06 -04:00
Jacob Pratt
49c82f31a8
Remove crate visibility usage in compiler 2022-05-20 20:04:54 -04:00
klensy
cc5f3e21ac use CursorRef more, to not to clone Trees 2022-05-18 18:43:48 +03:00
Vadim Petrochenkov
f2b7fa4847 ast: Introduce some traits to get AST node properties generically
And use them to avoid constructing some artificial `Nonterminal` tokens during expansion
2022-05-11 12:43:27 +03:00
Matthias Krüger
7a915dd80d
Rollup merge of #96682 - nnethercote:show-invisible-delims, r=petrochenkov
Show invisible delimeters (within comments) when pretty printing.

Because invisible syntax is really hard to work with!

r? `@petrochenkov`
2022-05-05 15:43:05 +02:00
bors
4c60a0ea5b Auto merge of #96546 - nnethercote:overhaul-MacArgs, r=petrochenkov
Overhaul `MacArgs`

Motivation:
- Clarify some code that I found hard to understand.
- Eliminate one use of three places where `TokenKind::Interpolated` values are created.

r? `@petrochenkov`
2022-05-04 21:16:28 +00:00
Nicholas Nethercote
99f5945f85 Overhaul MacArgs::Eq.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.

This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.

Things to note:
- Error messages have improved. Messages like this:
  ```
  unexpected token: `"bug" + "found"`
  ```
  now say "unexpected expression", which makes more sense. Although
  arbitrary expressions can exist within tokens thanks to
  `TokenKind::Interpolated`, that's not obvious to anyone who doesn't
  know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
  the value expression.
2022-05-05 07:06:12 +10:00
Nicholas Nethercote
5022d764cf Show invisible delimeters (within comments) when pretty printing. 2022-05-04 10:06:06 +10:00
Scott McMurray
e094ee5f10 Add do yeet expressions to allow experimentation in nightly
Using an obviously-placeholder syntax.  An RFC would still be needed before this could have any chance at stabilization, and it might be removed at any point.

But I'd really like to have it in nightly at least to ensure it works well with try_trait_v2, especially as we refactor the traits.
2022-04-30 17:40:27 -07:00
Nicholas Nethercote
5a05b614bf Tweak print_attr_item.
This commit rearranges the `match`. The new code avoids testing for
`MacArgs::Eq` twice, at the cost of repeating the `self.print_path()`
call. I think this is worthwhile because it puts the `match` in a more
standard and readable form.
2022-04-29 15:00:32 +10:00
Vadim Petrochenkov
2733ec1be3 rustc_ast: Harmonize delimiter naming with proc_macro::Delimiter 2022-04-28 10:04:29 +03:00
Nicholas Nethercote
6b367a0532 Avoid producing NoDelim values in MacArgs::delim(). 2022-04-27 08:15:12 +10:00
Dylan DPC
22d554657d
Rollup merge of #94985 - dtolnay:constattr, r=pnkfelix
Parse inner attributes on inline const block

According to https://github.com/rust-lang/rust/pull/84414#issuecomment-826150936, inner attributes are intended to be supported *"in all containers for statements (or some subset of statements)"*.

This PR adds inner attribute parsing and pretty-printing for inline const blocks (https://github.com/rust-lang/rust/issues/76001), which contain statements just like an unsafe block or a loop body.

```rust
let _ = const {
    #![allow(...)]

    let x = ();
    x
};
```
2022-04-16 19:42:00 +02:00
Amanieu d'Antras
dc345d8bff Reimplement lowering of sym operands for asm! so that it also works with global_asm! 2022-04-14 15:32:03 +01:00
Nicholas Nethercote
364b908d57 Remove Nonterminal::NtTT.
It's only needed for macro expansion, not as a general element in the
AST. This commit removes it, adds `NtOrTt` for the parser and macro
expansion cases, and renames the variants in `NamedMatch` to better
match the new type.
2022-03-28 10:03:02 +11:00
David Tolnay
f427698c03
Parse inner attributes on inline const block 2022-03-15 17:56:59 -07:00
Jack Huey
c20b4f5584 Change syntax for TyAlias where clauses 2022-03-05 13:13:45 -05:00
David Tolnay
d1b9e4a6f2
Pretty print ItemKind::Use in rustfmt style 2022-02-07 21:51:05 -08:00
David Tolnay
40fcbbafa0
Change struct expr pretty printing to match rustfmt style 2022-02-03 10:59:35 -08:00
David Tolnay
8bdf08fbed
Change pp indent to signed to allow negative indents 2022-02-03 10:59:09 -08:00
David Tolnay
125c729e05
Restore a visual alignment mode for block comments 2022-01-30 19:50:54 -08:00
David Tolnay
8ac05b9766
Fix some double indents on exprs containing blocks
The `print_expr` method already places an `ibox(INDENT_UNIT)` around
every expr that gets printed. Some exprs were then using `self.head`
inside of that, which does its own `cbox(INDENT_UNIT)`, resulting in two
levels of indentation:

    while true {
            stuff;
        }

This commit fixes those cases to produce the expected single level of
indentation within every expression containing a block.

    while true {
        stuff;
    }
2022-01-30 19:45:00 -08:00
David Tolnay
cb93e9c0ec
Compute indent never relative to current column
Previously the pretty printer would compute indentation always relative
to whatever column a block begins at, like this:

    fn demo(arg1: usize,
            arg2: usize);

This is never the thing to do in the dominant contemporary Rust style.
Rustfmt's default and the style used by the vast majority of Rust
codebases is block indentation:

    fn demo(
        arg1: usize,
        arg2: usize,
    );

where every indentation level is a multiple of 4 spaces and each level
is indented relative to the indentation of the previous line, not the
position that the block starts in.
2022-01-30 19:44:59 -08:00
lcnr
2684dfe583 try apply rustc_pass_by_value to Span 2022-01-27 11:29:41 +01:00
Matthias Krüger
fe93f08051
Rollup merge of #93065 - dtolnay:ringbuffer, r=lcnr
Pretty printer algorithm revamp step 2

This PR follows #92923 as a second chunk of modernizations backported from https://github.com/dtolnay/prettyplease into rustc_ast_pretty.

I've broken this up into atomic commits that hopefully are sensible in isolation. At every commit, the pretty printer is compilable and has runtime behavior that is identical to before and after the PR. None of the refactoring so far changes behavior.

The general theme of this chunk of commits is: the logic in the old pretty printer is doing some very basic things (pushing and popping tokens on a ring buffer) but expressed in a too-low-level way that I found makes it quite complicated/subtle to reason about. There are a number of obvious invariants that are "almost true" -- things like `self.left == self.buf.offset` and `self.right == self.buf.offset + self.buf.data.len()` and `self.right_total == self.left_total + self.buf.data.sum()`. The reason these things are "almost true" is the implementation tends to put updating one side of the invariant unreasonably far apart from updating the other side, leaving the invariant broken while unrelated stuff happens in between. The following code from master is an example of this:

e5e2b0be26/compiler/rustc_ast_pretty/src/pp.rs (L314-L317)

In this code the `advance_right` is reserving an entry into which to write a next token on the right side of the ring buffer, the `check_stack` is doing something totally unrelated to the right boundary of the ring buffer, and the `scan_push` is actually writing the token we previously reserved space for. Much of what this PR is doing is rearranging code to shrink the amount of stuff in between when an invariant is broken to when it is restored, until the whole thing can be factored out into one indivisible method call on the RingBuffer type.

The end state of the PR is that we can entirely eliminate `self.left` (because it's now just equal to `self.buf.offset` always) and `self.right` (because it's equal to `self.buf.offset + self.buf.data.len()` always) and the whole `Token::Eof` state which used to be the value of tokens that have been reserved space for but not yet written.

I found without these changes the pretty printer implementation to be hard to reason about and I wasn't able to confidently introduce improvements like trailing commas in `prettyplease` until after this refactor. The logic here is 43 years old at this point (Graydon translated it as directly as possible from the 1979 pretty printing paper) and while there are advantages to following the paper as closely as possible, in `prettyplease` I decided if we're going to adapt the algorithm to work better for Rust syntax, it was worthwhile making it easier to follow than the original.
2022-01-19 19:19:51 +01:00
David Tolnay
cc66a7ff20
Eliminate eof token state 2022-01-18 20:08:52 -08:00
David Tolnay
07a0325137
Move item-related pretty printing functions to module 2022-01-18 12:39:20 -08:00
David Tolnay
b1605643e3
Move expr-related pretty printing functions to module 2022-01-18 12:39:19 -08:00
kadmin
67f56671d0 Use Term in ProjectionPredicate
ProjectionPredicate should be able to handle both associated types and consts so this adds the
first step of that. It mainly just pipes types all the way down, not entirely sure how to handle
consts, but hopefully that'll come with time.
2022-01-17 17:44:56 +00:00
kadmin
fb57b7518d Add term
Instead of having a separate enum variant for types and consts have one but have either a const
or type.
2022-01-17 17:20:57 +00:00
kadmin
0765999622 add eq constraints on associated constants 2022-01-17 17:20:57 +00:00
bors
a34c079752 Auto merge of #92816 - tmiasko:rm-llvm-asm, r=Amanieu
Remove deprecated LLVM-style inline assembly

The `llvm_asm!` was deprecated back in #87590 1.56.0, with intention to remove
it once `asm!` was stabilized, which already happened in #91728 1.59.0. Now it
is time to remove `llvm_asm!` to avoid continued maintenance cost.

Closes #70173.
Closes #92794.
Closes #87612.
Closes #82065.

cc `@rust-lang/wg-inline-asm`

r? `@Amanieu`
2022-01-17 09:40:29 +00:00
Matthias Krüger
216ce7c519
Rollup merge of #92921 - dtolnay:printernew, r=wesleywiser
Rename Printer constructor from mk_printer() to Printer::new()

The original naming is left over from 2011 which was before impl blocks and associated functions existed.

21313d623a/src/comp/pretty/pp.rs
2022-01-17 06:08:16 +01:00
Matthias Krüger
9527533408
Rollup merge of #92487 - dtolnay:traitalias, r=matthewjasper
Fix unclosed boxes in pretty printing of TraitAlias

This was causing trait aliases to not even render at all in stringified / pretty printed output.

```rust
macro_rules! repro {
    ($item:item) => {
        stringify!($item)
    };
}

fn main() {
    println!("{:?}", repro!(pub trait Trait<T> = Sized where T: 'a;));
}
```

Before:&ensp;`""`
After:&ensp;`"pub trait Trait<T> = Sized where T: 'a;"`

The fix is copied from how `head`/`end` for `ItemKind::Use`, `ItemKind::ExternCrate`, and `ItemKind::Mod` are all done in the pretty printer:

dd3ac41495/compiler/rustc_ast_pretty/src/pprust/state.rs (L1178-L1184)
2022-01-16 16:58:10 +01:00
David Tolnay
953da9832d
Rename Printer constructor from mk_printer() to Printer::new() 2022-01-14 21:12:39 -08:00
Tomasz Miąsko
000b36c505 Remove deprecated LLVM-style inline assembly 2022-01-12 18:51:31 +01:00
Eric Huss
81c515bf77
Rollup merge of #92336 - dtolnay:printstateself, r=michaelwoerister
Remove &self from PrintState::to_string

The point of `PrintState::to_string` is to create a `State` and evaluate the caller's closure on it:

e9fbe79292/compiler/rustc_ast_pretty/src/pprust/state.rs (L868-L872)

Making the caller *also* construct and pass in a `State`, which is then ignored, was confusing.
2022-01-07 20:20:56 -08:00
Matthias Krüger
1a8f69826c
Rollup merge of #92417 - dtolnay:printimpl, r=jackh726
Fix spacing and ordering of words in pretty printed Impl

Follow-up to #92238 fixing one of the FIXMEs.

```rust
macro_rules! repro {
    ($item:item) => {
        stringify!($item)
    };
}

fn main() {
    println!("{}", repro!(impl<T> Struct<T> {}));
    println!("{}", repro!(impl<T> const Trait for T {}));
}
```

Before:&ensp;`impl <T> Struct<T> {}`
After:&ensp;`impl<T> Struct<T> {}`

Before:&ensp;`impl const <T> Trait for T {}` 😿
After:&ensp;`impl<T> const Trait for T {}`
2022-01-06 23:15:16 +01:00
Matthias Krüger
df921190f3
Rollup merge of #92418 - dtolnay:emptystructpat, r=michaelwoerister
Fix spacing in pretty printed PatKind::Struct with no fields

Follow-up to #92238 fixing one of the FIXMEs.

```rust
macro_rules! repro {
    ($pat:pat) => {
        stringify!($pat)
    };
}

fn main() {
    println!("{}", repro!(Struct {}));
}
```

Before:&ensp;<code>Struct&nbsp;{&nbsp;&nbsp;}</code>
After:&ensp;<code>Struct&nbsp;{}</code>
2022-01-03 14:44:20 +01:00
David Tolnay
a18f43f25d
Fix unclosed boxes in pretty printing of TraitAlias 2022-01-01 18:02:00 -08:00
Matthias Krüger
efe415878b
Rollup merge of #92420 - dtolnay:patrange, r=Mark-Simulacrum
Fix whitespace in pretty printed PatKind::Range

Follow-up to #92238 fixing one of the FIXMEs.

```rust
macro_rules! repro {
    ($pat:pat) => {
        stringify!($pat)
    };
}

fn main() {
    println!("{}", repro!(0..=1));
}
```

Before:&ensp;`0 ..=1`
After:&ensp;`0..=1`

The canonical spacing applied by rustfmt has no space after the lower expr. Rustc's parser diagnostics also do not put a space there:

df96fb166f/compiler/rustc_parse/src/parser/pat.rs (L754)
2022-01-01 10:48:56 +01:00
Matthias Krüger
682b4cbc4e
Rollup merge of #92412 - dtolnay:tryspace, r=Mark-Simulacrum
Fix double space in pretty printed TryBlock

Follow-up to #92238 fixing one of the FIXMEs.

```rust
macro_rules! repro {
    ($expr:expr) => {
        stringify!($expr)
    };
}

fn main() {
    println!("{}", repro!(try {}));
}
```

Before:&ensp;<code>try&nbsp;&nbsp;{}</code>
After:&ensp;<code>try&nbsp;{}</code>

The `head` helper already appends a space:

2b67c30bfe/compiler/rustc_ast_pretty/src/pprust/state.rs (L654-L664)

so doing `head` followed by `space` resulted in a double space:

2b67c30bfe/compiler/rustc_ast_pretty/src/pprust/state.rs (L2241-L2242)
2022-01-01 10:48:55 +01:00