Merge from rustc · rust-lang/rust@debf88a (original) (raw)

`@@ -681,22 +681,40 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere

`

681

681

`}

`

682

682

`}

`

683

683

``

``

684

`+

// The easiest way to implement token stream pretty printing would be to

`

``

685

`+

// print each token followed by a single space. But that would produce ugly

`

``

686

`+

// output, so we go to some effort to do better.

`

``

687

`+

//

`

``

688

`+

// First, we track whether each token that appears in source code is

`

``

689

`` +

// followed by a space, with Spacing, and reproduce that in the output.

``

``

690

`` +

// This works well in a lot of cases. E.g. stringify!(x + y) produces

``

``

691

`` +

// "x + y" and stringify!(x+y) produces "x+y".

``

``

692

`+

//

`

``

693

`+

// But this doesn't work for code produced by proc macros (which have no

`

``

694

`+

// original source text representation) nor for code produced by decl

`

``

695

`+

// macros (which are tricky because the whitespace after tokens appearing

`

``

696

`+

// in macro rules isn't always what you want in the produced output). For

`

``

697

`` +

// these we mostly use Spacing::Alone, which is the conservative choice.

``

``

698

`+

//

`

``

699

`` +

// So we have a backup mechanism for when Spacing::Alone occurs between a

``

``

700

`+

// pair of tokens: we check if that pair of tokens can obviously go

`

``

701

`` +

// together without a space between them. E.g. token x followed by token

``

``

702

`` +

// , is better printed as x, than x ,. (Even if the original source

``

``

703

`` +

// code was x ,.)

``

``

704

`+

//

`

``

705

`+

// Finally, we must be careful about changing the output. Token pretty

`

``

706

`` +

// printing is used by stringify! and `impl Display for

``

``

707

`` +

// proc_macro::TokenStream`, and some programs rely on the output having a

``

``

708

`+

// particular form, even though they shouldn't. In particular, some proc

`

``

709

`` +

// macros do format!({stream}) on a token stream and then "parse" the

``

``

710

`+

// output with simple string matching that can't handle whitespace changes.

`

``

711

`` +

// E.g. we have seen cases where a proc macro can handle a :: b but not

``

``

712

`` +

// a::b. See #117433 for some examples.

``

684

713

`fn print_tts(&mut self, tts: &TokenStream, convert_dollar_crate: bool) {

`

685

714

`let mut iter = tts.trees().peekable();

`

686

715

`while let Some(tt) = iter.next() {

`

687

716

`let spacing = self.print_tt(tt, convert_dollar_crate);

`

688

717

`if let Some(next) = iter.peek() {

`

689

``

`` -

// Should we print a space after tt? There are two guiding

``

690

``

`-

// factors.

`

691

``

`` -

// - spacing is the more important and accurate one. Most

``

692

``

`-

// tokens have good spacing information, and

`

693

``

`` -

// Joint/JointHidden get used a lot.

``

694

``

`` -

// - space_between is the backup. Code produced by proc

``

695

``

`-

// macros has worse spacing information, with no

`

696

``

`` -

// JointHidden usage and too much Alone usage, which

``

697

``

`-

// would result in over-spaced output such as

`

698

``

`` -

// ( x () , y . z ). space_between avoids some of the

``

699

``

`-

// excess whitespace.

`

700

718

`if spacing == Spacing::Alone && space_between(tt, next) {

`

701

719

`self.space();

`

702

720

`}

`