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
`}
`