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.
This commit is contained in:
parent
7e452c123c
commit
925f7fad57
@ -99,6 +99,11 @@ impl TokenTree {
|
|||||||
TokenTree::Token(Token::new(kind, span), Spacing::Joint)
|
TokenTree::Token(Token::new(kind, span), Spacing::Joint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a `TokenTree::Token` with joint-hidden spacing.
|
||||||
|
pub fn token_joint_hidden(kind: TokenKind, span: Span) -> TokenTree {
|
||||||
|
TokenTree::Token(Token::new(kind, span), Spacing::JointHidden)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn uninterpolate(&self) -> Cow<'_, TokenTree> {
|
pub fn uninterpolate(&self) -> Cow<'_, TokenTree> {
|
||||||
match self {
|
match self {
|
||||||
TokenTree::Token(token, spacing) => match token.uninterpolate() {
|
TokenTree::Token(token, spacing) => match token.uninterpolate() {
|
||||||
@ -303,21 +308,64 @@ pub struct AttributesData {
|
|||||||
#[derive(Clone, Debug, Default, Encodable, Decodable)]
|
#[derive(Clone, Debug, Default, Encodable, Decodable)]
|
||||||
pub struct TokenStream(pub(crate) Lrc<Vec<TokenTree>>);
|
pub struct TokenStream(pub(crate) Lrc<Vec<TokenTree>>);
|
||||||
|
|
||||||
/// Similar to `proc_macro::Spacing`, but for tokens.
|
/// Indicates whether a token can join with the following token to form a
|
||||||
///
|
/// compound token. Used for conversions to `proc_macro::Spacing`. Also used to
|
||||||
/// Note that all `ast::TokenTree::Token` instances have a `Spacing`, but when
|
/// guide pretty-printing, which is where the `JointHidden` value (which isn't
|
||||||
/// we convert to `proc_macro::TokenTree` for proc macros only `Punct`
|
/// part of `proc_macro::Spacing`) comes in useful.
|
||||||
/// `TokenTree`s have a `proc_macro::Spacing`.
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
||||||
pub enum Spacing {
|
pub enum Spacing {
|
||||||
/// The token is not immediately followed by an operator token (as
|
/// The token cannot join with the following token to form a compound
|
||||||
/// determined by `Token::is_op`). E.g. a `+` token is `Alone` in `+ =`,
|
/// token.
|
||||||
/// `+/*foo*/=`, `+ident`, and `+()`.
|
///
|
||||||
|
/// In token streams parsed from source code, the compiler will use `Alone`
|
||||||
|
/// for any token immediately followed by whitespace, a non-doc comment, or
|
||||||
|
/// EOF.
|
||||||
|
///
|
||||||
|
/// When constructing token streams within the compiler, use this for each
|
||||||
|
/// token that (a) should be pretty-printed with a space after it, or (b)
|
||||||
|
/// is the last token in the stream. (In the latter case the choice of
|
||||||
|
/// spacing doesn't matter because it is never used for the last token. We
|
||||||
|
/// arbitrarily use `Alone`.)
|
||||||
|
///
|
||||||
|
/// Converts to `proc_macro::Spacing::Alone`, and
|
||||||
|
/// `proc_macro::Spacing::Alone` converts back to this.
|
||||||
Alone,
|
Alone,
|
||||||
|
|
||||||
/// The token is immediately followed by an operator token. E.g. a `+`
|
/// The token can join with the following token to form a compound token.
|
||||||
/// token is `Joint` in `+=` and `++`.
|
///
|
||||||
|
/// In token streams parsed from source code, the compiler will use `Joint`
|
||||||
|
/// for any token immediately followed by punctuation (as determined by
|
||||||
|
/// `Token::is_punct`).
|
||||||
|
///
|
||||||
|
/// When constructing token streams within the compiler, use this for each
|
||||||
|
/// token that (a) should be pretty-printed without a space after it, and
|
||||||
|
/// (b) is followed by a punctuation token.
|
||||||
|
///
|
||||||
|
/// Converts to `proc_macro::Spacing::Joint`, and
|
||||||
|
/// `proc_macro::Spacing::Joint` converts back to this.
|
||||||
Joint,
|
Joint,
|
||||||
|
|
||||||
|
/// The token can join with the following token to form a compound token,
|
||||||
|
/// but this will not be visible at the proc macro level. (This is what the
|
||||||
|
/// `Hidden` means; see below.)
|
||||||
|
///
|
||||||
|
/// In token streams parsed from source code, the compiler will use
|
||||||
|
/// `JointHidden` for any token immediately followed by anything not
|
||||||
|
/// covered by the `Alone` and `Joint` cases: an identifier, lifetime,
|
||||||
|
/// literal, delimiter, doc comment.
|
||||||
|
///
|
||||||
|
/// When constructing token streams, use this for each token that (a)
|
||||||
|
/// should be pretty-printed without a space after it, and (b) is followed
|
||||||
|
/// by a non-punctuation token.
|
||||||
|
///
|
||||||
|
/// Converts to `proc_macro::Spacing::Alone`, but
|
||||||
|
/// `proc_macro::Spacing::Alone` converts back to `token::Spacing::Alone`.
|
||||||
|
/// Because of that, pretty-printing of `TokenStream`s produced by proc
|
||||||
|
/// macros is unavoidably uglier (with more whitespace between tokens) than
|
||||||
|
/// pretty-printing of `TokenStream`'s produced by other means (i.e. parsed
|
||||||
|
/// source code, internally constructed token streams, and token streams
|
||||||
|
/// produced by declarative macros).
|
||||||
|
JointHidden,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenStream {
|
impl TokenStream {
|
||||||
@ -421,16 +469,14 @@ impl TokenStream {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a token stream containing a single token with alone spacing.
|
/// Create a token stream containing a single token with alone spacing. The
|
||||||
|
/// spacing used for the final token in a constructed stream doesn't matter
|
||||||
|
/// because it's never used. In practice we arbitrarily use
|
||||||
|
/// `Spacing::Alone`.
|
||||||
pub fn token_alone(kind: TokenKind, span: Span) -> TokenStream {
|
pub fn token_alone(kind: TokenKind, span: Span) -> TokenStream {
|
||||||
TokenStream::new(vec![TokenTree::token_alone(kind, span)])
|
TokenStream::new(vec![TokenTree::token_alone(kind, span)])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a token stream containing a single token with joint spacing.
|
|
||||||
pub fn token_joint(kind: TokenKind, span: Span) -> TokenStream {
|
|
||||||
TokenStream::new(vec![TokenTree::token_joint(kind, span)])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a token stream containing a single `Delimited`.
|
/// Create a token stream containing a single `Delimited`.
|
||||||
pub fn delimited(span: DelimSpan, delim: Delimiter, tts: TokenStream) -> TokenStream {
|
pub fn delimited(span: DelimSpan, delim: Delimiter, tts: TokenStream) -> TokenStream {
|
||||||
TokenStream::new(vec![TokenTree::Delimited(span, delim, tts)])
|
TokenStream::new(vec![TokenTree::Delimited(span, delim, tts)])
|
||||||
@ -517,7 +563,7 @@ impl TokenStream {
|
|||||||
// If `vec` is not empty, try to glue `tt` onto its last token. The return
|
// If `vec` is not empty, try to glue `tt` onto its last token. The return
|
||||||
// value indicates if gluing took place.
|
// value indicates if gluing took place.
|
||||||
fn try_glue_to_last(vec: &mut Vec<TokenTree>, tt: &TokenTree) -> bool {
|
fn try_glue_to_last(vec: &mut Vec<TokenTree>, tt: &TokenTree) -> bool {
|
||||||
if let Some(TokenTree::Token(last_tok, Spacing::Joint)) = vec.last()
|
if let Some(TokenTree::Token(last_tok, Spacing::Joint | Spacing::JointHidden)) = vec.last()
|
||||||
&& let TokenTree::Token(tok, spacing) = tt
|
&& let TokenTree::Token(tok, spacing) = tt
|
||||||
&& let Some(glued_tok) = last_tok.glue(tok)
|
&& let Some(glued_tok) = last_tok.glue(tok)
|
||||||
{
|
{
|
||||||
@ -641,7 +687,7 @@ impl TokenStream {
|
|||||||
|
|
||||||
if attr_style == AttrStyle::Inner {
|
if attr_style == AttrStyle::Inner {
|
||||||
vec![
|
vec![
|
||||||
TokenTree::token_alone(token::Pound, span),
|
TokenTree::token_joint(token::Pound, span),
|
||||||
TokenTree::token_alone(token::Not, span),
|
TokenTree::token_alone(token::Not, span),
|
||||||
body,
|
body,
|
||||||
]
|
]
|
||||||
|
@ -10,7 +10,7 @@ use crate::pp::{self, Breaks};
|
|||||||
use rustc_ast::attr::AttrIdGenerator;
|
use rustc_ast::attr::AttrIdGenerator;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, Token, TokenKind};
|
use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, Token, TokenKind};
|
||||||
use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree};
|
||||||
use rustc_ast::util::classify;
|
use rustc_ast::util::classify;
|
||||||
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
|
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
|
||||||
use rustc_ast::util::parser;
|
use rustc_ast::util::parser;
|
||||||
@ -509,14 +509,15 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
|||||||
/// appropriate macro, transcribe back into the grammar we just parsed from,
|
/// appropriate macro, transcribe back into the grammar we just parsed from,
|
||||||
/// and then pretty-print the resulting AST nodes (so, e.g., we print
|
/// and then pretty-print the resulting AST nodes (so, e.g., we print
|
||||||
/// expression arguments as expressions). It can be done! I think.
|
/// expression arguments as expressions). It can be done! I think.
|
||||||
fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) {
|
fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) -> Spacing {
|
||||||
match tt {
|
match tt {
|
||||||
TokenTree::Token(token, _) => {
|
TokenTree::Token(token, spacing) => {
|
||||||
let token_str = self.token_to_string_ext(token, convert_dollar_crate);
|
let token_str = self.token_to_string_ext(token, convert_dollar_crate);
|
||||||
self.word(token_str);
|
self.word(token_str);
|
||||||
if let token::DocComment(..) = token.kind {
|
if let token::DocComment(..) = token.kind {
|
||||||
self.hardbreak()
|
self.hardbreak()
|
||||||
}
|
}
|
||||||
|
*spacing
|
||||||
}
|
}
|
||||||
TokenTree::Delimited(dspan, delim, tts) => {
|
TokenTree::Delimited(dspan, delim, tts) => {
|
||||||
self.print_mac_common(
|
self.print_mac_common(
|
||||||
@ -528,6 +529,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
|||||||
convert_dollar_crate,
|
convert_dollar_crate,
|
||||||
dspan.entire(),
|
dspan.entire(),
|
||||||
);
|
);
|
||||||
|
// FIXME: add two `Spacing` fields to `TokenTree::Delimited`
|
||||||
|
// and use the close delim one here.
|
||||||
|
Spacing::Alone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,9 +539,20 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
|||||||
fn print_tts(&mut self, tts: &TokenStream, convert_dollar_crate: bool) {
|
fn print_tts(&mut self, tts: &TokenStream, convert_dollar_crate: bool) {
|
||||||
let mut iter = tts.trees().peekable();
|
let mut iter = tts.trees().peekable();
|
||||||
while let Some(tt) = iter.next() {
|
while let Some(tt) = iter.next() {
|
||||||
self.print_tt(tt, convert_dollar_crate);
|
let spacing = self.print_tt(tt, convert_dollar_crate);
|
||||||
if let Some(next) = iter.peek() {
|
if let Some(next) = iter.peek() {
|
||||||
if space_between(tt, next) {
|
// Should we print a space after `tt`? There are two guiding
|
||||||
|
// factors.
|
||||||
|
// - `spacing` is the more important and accurate one. Most
|
||||||
|
// tokens have good spacing information, and
|
||||||
|
// `Joint`/`JointHidden` get used a lot.
|
||||||
|
// - `space_between` is the backup. Code produced by proc
|
||||||
|
// macros has worse spacing information, with no
|
||||||
|
// `JointHidden` usage and too much `Alone` usage, which
|
||||||
|
// would result in over-spaced output such as
|
||||||
|
// `( x () , y . z )`. `space_between` avoids some of the
|
||||||
|
// excess whitespace.
|
||||||
|
if spacing == Spacing::Alone && space_between(tt, next) {
|
||||||
self.space();
|
self.space();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1797,7 +1812,9 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn tt_to_string(&self, tt: &TokenTree) -> String {
|
pub(crate) fn tt_to_string(&self, tt: &TokenTree) -> String {
|
||||||
Self::to_string(|s| s.print_tt(tt, false))
|
Self::to_string(|s| {
|
||||||
|
s.print_tt(tt, false);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn tts_to_string(&self, tokens: &TokenStream) -> String {
|
pub(crate) fn tts_to_string(&self, tokens: &TokenStream) -> String {
|
||||||
|
@ -151,7 +151,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||||||
fn build_panic(&self, expr_str: &str, panic_path: Path) -> P<Expr> {
|
fn build_panic(&self, expr_str: &str, panic_path: Path) -> P<Expr> {
|
||||||
let escaped_expr_str = escape_to_fmt(expr_str);
|
let escaped_expr_str = escape_to_fmt(expr_str);
|
||||||
let initial = [
|
let initial = [
|
||||||
TokenTree::token_alone(
|
TokenTree::token_joint_hidden(
|
||||||
token::Literal(token::Lit {
|
token::Literal(token::Lit {
|
||||||
kind: token::LitKind::Str,
|
kind: token::LitKind::Str,
|
||||||
symbol: Symbol::intern(&if self.fmt_string.is_empty() {
|
symbol: Symbol::intern(&if self.fmt_string.is_empty() {
|
||||||
@ -170,7 +170,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||||||
];
|
];
|
||||||
let captures = self.capture_decls.iter().flat_map(|cap| {
|
let captures = self.capture_decls.iter().flat_map(|cap| {
|
||||||
[
|
[
|
||||||
TokenTree::token_alone(token::Ident(cap.ident.name, false), cap.ident.span),
|
TokenTree::token_joint_hidden(token::Ident(cap.ident.name, false), cap.ident.span),
|
||||||
TokenTree::token_alone(token::Comma, self.span),
|
TokenTree::token_alone(token::Comma, self.span),
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -372,16 +372,6 @@ impl<'a> StripUnconfigured<'a> {
|
|||||||
};
|
};
|
||||||
let pound_span = pound_token.span;
|
let pound_span = pound_token.span;
|
||||||
|
|
||||||
let mut trees = vec![AttrTokenTree::Token(pound_token, Spacing::Alone)];
|
|
||||||
if attr.style == AttrStyle::Inner {
|
|
||||||
// For inner attributes, we do the same thing for the `!` in `#![some_attr]`
|
|
||||||
let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _) =
|
|
||||||
orig_trees.next().unwrap().clone()
|
|
||||||
else {
|
|
||||||
panic!("Bad tokens for attribute {attr:?}");
|
|
||||||
};
|
|
||||||
trees.push(AttrTokenTree::Token(bang_token, Spacing::Alone));
|
|
||||||
}
|
|
||||||
// We don't really have a good span to use for the synthesized `[]`
|
// We don't really have a good span to use for the synthesized `[]`
|
||||||
// in `#[attr]`, so just use the span of the `#` token.
|
// in `#[attr]`, so just use the span of the `#` token.
|
||||||
let bracket_group = AttrTokenTree::Delimited(
|
let bracket_group = AttrTokenTree::Delimited(
|
||||||
@ -392,7 +382,21 @@ impl<'a> StripUnconfigured<'a> {
|
|||||||
.unwrap_or_else(|| panic!("Missing tokens for {item:?}"))
|
.unwrap_or_else(|| panic!("Missing tokens for {item:?}"))
|
||||||
.to_attr_token_stream(),
|
.to_attr_token_stream(),
|
||||||
);
|
);
|
||||||
trees.push(bracket_group);
|
let trees = if attr.style == AttrStyle::Inner {
|
||||||
|
// For inner attributes, we do the same thing for the `!` in `#![some_attr]`
|
||||||
|
let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _) =
|
||||||
|
orig_trees.next().unwrap().clone()
|
||||||
|
else {
|
||||||
|
panic!("Bad tokens for attribute {attr:?}");
|
||||||
|
};
|
||||||
|
vec![
|
||||||
|
AttrTokenTree::Token(pound_token, Spacing::Joint),
|
||||||
|
AttrTokenTree::Token(bang_token, Spacing::JointHidden),
|
||||||
|
bracket_group,
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
vec![AttrTokenTree::Token(pound_token, Spacing::JointHidden), bracket_group]
|
||||||
|
};
|
||||||
let tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::new(trees)));
|
let tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::new(trees)));
|
||||||
let attr = attr::mk_attr_from_item(
|
let attr = attr::mk_attr_from_item(
|
||||||
&self.sess.parse_sess.attr_id_generator,
|
&self.sess.parse_sess.attr_id_generator,
|
||||||
|
@ -240,7 +240,7 @@ pub(super) fn transcribe<'a>(
|
|||||||
// with modified syntax context. (I believe this supports nested macros).
|
// with modified syntax context. (I believe this supports nested macros).
|
||||||
marker.visit_span(&mut sp);
|
marker.visit_span(&mut sp);
|
||||||
marker.visit_ident(&mut original_ident);
|
marker.visit_ident(&mut original_ident);
|
||||||
result.push(TokenTree::token_alone(token::Dollar, sp));
|
result.push(TokenTree::token_joint_hidden(token::Dollar, sp));
|
||||||
result.push(TokenTree::Token(
|
result.push(TokenTree::Token(
|
||||||
Token::from_ast_ident(original_ident),
|
Token::from_ast_ident(original_ident),
|
||||||
Spacing::Alone,
|
Spacing::Alone,
|
||||||
|
@ -120,23 +120,25 @@ fn string_to_tts_1() {
|
|||||||
|
|
||||||
let expected = TokenStream::new(vec![
|
let expected = TokenStream::new(vec![
|
||||||
TokenTree::token_alone(token::Ident(kw::Fn, false), sp(0, 2)),
|
TokenTree::token_alone(token::Ident(kw::Fn, false), sp(0, 2)),
|
||||||
TokenTree::token_alone(token::Ident(Symbol::intern("a"), false), sp(3, 4)),
|
TokenTree::token_joint_hidden(token::Ident(Symbol::intern("a"), false), sp(3, 4)),
|
||||||
TokenTree::Delimited(
|
TokenTree::Delimited(
|
||||||
DelimSpan::from_pair(sp(5, 6), sp(13, 14)),
|
DelimSpan::from_pair(sp(4, 5), sp(11, 12)),
|
||||||
Delimiter::Parenthesis,
|
Delimiter::Parenthesis,
|
||||||
TokenStream::new(vec![
|
TokenStream::new(vec![
|
||||||
TokenTree::token_alone(token::Ident(Symbol::intern("b"), false), sp(6, 7)),
|
TokenTree::token_joint(token::Ident(Symbol::intern("b"), false), sp(5, 6)),
|
||||||
TokenTree::token_alone(token::Colon, sp(8, 9)),
|
TokenTree::token_alone(token::Colon, sp(6, 7)),
|
||||||
TokenTree::token_alone(token::Ident(sym::i32, false), sp(10, 13)),
|
// `JointHidden` because the `i32` is immediately followed by the `)`.
|
||||||
|
TokenTree::token_joint_hidden(token::Ident(sym::i32, false), sp(8, 11)),
|
||||||
])
|
])
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
TokenTree::Delimited(
|
TokenTree::Delimited(
|
||||||
DelimSpan::from_pair(sp(15, 16), sp(20, 21)),
|
DelimSpan::from_pair(sp(13, 14), sp(18, 19)),
|
||||||
Delimiter::Brace,
|
Delimiter::Brace,
|
||||||
TokenStream::new(vec![
|
TokenStream::new(vec![
|
||||||
TokenTree::token_joint(token::Ident(Symbol::intern("b"), false), sp(17, 18)),
|
TokenTree::token_joint(token::Ident(Symbol::intern("b"), false), sp(15, 16)),
|
||||||
TokenTree::token_alone(token::Semi, sp(18, 19)),
|
// `Alone` because the `;` is followed by whitespace.
|
||||||
|
TokenTree::token_alone(token::Semi, sp(16, 17)),
|
||||||
])
|
])
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
|
@ -5,7 +5,7 @@ use pm::bridge::{
|
|||||||
use pm::{Delimiter, Level};
|
use pm::{Delimiter, Level};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_ast::tokenstream::{self, Spacing::*, TokenStream};
|
use rustc_ast::tokenstream::{self, Spacing, TokenStream};
|
||||||
use rustc_ast::util::literal::escape_byte_str_symbol;
|
use rustc_ast::util::literal::escape_byte_str_symbol;
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
@ -111,7 +111,22 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
|
|||||||
}));
|
}));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tokenstream::TokenTree::Token(token, spacing) => (token, spacing == Joint),
|
tokenstream::TokenTree::Token(token, spacing) => {
|
||||||
|
// Do not be tempted to check here that the `spacing`
|
||||||
|
// values are "correct" w.r.t. the token stream (e.g. that
|
||||||
|
// `Spacing::Joint` is actually followed by a `Punct` token
|
||||||
|
// tree). Because the problem in #76399 was introduced that
|
||||||
|
// way.
|
||||||
|
//
|
||||||
|
// This is where the `Hidden` in `JointHidden` applies,
|
||||||
|
// because the jointness is effectively hidden from proc
|
||||||
|
// macros.
|
||||||
|
let joint = match spacing {
|
||||||
|
Spacing::Alone | Spacing::JointHidden => false,
|
||||||
|
Spacing::Joint => true,
|
||||||
|
};
|
||||||
|
(token, joint)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Split the operator into one or more `Punct`s, one per character.
|
// Split the operator into one or more `Punct`s, one per character.
|
||||||
@ -133,7 +148,8 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
|
|||||||
} else {
|
} else {
|
||||||
span
|
span
|
||||||
};
|
};
|
||||||
TokenTree::Punct(Punct { ch, joint: if is_final { joint } else { true }, span })
|
let joint = if is_final { joint } else { true };
|
||||||
|
TokenTree::Punct(Punct { ch, joint, span })
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -268,6 +284,10 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
|
|||||||
fn to_internal(self) -> SmallVec<[tokenstream::TokenTree; 2]> {
|
fn to_internal(self) -> SmallVec<[tokenstream::TokenTree; 2]> {
|
||||||
use rustc_ast::token::*;
|
use rustc_ast::token::*;
|
||||||
|
|
||||||
|
// The code below is conservative and uses `token_alone` in most
|
||||||
|
// places. When the resulting code is pretty-printed by `print_tts` it
|
||||||
|
// ends up with spaces between most tokens, which is safe but ugly.
|
||||||
|
// It's hard in general to do better when working at the token level.
|
||||||
let (tree, rustc) = self;
|
let (tree, rustc) = self;
|
||||||
match tree {
|
match tree {
|
||||||
TokenTree::Punct(Punct { ch, joint, span }) => {
|
TokenTree::Punct(Punct { ch, joint, span }) => {
|
||||||
@ -296,6 +316,11 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
|
|||||||
b'\'' => SingleQuote,
|
b'\'' => SingleQuote,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
// We never produce `token::Spacing::JointHidden` here, which
|
||||||
|
// means the pretty-printing of code produced by proc macros is
|
||||||
|
// ugly, with lots of whitespace between tokens. This is
|
||||||
|
// unavoidable because `proc_macro::Spacing` only applies to
|
||||||
|
// `Punct` token trees.
|
||||||
smallvec![if joint {
|
smallvec![if joint {
|
||||||
tokenstream::TokenTree::token_joint(kind, span)
|
tokenstream::TokenTree::token_joint(kind, span)
|
||||||
} else {
|
} else {
|
||||||
@ -322,7 +347,7 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
|
|||||||
let minus = BinOp(BinOpToken::Minus);
|
let minus = BinOp(BinOpToken::Minus);
|
||||||
let symbol = Symbol::intern(&symbol.as_str()[1..]);
|
let symbol = Symbol::intern(&symbol.as_str()[1..]);
|
||||||
let integer = TokenKind::lit(token::Integer, symbol, suffix);
|
let integer = TokenKind::lit(token::Integer, symbol, suffix);
|
||||||
let a = tokenstream::TokenTree::token_alone(minus, span);
|
let a = tokenstream::TokenTree::token_joint_hidden(minus, span);
|
||||||
let b = tokenstream::TokenTree::token_alone(integer, span);
|
let b = tokenstream::TokenTree::token_alone(integer, span);
|
||||||
smallvec![a, b]
|
smallvec![a, b]
|
||||||
}
|
}
|
||||||
@ -335,7 +360,7 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
|
|||||||
let minus = BinOp(BinOpToken::Minus);
|
let minus = BinOp(BinOpToken::Minus);
|
||||||
let symbol = Symbol::intern(&symbol.as_str()[1..]);
|
let symbol = Symbol::intern(&symbol.as_str()[1..]);
|
||||||
let float = TokenKind::lit(token::Float, symbol, suffix);
|
let float = TokenKind::lit(token::Float, symbol, suffix);
|
||||||
let a = tokenstream::TokenTree::token_alone(minus, span);
|
let a = tokenstream::TokenTree::token_joint_hidden(minus, span);
|
||||||
let b = tokenstream::TokenTree::token_alone(float, span);
|
let b = tokenstream::TokenTree::token_alone(float, span);
|
||||||
smallvec![a, b]
|
smallvec![a, b]
|
||||||
}
|
}
|
||||||
@ -546,7 +571,10 @@ impl server::TokenStream for Rustc<'_, '_> {
|
|||||||
Ok(Self::TokenStream::from_iter([
|
Ok(Self::TokenStream::from_iter([
|
||||||
// FIXME: The span of the `-` token is lost when
|
// FIXME: The span of the `-` token is lost when
|
||||||
// parsing, so we cannot faithfully recover it here.
|
// parsing, so we cannot faithfully recover it here.
|
||||||
tokenstream::TokenTree::token_alone(token::BinOp(token::Minus), e.span),
|
tokenstream::TokenTree::token_joint_hidden(
|
||||||
|
token::BinOp(token::Minus),
|
||||||
|
e.span,
|
||||||
|
),
|
||||||
tokenstream::TokenTree::token_alone(token::Literal(*token_lit), e.span),
|
tokenstream::TokenTree::token_alone(token::Literal(*token_lit), e.span),
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,13 @@ impl<'a> TokenTreesReader<'a> {
|
|||||||
} else if let Some(glued) = self.token.glue(&next_tok) {
|
} else if let Some(glued) = self.token.glue(&next_tok) {
|
||||||
self.token = glued;
|
self.token = glued;
|
||||||
} else {
|
} else {
|
||||||
let this_spacing =
|
let this_spacing = if next_tok.is_punct() {
|
||||||
if next_tok.is_punct() { Spacing::Joint } else { Spacing::Alone };
|
Spacing::Joint
|
||||||
|
} else if next_tok.kind == token::Eof {
|
||||||
|
Spacing::Alone
|
||||||
|
} else {
|
||||||
|
Spacing::JointHidden
|
||||||
|
};
|
||||||
break (this_spacing, next_tok);
|
break (this_spacing, next_tok);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -130,7 +130,7 @@ pub struct Parser<'a> {
|
|||||||
pub sess: &'a ParseSess,
|
pub sess: &'a ParseSess,
|
||||||
/// The current token.
|
/// The current token.
|
||||||
pub token: Token,
|
pub token: Token,
|
||||||
/// The spacing for the current token
|
/// The spacing for the current token.
|
||||||
pub token_spacing: Spacing,
|
pub token_spacing: Spacing,
|
||||||
/// The previous token.
|
/// The previous token.
|
||||||
pub prev_token: Token,
|
pub prev_token: Token,
|
||||||
@ -268,6 +268,8 @@ impl TokenCursor {
|
|||||||
let trees = tts.clone().into_trees();
|
let trees = tts.clone().into_trees();
|
||||||
self.stack.push((mem::replace(&mut self.tree_cursor, trees), delim, sp));
|
self.stack.push((mem::replace(&mut self.tree_cursor, trees), delim, sp));
|
||||||
if delim != Delimiter::Invisible {
|
if delim != Delimiter::Invisible {
|
||||||
|
// FIXME: add two `Spacing` fields to `TokenTree::Delimited`
|
||||||
|
// and use the open delim one here.
|
||||||
return (Token::new(token::OpenDelim(delim), sp.open), Spacing::Alone);
|
return (Token::new(token::OpenDelim(delim), sp.open), Spacing::Alone);
|
||||||
}
|
}
|
||||||
// No open delimiter to return; continue on to the next iteration.
|
// No open delimiter to return; continue on to the next iteration.
|
||||||
@ -277,11 +279,15 @@ impl TokenCursor {
|
|||||||
// We have exhausted this token stream. Move back to its parent token stream.
|
// We have exhausted this token stream. Move back to its parent token stream.
|
||||||
self.tree_cursor = tree_cursor;
|
self.tree_cursor = tree_cursor;
|
||||||
if delim != Delimiter::Invisible {
|
if delim != Delimiter::Invisible {
|
||||||
|
// FIXME: add two `Spacing` fields to `TokenTree::Delimited` and
|
||||||
|
// use the close delim one here.
|
||||||
return (Token::new(token::CloseDelim(delim), span.close), Spacing::Alone);
|
return (Token::new(token::CloseDelim(delim), span.close), Spacing::Alone);
|
||||||
}
|
}
|
||||||
// No close delimiter to return; continue on to the next iteration.
|
// No close delimiter to return; continue on to the next iteration.
|
||||||
} else {
|
} else {
|
||||||
// We have exhausted the outermost token stream.
|
// We have exhausted the outermost token stream. The use of
|
||||||
|
// `Spacing::Alone` is arbitrary and immaterial, because the
|
||||||
|
// `Eof` token's spacing is never used.
|
||||||
return (Token::new(token::Eof, DUMMY_SP), Spacing::Alone);
|
return (Token::new(token::Eof, DUMMY_SP), Spacing::Alone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -699,8 +705,8 @@ impl<'a> Parser<'a> {
|
|||||||
// is not needed (we'll capture the entire 'glued' token),
|
// is not needed (we'll capture the entire 'glued' token),
|
||||||
// and `bump` will set this field to `None`
|
// and `bump` will set this field to `None`
|
||||||
self.break_last_token = true;
|
self.break_last_token = true;
|
||||||
// Use the spacing of the glued token as the spacing
|
// Use the spacing of the glued token as the spacing of the
|
||||||
// of the unglued second token.
|
// unglued second token.
|
||||||
self.bump_with((Token::new(second, second_span), self.token_spacing));
|
self.bump_with((Token::new(second, second_span), self.token_spacing));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -1312,8 +1318,9 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
token::CloseDelim(_) | token::Eof => unreachable!(),
|
token::CloseDelim(_) | token::Eof => unreachable!(),
|
||||||
_ => {
|
_ => {
|
||||||
|
let prev_spacing = self.token_spacing;
|
||||||
self.bump();
|
self.bump();
|
||||||
TokenTree::Token(self.prev_token.clone(), Spacing::Alone)
|
TokenTree::Token(self.prev_token.clone(), prev_spacing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -925,13 +925,12 @@ impl !Sync for Punct {}
|
|||||||
pub enum Spacing {
|
pub enum Spacing {
|
||||||
/// A `Punct` token can join with the following token to form a multi-character operator.
|
/// A `Punct` token can join with the following token to form a multi-character operator.
|
||||||
///
|
///
|
||||||
/// In token streams constructed using proc macro interfaces `Joint` punctuation tokens can be
|
/// In token streams constructed using proc macro interfaces, `Joint` punctuation tokens can be
|
||||||
/// followed by any other tokens. \
|
/// followed by any other tokens. However, in token streams parsed from source code, the
|
||||||
/// However, in token streams parsed from source code compiler will only set spacing to `Joint`
|
/// compiler will only set spacing to `Joint` in the following cases.
|
||||||
/// in the following cases:
|
/// - When a `Punct` is immediately followed by another `Punct` without a whitespace. E.g. `+`
|
||||||
/// - A `Punct` is immediately followed by another `Punct` without a whitespace. \
|
/// is `Joint` in `+=` and `++`.
|
||||||
/// E.g. `+` is `Joint` in `+=` and `++`.
|
/// - When a single quote `'` is immediately followed by an identifier without a whitespace.
|
||||||
/// - A single quote `'` is immediately followed by an identifier without a whitespace. \
|
|
||||||
/// E.g. `'` is `Joint` in `'lifetime`.
|
/// E.g. `'` is `Joint` in `'lifetime`.
|
||||||
///
|
///
|
||||||
/// This list may be extended in the future to enable more token combinations.
|
/// This list may be extended in the future to enable more token combinations.
|
||||||
@ -939,11 +938,10 @@ pub enum Spacing {
|
|||||||
Joint,
|
Joint,
|
||||||
/// A `Punct` token cannot join with the following token to form a multi-character operator.
|
/// A `Punct` token cannot join with the following token to form a multi-character operator.
|
||||||
///
|
///
|
||||||
/// `Alone` punctuation tokens can be followed by any other tokens. \
|
/// `Alone` punctuation tokens can be followed by any other tokens. In token streams parsed
|
||||||
/// In token streams parsed from source code compiler will set spacing to `Alone` in all cases
|
/// from source code, the compiler will set spacing to `Alone` in all cases not covered by the
|
||||||
/// not covered by the conditions for `Joint` above. \
|
/// conditions for `Joint` above. E.g. `+` is `Alone` in `+ =`, `+ident` and `+()`. In
|
||||||
/// E.g. `+` is `Alone` in `+ =`, `+ident` and `+()`.
|
/// particular, tokens not followed by anything will be marked as `Alone`.
|
||||||
/// In particular, token not followed by anything will also be marked as `Alone`.
|
|
||||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||||
Alone,
|
Alone,
|
||||||
}
|
}
|
||||||
@ -978,8 +976,8 @@ impl Punct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the spacing of this punctuation character, indicating whether it can be potentially
|
/// Returns the spacing of this punctuation character, indicating whether it can be potentially
|
||||||
/// combined into a multi-character operator with the following token (`Joint`), or the operator
|
/// combined into a multi-character operator with the following token (`Joint`), or whether the
|
||||||
/// has certainly ended (`Alone`).
|
/// operator has definitely ended (`Alone`).
|
||||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||||
pub fn spacing(&self) -> Spacing {
|
pub fn spacing(&self) -> Spacing {
|
||||||
if self.0.joint { Spacing::Joint } else { Spacing::Alone }
|
if self.0.joint { Spacing::Joint } else { Spacing::Alone }
|
||||||
|
@ -59,18 +59,12 @@ fn test_block() {
|
|||||||
c1!(block, [ {} ], "{}");
|
c1!(block, [ {} ], "{}");
|
||||||
c1!(block, [ { true } ], "{ true }");
|
c1!(block, [ { true } ], "{ true }");
|
||||||
c1!(block, [ { return } ], "{ return }");
|
c1!(block, [ { return } ], "{ return }");
|
||||||
c2!(block, [ {
|
c1!(block, [ { return; } ], "{ return; }");
|
||||||
return;
|
c1!(block,
|
||||||
} ],
|
|
||||||
"{ return; }",
|
|
||||||
"{ return ; }"
|
|
||||||
);
|
|
||||||
c2!(block,
|
|
||||||
[ {
|
[ {
|
||||||
let _;
|
let _;
|
||||||
true
|
true
|
||||||
} ],
|
} ],
|
||||||
"{ let _; true }",
|
|
||||||
"{ let _; true }"
|
"{ let _; true }"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -88,17 +82,17 @@ fn test_expr() {
|
|||||||
|
|
||||||
// ExprKind::Call
|
// ExprKind::Call
|
||||||
c1!(expr, [ f() ], "f()");
|
c1!(expr, [ f() ], "f()");
|
||||||
c2!(expr, [ f::<u8>() ], "f::<u8>()", "f :: < u8 > ()");
|
c1!(expr, [ f::<u8>() ], "f::<u8>()");
|
||||||
c2!(expr, [ f::<1>() ], "f::<1>()", "f :: < 1 > ()");
|
c1!(expr, [ f::<1>() ], "f::<1>()");
|
||||||
c2!(expr, [ f::<'a, u8, 1>() ], "f::<'a, u8, 1>()", "f :: < 'a, u8, 1 > ()");
|
c1!(expr, [ f::<'a, u8, 1>() ], "f::<'a, u8, 1>()");
|
||||||
c1!(expr, [ f(true) ], "f(true)");
|
c1!(expr, [ f(true) ], "f(true)");
|
||||||
c2!(expr, [ f(true,) ], "f(true)", "f(true,)");
|
c2!(expr, [ f(true,) ], "f(true)", "f(true,)");
|
||||||
c2!(expr, [ ()() ], "()()", "() ()");
|
c2!(expr, [ ()() ], "()()", "() ()");
|
||||||
|
|
||||||
// ExprKind::MethodCall
|
// ExprKind::MethodCall
|
||||||
c1!(expr, [ x.f() ], "x.f()");
|
c1!(expr, [ x.f() ], "x.f()");
|
||||||
c2!(expr, [ x.f::<u8>() ], "x.f::<u8>()", "x.f :: < u8 > ()");
|
c1!(expr, [ x.f::<u8>() ], "x.f::<u8>()");
|
||||||
c2!(expr, [ x.collect::<Vec<_>>() ], "x.collect::<Vec<_>>()", "x.collect :: < Vec < _ >> ()");
|
c1!(expr, [ x.collect::<Vec<_>>() ], "x.collect::<Vec<_>>()");
|
||||||
|
|
||||||
// ExprKind::Tup
|
// ExprKind::Tup
|
||||||
c1!(expr, [ () ], "()");
|
c1!(expr, [ () ], "()");
|
||||||
@ -111,17 +105,13 @@ fn test_expr() {
|
|||||||
c1!(expr, [ true || false && false ], "true || false && false");
|
c1!(expr, [ true || false && false ], "true || false && false");
|
||||||
c1!(expr, [ a < 1 && 2 < b && c > 3 && 4 > d ], "a < 1 && 2 < b && c > 3 && 4 > d");
|
c1!(expr, [ a < 1 && 2 < b && c > 3 && 4 > d ], "a < 1 && 2 < b && c > 3 && 4 > d");
|
||||||
c2!(expr, [ a & b & !c ], "a & b & !c", "a & b &!c"); // FIXME
|
c2!(expr, [ a & b & !c ], "a & b & !c", "a & b &!c"); // FIXME
|
||||||
c2!(expr,
|
c1!(expr, [ a + b * c - d + -1 * -2 - -3], "a + b * c - d + -1 * -2 - -3");
|
||||||
[ a + b * c - d + -1 * -2 - -3],
|
|
||||||
"a + b * c - d + -1 * -2 - -3",
|
|
||||||
"a + b * c - d + - 1 * - 2 - - 3"
|
|
||||||
);
|
|
||||||
c2!(expr, [ x = !y ], "x = !y", "x =!y"); // FIXME
|
c2!(expr, [ x = !y ], "x = !y", "x =!y"); // FIXME
|
||||||
|
|
||||||
// ExprKind::Unary
|
// ExprKind::Unary
|
||||||
c2!(expr, [ *expr ], "*expr", "* expr");
|
c1!(expr, [ *expr ], "*expr");
|
||||||
c2!(expr, [ !expr ], "!expr", "! expr");
|
c1!(expr, [ !expr ], "!expr");
|
||||||
c2!(expr, [ -expr ], "-expr", "- expr");
|
c1!(expr, [ -expr ], "-expr");
|
||||||
|
|
||||||
// ExprKind::Lit
|
// ExprKind::Lit
|
||||||
c1!(expr, [ 'x' ], "'x'");
|
c1!(expr, [ 'x' ], "'x'");
|
||||||
@ -130,7 +120,7 @@ fn test_expr() {
|
|||||||
|
|
||||||
// ExprKind::Cast
|
// ExprKind::Cast
|
||||||
c1!(expr, [ expr as T ], "expr as T");
|
c1!(expr, [ expr as T ], "expr as T");
|
||||||
c2!(expr, [ expr as T<u8> ], "expr as T<u8>", "expr as T < u8 >");
|
c1!(expr, [ expr as T<u8> ], "expr as T<u8>");
|
||||||
|
|
||||||
// ExprKind::Type: there is no syntax for type ascription.
|
// ExprKind::Type: there is no syntax for type ascription.
|
||||||
|
|
||||||
@ -140,11 +130,7 @@ fn test_expr() {
|
|||||||
// ExprKind::If
|
// ExprKind::If
|
||||||
c1!(expr, [ if true {} ], "if true {}");
|
c1!(expr, [ if true {} ], "if true {}");
|
||||||
c2!(expr, [ if !true {} ], "if !true {}", "if!true {}"); // FIXME
|
c2!(expr, [ if !true {} ], "if !true {}", "if!true {}"); // FIXME
|
||||||
c2!(expr,
|
c1!(expr, [ if ::std::blah() { } else { } ], "if ::std::blah() {} else {}");
|
||||||
[ if ::std::blah() { } else { } ],
|
|
||||||
"if ::std::blah() {} else {}",
|
|
||||||
"if :: std :: blah() {} else {}"
|
|
||||||
);
|
|
||||||
c1!(expr, [ if let true = true {} else {} ], "if let true = true {} else {}");
|
c1!(expr, [ if let true = true {} else {} ], "if let true = true {} else {}");
|
||||||
c1!(expr,
|
c1!(expr,
|
||||||
[ if true {
|
[ if true {
|
||||||
@ -159,7 +145,7 @@ fn test_expr() {
|
|||||||
} ],
|
} ],
|
||||||
"if true {} else if false {} else {}"
|
"if true {} else if false {} else {}"
|
||||||
);
|
);
|
||||||
c2!(expr,
|
c1!(expr,
|
||||||
[ if true {
|
[ if true {
|
||||||
return;
|
return;
|
||||||
} else if false {
|
} else if false {
|
||||||
@ -167,22 +153,21 @@ fn test_expr() {
|
|||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
} ],
|
} ],
|
||||||
"if true { return; } else if false { 0 } else { 0 }",
|
|
||||||
"if true { return; } else if false { 0 } else { 0 }"
|
"if true { return; } else if false { 0 } else { 0 }"
|
||||||
);
|
);
|
||||||
|
|
||||||
// ExprKind::While
|
// ExprKind::While
|
||||||
c1!(expr, [ while true {} ], "while true {}");
|
c1!(expr, [ while true {} ], "while true {}");
|
||||||
c2!(expr, [ 'a: while true {} ], "'a: while true {}", "'a : while true {}");
|
c1!(expr, [ 'a: while true {} ], "'a: while true {}");
|
||||||
c1!(expr, [ while let true = true {} ], "while let true = true {}");
|
c1!(expr, [ while let true = true {} ], "while let true = true {}");
|
||||||
|
|
||||||
// ExprKind::ForLoop
|
// ExprKind::ForLoop
|
||||||
c1!(expr, [ for _ in x {} ], "for _ in x {}");
|
c1!(expr, [ for _ in x {} ], "for _ in x {}");
|
||||||
c2!(expr, [ 'a: for _ in x {} ], "'a: for _ in x {}", "'a : for _ in x {}");
|
c1!(expr, [ 'a: for _ in x {} ], "'a: for _ in x {}");
|
||||||
|
|
||||||
// ExprKind::Loop
|
// ExprKind::Loop
|
||||||
c1!(expr, [ loop {} ], "loop {}");
|
c1!(expr, [ loop {} ], "loop {}");
|
||||||
c2!(expr, [ 'a: loop {} ], "'a: loop {}", "'a : loop {}");
|
c1!(expr, [ 'a: loop {} ], "'a: loop {}");
|
||||||
|
|
||||||
// ExprKind::Match
|
// ExprKind::Match
|
||||||
c1!(expr, [ match self {} ], "match self {}");
|
c1!(expr, [ match self {} ], "match self {}");
|
||||||
@ -202,8 +187,8 @@ fn test_expr() {
|
|||||||
|
|
||||||
// ExprKind::Closure
|
// ExprKind::Closure
|
||||||
c1!(expr, [ || {} ], "|| {}");
|
c1!(expr, [ || {} ], "|| {}");
|
||||||
c2!(expr, [ |x| {} ], "|x| {}", "| x | {}");
|
c1!(expr, [ |x| {} ], "|x| {}");
|
||||||
c2!(expr, [ |x: u8| {} ], "|x: u8| {}", "| x : u8 | {}");
|
c1!(expr, [ |x: u8| {} ], "|x: u8| {}");
|
||||||
c1!(expr, [ || () ], "|| ()");
|
c1!(expr, [ || () ], "|| ()");
|
||||||
c1!(expr, [ move || self ], "move || self");
|
c1!(expr, [ move || self ], "move || self");
|
||||||
c1!(expr, [ async || self ], "async || self");
|
c1!(expr, [ async || self ], "async || self");
|
||||||
@ -218,7 +203,7 @@ fn test_expr() {
|
|||||||
// ExprKind::Block
|
// ExprKind::Block
|
||||||
c1!(expr, [ {} ], "{}");
|
c1!(expr, [ {} ], "{}");
|
||||||
c1!(expr, [ unsafe {} ], "unsafe {}");
|
c1!(expr, [ unsafe {} ], "unsafe {}");
|
||||||
c2!(expr, [ 'a: {} ], "'a: {}", "'a : {}");
|
c1!(expr, [ 'a: {} ], "'a: {}");
|
||||||
c1!(expr, [ #[attr] {} ], "#[attr] {}");
|
c1!(expr, [ #[attr] {} ], "#[attr] {}");
|
||||||
c2!(expr,
|
c2!(expr,
|
||||||
[
|
[
|
||||||
@ -253,34 +238,34 @@ fn test_expr() {
|
|||||||
c1!(expr, [ expr.0 ], "expr.0");
|
c1!(expr, [ expr.0 ], "expr.0");
|
||||||
|
|
||||||
// ExprKind::Index
|
// ExprKind::Index
|
||||||
c2!(expr, [ expr[true] ], "expr[true]", "expr [true]");
|
c1!(expr, [ expr[true] ], "expr[true]");
|
||||||
|
|
||||||
// ExprKind::Range
|
// ExprKind::Range
|
||||||
c1!(expr, [ .. ], "..");
|
c1!(expr, [ .. ], "..");
|
||||||
c2!(expr, [ ..hi ], "..hi", ".. hi");
|
c1!(expr, [ ..hi ], "..hi");
|
||||||
c2!(expr, [ lo.. ], "lo..", "lo ..");
|
c1!(expr, [ lo.. ], "lo..");
|
||||||
c2!(expr, [ lo..hi ], "lo..hi", "lo .. hi");
|
c1!(expr, [ lo..hi ], "lo..hi");
|
||||||
c2!(expr, [ ..=hi ], "..=hi", "..= hi");
|
c1!(expr, [ ..=hi ], "..=hi");
|
||||||
c2!(expr, [ lo..=hi ], "lo..=hi", "lo ..= hi");
|
c1!(expr, [ lo..=hi ], "lo..=hi");
|
||||||
c2!(expr, [ -2..=-1 ], "-2..=-1", "- 2 ..= - 1");
|
c1!(expr, [ -2..=-1 ], "-2..=-1");
|
||||||
|
|
||||||
// ExprKind::Underscore
|
// ExprKind::Underscore
|
||||||
// FIXME: todo
|
// FIXME: todo
|
||||||
|
|
||||||
// ExprKind::Path
|
// ExprKind::Path
|
||||||
c1!(expr, [ thing ], "thing");
|
c1!(expr, [ thing ], "thing");
|
||||||
c2!(expr, [ m::thing ], "m::thing", "m :: thing");
|
c1!(expr, [ m::thing ], "m::thing");
|
||||||
c2!(expr, [ self::thing ], "self::thing", "self :: thing");
|
c1!(expr, [ self::thing ], "self::thing");
|
||||||
c2!(expr, [ crate::thing ], "crate::thing", "crate :: thing");
|
c1!(expr, [ crate::thing ], "crate::thing");
|
||||||
c2!(expr, [ Self::thing ], "Self::thing", "Self :: thing");
|
c1!(expr, [ Self::thing ], "Self::thing");
|
||||||
c2!(expr, [ <Self as T>::thing ], "<Self as T>::thing", "< Self as T > :: thing");
|
c1!(expr, [ <Self as T>::thing ], "<Self as T>::thing");
|
||||||
c2!(expr, [ Self::<'static> ], "Self::<'static>", "Self :: < 'static >");
|
c1!(expr, [ Self::<'static> ], "Self::<'static>");
|
||||||
|
|
||||||
// ExprKind::AddrOf
|
// ExprKind::AddrOf
|
||||||
c2!(expr, [ &expr ], "&expr", "& expr");
|
c1!(expr, [ &expr ], "&expr");
|
||||||
c2!(expr, [ &mut expr ], "&mut expr", "& mut expr");
|
c1!(expr, [ &mut expr ], "&mut expr");
|
||||||
c2!(expr, [ &raw const expr ], "&raw const expr", "& raw const expr");
|
c1!(expr, [ &raw const expr ], "&raw const expr");
|
||||||
c2!(expr, [ &raw mut expr ], "&raw mut expr", "& raw mut expr");
|
c1!(expr, [ &raw mut expr ], "&raw mut expr");
|
||||||
|
|
||||||
// ExprKind::Break
|
// ExprKind::Break
|
||||||
c1!(expr, [ break ], "break");
|
c1!(expr, [ break ], "break");
|
||||||
@ -301,29 +286,21 @@ fn test_expr() {
|
|||||||
// ExprKind::OffsetOf: untestable because this test works pre-expansion.
|
// ExprKind::OffsetOf: untestable because this test works pre-expansion.
|
||||||
|
|
||||||
// ExprKind::MacCall
|
// ExprKind::MacCall
|
||||||
c2!(expr, [ mac!(...) ], "mac!(...)", "mac! (...)");
|
c1!(expr, [ mac!(...) ], "mac!(...)");
|
||||||
c2!(expr, [ mac![...] ], "mac![...]", "mac! [...]");
|
c1!(expr, [ mac![...] ], "mac![...]");
|
||||||
c1!(expr, [ mac! { ... } ], "mac! { ... }");
|
c1!(expr, [ mac! { ... } ], "mac! { ... }");
|
||||||
|
|
||||||
// ExprKind::Struct
|
// ExprKind::Struct
|
||||||
c1!(expr, [ Struct {} ], "Struct {}");
|
c1!(expr, [ Struct {} ], "Struct {}");
|
||||||
c2!(expr,
|
c1!(expr, [ <Struct as Trait>::Type {} ], "<Struct as Trait>::Type {}");
|
||||||
[ <Struct as Trait>::Type {} ],
|
|
||||||
"<Struct as Trait>::Type {}",
|
|
||||||
"< Struct as Trait > :: Type {}"
|
|
||||||
);
|
|
||||||
c1!(expr, [ Struct { .. } ], "Struct { .. }");
|
c1!(expr, [ Struct { .. } ], "Struct { .. }");
|
||||||
c2!(expr, [ Struct { ..base } ], "Struct { ..base }", "Struct { .. base }");
|
c1!(expr, [ Struct { ..base } ], "Struct { ..base }");
|
||||||
c1!(expr, [ Struct { x } ], "Struct { x }");
|
c1!(expr, [ Struct { x } ], "Struct { x }");
|
||||||
c1!(expr, [ Struct { x, .. } ], "Struct { x, .. }");
|
c1!(expr, [ Struct { x, .. } ], "Struct { x, .. }");
|
||||||
c2!(expr, [ Struct { x, ..base } ], "Struct { x, ..base }", "Struct { x, .. base }");
|
c1!(expr, [ Struct { x, ..base } ], "Struct { x, ..base }");
|
||||||
c2!(expr, [ Struct { x: true } ], "Struct { x: true }", "Struct { x : true }");
|
c1!(expr, [ Struct { x: true } ], "Struct { x: true }");
|
||||||
c2!(expr, [ Struct { x: true, .. } ], "Struct { x: true, .. }", "Struct { x : true, .. }");
|
c1!(expr, [ Struct { x: true, .. } ], "Struct { x: true, .. }");
|
||||||
c2!(expr,
|
c1!(expr, [ Struct { x: true, ..base } ], "Struct { x: true, ..base }");
|
||||||
[ Struct { x: true, ..base } ],
|
|
||||||
"Struct { x: true, ..base }",
|
|
||||||
"Struct { x : true, .. base }"
|
|
||||||
);
|
|
||||||
|
|
||||||
// ExprKind::Repeat
|
// ExprKind::Repeat
|
||||||
c2!(expr, [ [(); 0] ], "[(); 0]", "[() ; 0]");
|
c2!(expr, [ [(); 0] ], "[(); 0]", "[() ; 0]");
|
||||||
@ -332,7 +309,7 @@ fn test_expr() {
|
|||||||
c1!(expr, [ (expr) ], "(expr)");
|
c1!(expr, [ (expr) ], "(expr)");
|
||||||
|
|
||||||
// ExprKind::Try
|
// ExprKind::Try
|
||||||
c2!(expr, [ expr? ], "expr?", "expr ?");
|
c1!(expr, [ expr? ], "expr?");
|
||||||
|
|
||||||
// ExprKind::Yield
|
// ExprKind::Yield
|
||||||
c1!(expr, [ yield ], "yield");
|
c1!(expr, [ yield ], "yield");
|
||||||
@ -356,12 +333,8 @@ fn test_expr() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_item() {
|
fn test_item() {
|
||||||
// ItemKind::ExternCrate
|
// ItemKind::ExternCrate
|
||||||
c2!(item, [ extern crate std; ], "extern crate std;", "extern crate std ;");
|
c1!(item, [ extern crate std; ], "extern crate std;");
|
||||||
c2!(item,
|
c1!(item, [ pub extern crate self as std; ], "pub extern crate self as std;");
|
||||||
[ pub extern crate self as std; ],
|
|
||||||
"pub extern crate self as std;",
|
|
||||||
"pub extern crate self as std ;"
|
|
||||||
);
|
|
||||||
|
|
||||||
// ItemKind::Use
|
// ItemKind::Use
|
||||||
c2!(item,
|
c2!(item,
|
||||||
@ -369,7 +342,7 @@ fn test_item() {
|
|||||||
"pub use crate::{a, b::c};",
|
"pub use crate::{a, b::c};",
|
||||||
"pub use crate::{ a, b::c } ;"
|
"pub use crate::{ a, b::c } ;"
|
||||||
);
|
);
|
||||||
c2!(item, [ pub use A::*; ], "pub use A::*;", "pub use A :: * ;");
|
c1!(item, [ pub use A::*; ], "pub use A::*;");
|
||||||
|
|
||||||
// ItemKind::Static
|
// ItemKind::Static
|
||||||
c2!(item, [ pub static S: () = {}; ], "pub static S: () = {};", "pub static S: () = {} ;");
|
c2!(item, [ pub static S: () = {}; ], "pub static S: () = {};", "pub static S: () = {} ;");
|
||||||
@ -386,21 +359,16 @@ fn test_item() {
|
|||||||
[ pub default const async unsafe extern "C" fn f() {} ],
|
[ pub default const async unsafe extern "C" fn f() {} ],
|
||||||
"pub default const async unsafe extern \"C\" fn f() {}"
|
"pub default const async unsafe extern \"C\" fn f() {}"
|
||||||
);
|
);
|
||||||
c2!(item,
|
c1!(item, [ fn g<T>(t: Vec<Vec<Vec<T>>>) {} ], "fn g<T>(t: Vec<Vec<Vec<T>>>) {}");
|
||||||
[ fn g<T>(t: Vec<Vec<Vec<T>>>) {} ],
|
c1!(item,
|
||||||
"fn g<T>(t: Vec<Vec<Vec<T>>>) {}",
|
|
||||||
"fn g < T > (t : Vec < Vec < Vec < T >> >) {}"
|
|
||||||
);
|
|
||||||
c2!(item,
|
|
||||||
[ fn h<'a>(t: &'a Vec<Cell<dyn D>>) {} ],
|
[ fn h<'a>(t: &'a Vec<Cell<dyn D>>) {} ],
|
||||||
"fn h<'a>(t: &'a Vec<Cell<dyn D>>) {}",
|
|
||||||
"fn h<'a>(t: &'a Vec<Cell<dyn D>>) {}"
|
"fn h<'a>(t: &'a Vec<Cell<dyn D>>) {}"
|
||||||
);
|
);
|
||||||
|
|
||||||
// ItemKind::Mod
|
// ItemKind::Mod
|
||||||
c2!(item, [ pub mod m; ], "pub mod m;", "pub mod m ;");
|
c1!(item, [ pub mod m; ], "pub mod m;");
|
||||||
c1!(item, [ mod m {} ], "mod m {}");
|
c1!(item, [ mod m {} ], "mod m {}");
|
||||||
c2!(item, [ unsafe mod m; ], "unsafe mod m;", "unsafe mod m ;");
|
c1!(item, [ unsafe mod m; ], "unsafe mod m;");
|
||||||
c1!(item, [ unsafe mod m {} ], "unsafe mod m {}");
|
c1!(item, [ unsafe mod m {} ], "unsafe mod m {}");
|
||||||
|
|
||||||
// ItemKind::ForeignMod
|
// ItemKind::ForeignMod
|
||||||
@ -460,7 +428,7 @@ fn test_item() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// ItemKind::Struct
|
// ItemKind::Struct
|
||||||
c2!(item, [ pub struct Unit; ], "pub struct Unit;", "pub struct Unit ;");
|
c1!(item, [ pub struct Unit; ], "pub struct Unit;");
|
||||||
c2!(item, [ struct Tuple(); ], "struct Tuple();", "struct Tuple() ;");
|
c2!(item, [ struct Tuple(); ], "struct Tuple();", "struct Tuple() ;");
|
||||||
c2!(item, [ struct Tuple(T); ], "struct Tuple(T);", "struct Tuple(T) ;");
|
c2!(item, [ struct Tuple(T); ], "struct Tuple(T);", "struct Tuple(T) ;");
|
||||||
c1!(item, [ struct Struct {} ], "struct Struct {}");
|
c1!(item, [ struct Struct {} ], "struct Struct {}");
|
||||||
@ -508,22 +476,17 @@ fn test_item() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// ItemKind::TraitAlias
|
// ItemKind::TraitAlias
|
||||||
c2!(item,
|
c1!(item,
|
||||||
[ pub trait Trait<T> = Sized where T: 'a; ],
|
[ pub trait Trait<T> = Sized where T: 'a; ],
|
||||||
"pub trait Trait<T> = Sized where T: 'a;",
|
|
||||||
"pub trait Trait<T> = Sized where T: 'a;"
|
"pub trait Trait<T> = Sized where T: 'a;"
|
||||||
);
|
);
|
||||||
|
|
||||||
// ItemKind::Impl
|
// ItemKind::Impl
|
||||||
c1!(item, [ pub impl Struct {} ], "pub impl Struct {}");
|
c1!(item, [ pub impl Struct {} ], "pub impl Struct {}");
|
||||||
c2!(item, [ impl<T> Struct<T> {} ], "impl<T> Struct<T> {}", "impl < T > Struct < T > {}");
|
c1!(item, [ impl<T> Struct<T> {} ], "impl<T> Struct<T> {}");
|
||||||
c1!(item, [ pub impl Trait for Struct {} ], "pub impl Trait for Struct {}");
|
c1!(item, [ pub impl Trait for Struct {} ], "pub impl Trait for Struct {}");
|
||||||
c2!(item,
|
c1!(item, [ impl<T> const Trait for T {} ], "impl<T> const Trait for T {}");
|
||||||
[ impl<T> const Trait for T {} ],
|
c1!(item, [ impl ~const Struct {} ], "impl ~const Struct {}");
|
||||||
"impl<T> const Trait for T {}",
|
|
||||||
"impl < T > const Trait for T {}"
|
|
||||||
);
|
|
||||||
c2!(item, [ impl ~const Struct {} ], "impl ~const Struct {}", "impl ~ const Struct {}");
|
|
||||||
|
|
||||||
// ItemKind::MacCall
|
// ItemKind::MacCall
|
||||||
c2!(item, [ mac!(...); ], "mac!(...);", "mac!(...) ;");
|
c2!(item, [ mac!(...); ], "mac!(...);", "mac!(...) ;");
|
||||||
@ -551,7 +514,7 @@ fn test_meta() {
|
|||||||
c1!(meta, [ k ], "k");
|
c1!(meta, [ k ], "k");
|
||||||
c1!(meta, [ k = "v" ], "k = \"v\"");
|
c1!(meta, [ k = "v" ], "k = \"v\"");
|
||||||
c1!(meta, [ list(k1, k2 = "v") ], "list(k1, k2 = \"v\")");
|
c1!(meta, [ list(k1, k2 = "v") ], "list(k1, k2 = \"v\")");
|
||||||
c2!(meta, [ serde::k ], "serde::k", "serde :: k");
|
c1!(meta, [ serde::k ], "serde::k");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -568,31 +531,23 @@ fn test_pat() {
|
|||||||
|
|
||||||
// PatKind::Struct
|
// PatKind::Struct
|
||||||
c1!(pat, [ Struct {} ], "Struct {}");
|
c1!(pat, [ Struct {} ], "Struct {}");
|
||||||
c2!(pat, [ Struct::<u8> {} ], "Struct::<u8> {}", "Struct :: < u8 > {}");
|
c1!(pat, [ Struct::<u8> {} ], "Struct::<u8> {}");
|
||||||
c2!(pat, [ Struct::<'static> {} ], "Struct::<'static> {}", "Struct :: < 'static > {}");
|
c1!(pat, [ Struct::<'static> {} ], "Struct::<'static> {}");
|
||||||
c1!(pat, [ Struct { x } ], "Struct { x }");
|
c1!(pat, [ Struct { x } ], "Struct { x }");
|
||||||
c2!(pat, [ Struct { x: _x } ], "Struct { x: _x }", "Struct { x : _x }");
|
c1!(pat, [ Struct { x: _x } ], "Struct { x: _x }");
|
||||||
c1!(pat, [ Struct { .. } ], "Struct { .. }");
|
c1!(pat, [ Struct { .. } ], "Struct { .. }");
|
||||||
c1!(pat, [ Struct { x, .. } ], "Struct { x, .. }");
|
c1!(pat, [ Struct { x, .. } ], "Struct { x, .. }");
|
||||||
c2!(pat, [ Struct { x: _x, .. } ], "Struct { x: _x, .. }", "Struct { x : _x, .. }");
|
c1!(pat, [ Struct { x: _x, .. } ], "Struct { x: _x, .. }");
|
||||||
c2!(pat,
|
c1!(pat, [ <Struct as Trait>::Type {} ], "<Struct as Trait>::Type {}");
|
||||||
[ <Struct as Trait>::Type {} ],
|
|
||||||
"<Struct as Trait>::Type {}",
|
|
||||||
"< Struct as Trait > :: Type {}"
|
|
||||||
);
|
|
||||||
|
|
||||||
// PatKind::TupleStruct
|
// PatKind::TupleStruct
|
||||||
c1!(pat, [ Tuple() ], "Tuple()");
|
c1!(pat, [ Tuple() ], "Tuple()");
|
||||||
c2!(pat, [ Tuple::<u8>() ], "Tuple::<u8>()", "Tuple :: < u8 > ()");
|
c1!(pat, [ Tuple::<u8>() ], "Tuple::<u8>()");
|
||||||
c2!(pat, [ Tuple::<'static>() ], "Tuple::<'static>()", "Tuple :: < 'static > ()");
|
c1!(pat, [ Tuple::<'static>() ], "Tuple::<'static>()");
|
||||||
c1!(pat, [ Tuple(x) ], "Tuple(x)");
|
c1!(pat, [ Tuple(x) ], "Tuple(x)");
|
||||||
c1!(pat, [ Tuple(..) ], "Tuple(..)");
|
c1!(pat, [ Tuple(..) ], "Tuple(..)");
|
||||||
c1!(pat, [ Tuple(x, ..) ], "Tuple(x, ..)");
|
c1!(pat, [ Tuple(x, ..) ], "Tuple(x, ..)");
|
||||||
c2!(pat,
|
c1!(pat, [ <Struct as Trait>::Type() ], "<Struct as Trait>::Type()");
|
||||||
[ <Struct as Trait>::Type() ],
|
|
||||||
"<Struct as Trait>::Type()",
|
|
||||||
"< Struct as Trait > :: Type()"
|
|
||||||
);
|
|
||||||
|
|
||||||
// PatKind::Or
|
// PatKind::Or
|
||||||
c1!(pat, [ true | false ], "true | false");
|
c1!(pat, [ true | false ], "true | false");
|
||||||
@ -600,10 +555,10 @@ fn test_pat() {
|
|||||||
c2!(pat, [ |true| false ], "true | false", "|true| false");
|
c2!(pat, [ |true| false ], "true | false", "|true| false");
|
||||||
|
|
||||||
// PatKind::Path
|
// PatKind::Path
|
||||||
c2!(pat, [ crate::Path ], "crate::Path", "crate :: Path");
|
c1!(pat, [ crate::Path ], "crate::Path");
|
||||||
c2!(pat, [ Path::<u8> ], "Path::<u8>", "Path :: < u8 >");
|
c1!(pat, [ Path::<u8> ], "Path::<u8>");
|
||||||
c2!(pat, [ Path::<'static> ], "Path::<'static>", "Path :: < 'static >");
|
c1!(pat, [ Path::<'static> ], "Path::<'static>");
|
||||||
c2!(pat, [ <Struct as Trait>::Type ], "<Struct as Trait>::Type", "< Struct as Trait > :: Type");
|
c1!(pat, [ <Struct as Trait>::Type ], "<Struct as Trait>::Type");
|
||||||
|
|
||||||
// PatKind::Tuple
|
// PatKind::Tuple
|
||||||
c1!(pat, [ () ], "()");
|
c1!(pat, [ () ], "()");
|
||||||
@ -614,18 +569,18 @@ fn test_pat() {
|
|||||||
c1!(pat, [ box pat ], "box pat");
|
c1!(pat, [ box pat ], "box pat");
|
||||||
|
|
||||||
// PatKind::Ref
|
// PatKind::Ref
|
||||||
c2!(pat, [ &pat ], "&pat", "& pat");
|
c1!(pat, [ &pat ], "&pat");
|
||||||
c2!(pat, [ &mut pat ], "&mut pat", "& mut pat");
|
c1!(pat, [ &mut pat ], "&mut pat");
|
||||||
|
|
||||||
// PatKind::Lit
|
// PatKind::Lit
|
||||||
c1!(pat, [ 1_000_i8 ], "1_000_i8");
|
c1!(pat, [ 1_000_i8 ], "1_000_i8");
|
||||||
|
|
||||||
// PatKind::Range
|
// PatKind::Range
|
||||||
c2!(pat, [ ..1 ], "..1", ".. 1");
|
c1!(pat, [ ..1 ], "..1");
|
||||||
c2!(pat, [ 0.. ], "0..", "0 ..");
|
c1!(pat, [ 0.. ], "0..");
|
||||||
c2!(pat, [ 0..1 ], "0..1", "0 .. 1");
|
c1!(pat, [ 0..1 ], "0..1");
|
||||||
c2!(pat, [ 0..=1 ], "0..=1", "0 ..= 1");
|
c1!(pat, [ 0..=1 ], "0..=1");
|
||||||
c2!(pat, [ -2..=-1 ], "-2..=-1", "- 2 ..= - 1");
|
c1!(pat, [ -2..=-1 ], "-2..=-1");
|
||||||
|
|
||||||
// PatKind::Slice
|
// PatKind::Slice
|
||||||
c1!(pat, [ [] ], "[]");
|
c1!(pat, [ [] ], "[]");
|
||||||
@ -644,19 +599,19 @@ fn test_pat() {
|
|||||||
c1!(pat, [ (pat) ], "(pat)");
|
c1!(pat, [ (pat) ], "(pat)");
|
||||||
|
|
||||||
// PatKind::MacCall
|
// PatKind::MacCall
|
||||||
c2!(pat, [ mac!(...) ], "mac!(...)", "mac! (...)");
|
c1!(pat, [ mac!(...) ], "mac!(...)");
|
||||||
c2!(pat, [ mac![...] ], "mac![...]", "mac! [...]");
|
c1!(pat, [ mac![...] ], "mac![...]");
|
||||||
c1!(pat, [ mac! { ... } ], "mac! { ... }");
|
c1!(pat, [ mac! { ... } ], "mac! { ... }");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_path() {
|
fn test_path() {
|
||||||
c1!(path, [ thing ], "thing");
|
c1!(path, [ thing ], "thing");
|
||||||
c2!(path, [ m::thing ], "m::thing", "m :: thing");
|
c1!(path, [ m::thing ], "m::thing");
|
||||||
c2!(path, [ self::thing ], "self::thing", "self :: thing");
|
c1!(path, [ self::thing ], "self::thing");
|
||||||
c2!(path, [ crate::thing ], "crate::thing", "crate :: thing");
|
c1!(path, [ crate::thing ], "crate::thing");
|
||||||
c2!(path, [ Self::thing ], "Self::thing", "Self :: thing");
|
c1!(path, [ Self::thing ], "Self::thing");
|
||||||
c2!(path, [ Self<'static> ], "Self<'static>", "Self < 'static >");
|
c1!(path, [ Self<'static> ], "Self<'static>");
|
||||||
c2!(path, [ Self::<'static> ], "Self<'static>", "Self::<'static>");
|
c2!(path, [ Self::<'static> ], "Self<'static>", "Self::<'static>");
|
||||||
c1!(path, [ Self() ], "Self()");
|
c1!(path, [ Self() ], "Self()");
|
||||||
c1!(path, [ Self() -> () ], "Self() -> ()");
|
c1!(path, [ Self() -> () ], "Self() -> ()");
|
||||||
@ -676,7 +631,7 @@ fn test_stmt() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// StmtKind::Item
|
// StmtKind::Item
|
||||||
c2!(stmt, [ struct S; ], "struct S;", "struct S ;");
|
c1!(stmt, [ struct S; ], "struct S;");
|
||||||
c1!(stmt, [ struct S {} ], "struct S {}");
|
c1!(stmt, [ struct S {} ], "struct S {}");
|
||||||
|
|
||||||
// StmtKind::Expr
|
// StmtKind::Expr
|
||||||
@ -689,8 +644,8 @@ fn test_stmt() {
|
|||||||
c1!(stmt, [ ; ], ";");
|
c1!(stmt, [ ; ], ";");
|
||||||
|
|
||||||
// StmtKind::MacCall
|
// StmtKind::MacCall
|
||||||
c2!(stmt, [ mac!(...) ], "mac!(...)", "mac! (...)");
|
c1!(stmt, [ mac!(...) ], "mac!(...)");
|
||||||
c2!(stmt, [ mac![...] ], "mac![...]", "mac! [...]");
|
c1!(stmt, [ mac![...] ], "mac![...]");
|
||||||
c1!(stmt, [ mac! { ... } ], "mac! { ... }");
|
c1!(stmt, [ mac! { ... } ], "mac! { ... }");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,26 +655,26 @@ fn test_ty() {
|
|||||||
c1!(ty, [ [T] ], "[T]");
|
c1!(ty, [ [T] ], "[T]");
|
||||||
|
|
||||||
// TyKind::Array
|
// TyKind::Array
|
||||||
c2!(ty, [ [T; 0] ], "[T; 0]", "[T ; 0]");
|
c1!(ty, [ [T; 0] ], "[T; 0]");
|
||||||
|
|
||||||
// TyKind::Ptr
|
// TyKind::Ptr
|
||||||
c2!(ty, [ *const T ], "*const T", "* const T");
|
c1!(ty, [ *const T ], "*const T");
|
||||||
c2!(ty, [ *mut T ], "*mut T", "* mut T");
|
c1!(ty, [ *mut T ], "*mut T");
|
||||||
|
|
||||||
// TyKind::Ref
|
// TyKind::Ref
|
||||||
c2!(ty, [ &T ], "&T", "& T");
|
c1!(ty, [ &T ], "&T");
|
||||||
c2!(ty, [ &mut T ], "&mut T", "& mut T");
|
c1!(ty, [ &mut T ], "&mut T");
|
||||||
c2!(ty, [ &'a T ], "&'a T", "& 'a T");
|
c1!(ty, [ &'a T ], "&'a T");
|
||||||
c2!(ty, [ &'a mut [T] ], "&'a mut [T]", "& 'a mut [T]");
|
c1!(ty, [ &'a mut [T] ], "&'a mut [T]");
|
||||||
c2!(ty, [ &A<B<C<D<E>>>> ], "&A<B<C<D<E>>>>", "& A < B < C < D < E >> >>");
|
c1!(ty, [ &A<B<C<D<E>>>> ], "&A<B<C<D<E>>>>");
|
||||||
|
|
||||||
// TyKind::BareFn
|
// TyKind::BareFn
|
||||||
c1!(ty, [ fn() ], "fn()");
|
c1!(ty, [ fn() ], "fn()");
|
||||||
c1!(ty, [ fn() -> () ], "fn() -> ()");
|
c1!(ty, [ fn() -> () ], "fn() -> ()");
|
||||||
c1!(ty, [ fn(u8) ], "fn(u8)");
|
c1!(ty, [ fn(u8) ], "fn(u8)");
|
||||||
c2!(ty, [ fn(x: u8) ], "fn(x: u8)", "fn(x : u8)");
|
c1!(ty, [ fn(x: u8) ], "fn(x: u8)");
|
||||||
c2!(ty, [ for<> fn() ], "fn()", "for<> fn()");
|
c2!(ty, [ for<> fn() ], "fn()", "for<> fn()");
|
||||||
c2!(ty, [ for<'a> fn() ], "for<'a> fn()", "for < 'a > fn()");
|
c1!(ty, [ for<'a> fn() ], "for<'a> fn()");
|
||||||
|
|
||||||
// TyKind::Never
|
// TyKind::Never
|
||||||
c1!(ty, [ ! ], "!");
|
c1!(ty, [ ! ], "!");
|
||||||
@ -735,28 +690,28 @@ fn test_ty() {
|
|||||||
|
|
||||||
// TyKind::Path
|
// TyKind::Path
|
||||||
c1!(ty, [ T ], "T");
|
c1!(ty, [ T ], "T");
|
||||||
c2!(ty, [ Ref<'a> ], "Ref<'a>", "Ref < 'a >");
|
c1!(ty, [ Ref<'a> ], "Ref<'a>");
|
||||||
c2!(ty, [ PhantomData<T> ], "PhantomData<T>", "PhantomData < T >");
|
c1!(ty, [ PhantomData<T> ], "PhantomData<T>");
|
||||||
c2!(ty, [ PhantomData::<T> ], "PhantomData<T>", "PhantomData::<T>");
|
c2!(ty, [ PhantomData::<T> ], "PhantomData<T>", "PhantomData::<T>");
|
||||||
c2!(ty, [ Fn() -> ! ], "Fn() -> !", "Fn() ->!");
|
c2!(ty, [ Fn() -> ! ], "Fn() -> !", "Fn() ->!");
|
||||||
c2!(ty, [ Fn(u8) -> ! ], "Fn(u8) -> !", "Fn(u8) ->!"); // FIXME
|
c2!(ty, [ Fn(u8) -> ! ], "Fn(u8) -> !", "Fn(u8) ->!"); // FIXME
|
||||||
c2!(ty, [ <Struct as Trait>::Type ], "<Struct as Trait>::Type", "< Struct as Trait > :: Type");
|
c1!(ty, [ <Struct as Trait>::Type ], "<Struct as Trait>::Type");
|
||||||
|
|
||||||
// TyKind::TraitObject
|
// TyKind::TraitObject
|
||||||
c1!(ty, [ dyn Send ], "dyn Send");
|
c1!(ty, [ dyn Send ], "dyn Send");
|
||||||
c1!(ty, [ dyn Send + 'a ], "dyn Send + 'a");
|
c1!(ty, [ dyn Send + 'a ], "dyn Send + 'a");
|
||||||
c1!(ty, [ dyn 'a + Send ], "dyn 'a + Send");
|
c1!(ty, [ dyn 'a + Send ], "dyn 'a + Send");
|
||||||
c2!(ty, [ dyn ?Sized ], "dyn ?Sized", "dyn ? Sized");
|
c1!(ty, [ dyn ?Sized ], "dyn ?Sized");
|
||||||
c2!(ty, [ dyn ~const Clone ], "dyn ~const Clone", "dyn ~ const Clone");
|
c1!(ty, [ dyn ~const Clone ], "dyn ~const Clone");
|
||||||
c2!(ty, [ dyn for<'a> Send ], "dyn for<'a> Send", "dyn for < 'a > Send");
|
c1!(ty, [ dyn for<'a> Send ], "dyn for<'a> Send");
|
||||||
|
|
||||||
// TyKind::ImplTrait
|
// TyKind::ImplTrait
|
||||||
c1!(ty, [ impl Send ], "impl Send");
|
c1!(ty, [ impl Send ], "impl Send");
|
||||||
c1!(ty, [ impl Send + 'a ], "impl Send + 'a");
|
c1!(ty, [ impl Send + 'a ], "impl Send + 'a");
|
||||||
c1!(ty, [ impl 'a + Send ], "impl 'a + Send");
|
c1!(ty, [ impl 'a + Send ], "impl 'a + Send");
|
||||||
c2!(ty, [ impl ?Sized ], "impl ?Sized", "impl ? Sized");
|
c1!(ty, [ impl ?Sized ], "impl ?Sized");
|
||||||
c2!(ty, [ impl ~const Clone ], "impl ~const Clone", "impl ~ const Clone");
|
c1!(ty, [ impl ~const Clone ], "impl ~const Clone");
|
||||||
c2!(ty, [ impl for<'a> Send ], "impl for<'a> Send", "impl for < 'a > Send");
|
c1!(ty, [ impl for<'a> Send ], "impl for<'a> Send");
|
||||||
|
|
||||||
// TyKind::Paren
|
// TyKind::Paren
|
||||||
c1!(ty, [ (T) ], "(T)");
|
c1!(ty, [ (T) ], "(T)");
|
||||||
@ -769,8 +724,8 @@ fn test_ty() {
|
|||||||
// TyKind::ImplicitSelf: there is no syntax for this.
|
// TyKind::ImplicitSelf: there is no syntax for this.
|
||||||
|
|
||||||
// TyKind::MacCall
|
// TyKind::MacCall
|
||||||
c2!(ty, [ mac!(...) ], "mac!(...)", "mac! (...)");
|
c1!(ty, [ mac!(...) ], "mac!(...)");
|
||||||
c2!(ty, [ mac![...] ], "mac![...]", "mac! [...]");
|
c1!(ty, [ mac![...] ], "mac![...]");
|
||||||
c1!(ty, [ mac! { ... } ], "mac! { ... }");
|
c1!(ty, [ mac! { ... } ], "mac! { ... }");
|
||||||
|
|
||||||
// TyKind::Err: untestable.
|
// TyKind::Err: untestable.
|
||||||
@ -815,7 +770,7 @@ macro_rules! p {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_punct() {
|
fn test_punct() {
|
||||||
// For all these cases, we must preserve spaces between the tokens.
|
// For all these cases, we should preserve spaces between the tokens.
|
||||||
// Otherwise, any old proc macro that parses pretty-printed code might glue
|
// Otherwise, any old proc macro that parses pretty-printed code might glue
|
||||||
// together tokens that shouldn't be glued.
|
// together tokens that shouldn't be glued.
|
||||||
p!([ = = < < <= <= == == != != >= >= > > ], "= = < < <= <= == == != != >= >= > >");
|
p!([ = = < < <= <= == == != != >= >= > > ], "= = < < <= <= == == != != >= >= > >");
|
||||||
@ -828,10 +783,7 @@ fn test_punct() {
|
|||||||
p!([ + + += += - - -= -= * * *= *= / / /= /= ], "+ + += += - - -= -= * * *= *= / / /= /=");
|
p!([ + + += += - - -= -= * * *= *= / / /= /= ], "+ + += += - - -= -= * * *= *= / / /= /=");
|
||||||
p!([ % % %= %= ^ ^ ^= ^= << << <<= <<= >> >> >>= >>= ],
|
p!([ % % %= %= ^ ^ ^= ^= << << <<= <<= >> >> >>= >>= ],
|
||||||
"% % %= %= ^ ^ ^= ^= << << <<= <<= >> >> >>= >>=");
|
"% % %= %= ^ ^ ^= ^= << << <<= <<= >> >> >>= >>=");
|
||||||
|
p!([ +! ?= |> >>@ --> <-- $$ =====> ], "+! ?= |> >>@ --> <-- $$=====>");
|
||||||
// For these one we must insert spaces between adjacent tokens, again due
|
p!([ ,; ;, ** @@ $+$ >< <> ?? +== ], ",; ;, ** @@ $+$>< <> ?? +=="); // FIXME: `$ >` -> `$>`
|
||||||
// to proc macros.
|
p!([ :#!@|$=&*,+;*~? ], ":#!@|$=&*,+;*~?");
|
||||||
p!([ +! ?= |> >>@ --> <-- $$ =====> ], "+! ? = | > >> @ - -> <- - $$== == =>"); // FIXME
|
|
||||||
p!([ ,; ;, ** @@ $+$ >< <> ?? +== ], ", ; ;, * * @ @ $+ $> < < > ? ? += ="); // FIXME
|
|
||||||
p!([ :#!@|$=&*,+;*~? ], ": #! @ | $= & *, + ; * ~ ?"); // FIXME
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): struct ItemWithSemi;
|
PRINT-ATTR INPUT (DISPLAY): struct ItemWithSemi;
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): struct ItemWithSemi ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
@ -46,6 +47,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!";
|
PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!";
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_let] let string = "Hello, world!" ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
@ -88,6 +90,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro!("{}", string) ;
|
PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro!("{}", string) ;
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_my_macro_stmt] my_macro! ("{}", string) ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
@ -141,6 +144,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): second_make_stmt!(#[allow(dead_code)] struct Bar {}) ;
|
PRINT-ATTR INPUT (DISPLAY): second_make_stmt!(#[allow(dead_code)] struct Bar {}) ;
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): second_make_stmt! (#[allow(dead_code)] struct Bar {}) ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "second_make_stmt",
|
ident: "second_make_stmt",
|
||||||
@ -289,6 +293,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct NonBracedStruct;
|
PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct NonBracedStruct;
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): #[rustc_dummy] struct NonBracedStruct ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): fn foo<T: MyTrait<MyStruct<{ true } >>>() {}
|
PRINT-ATTR INPUT (DISPLAY): fn foo<T: MyTrait<MyStruct<{ true } >>>() {}
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): fn foo < T : MyTrait < MyStruct < { true } >>> () {}
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "fn",
|
ident: "fn",
|
||||||
@ -77,6 +78,8 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): impl<T> MyTrait<T> for MyStruct<{ true } > { #![rustc_dummy] }
|
PRINT-ATTR INPUT (DISPLAY): impl<T> MyTrait<T> for MyStruct<{ true } > { #![rustc_dummy] }
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): impl < T > MyTrait < T > for MyStruct < { true } > { #![rustc_dummy] }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): impl < T > MyTrait < T > for MyStruct < { true } > { #! [rustc_dummy] }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "impl",
|
ident: "impl",
|
||||||
|
@ -30,6 +30,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!";
|
PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!";
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_let] let string = "Hello, world!" ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
@ -72,6 +73,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro!("{}", string) ;
|
PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro!("{}", string) ;
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_my_macro_stmt] my_macro! ("{}", string) ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
@ -125,6 +127,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): second_make_stmt!(#[allow(dead_code)] struct Bar {}) ;
|
PRINT-ATTR INPUT (DISPLAY): second_make_stmt!(#[allow(dead_code)] struct Bar {}) ;
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): second_make_stmt! (#[allow(dead_code)] struct Bar {}) ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "second_make_stmt",
|
ident: "second_make_stmt",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): #[derive(Print)] struct AttributeDerive { #[cfg(FALSE)] field: u8, }
|
PRINT-ATTR INPUT (DISPLAY): #[derive(Print)] struct AttributeDerive { #[cfg(FALSE)] field: u8, }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[derive(Print)] struct AttributeDerive { #[cfg(FALSE)] field : u8, }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
@ -131,6 +132,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { #[cfg(FALSE)] field: u8, }
|
PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { #[cfg(FALSE)] field: u8, }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): struct DeriveAttribute { #[cfg(FALSE)] field : u8, }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -40,7 +40,6 @@ pub fn no_output(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
assert!(attr.to_string().is_empty());
|
assert!(attr.to_string().is_empty());
|
||||||
assert!(!item.to_string().is_empty());
|
assert!(!item.to_string().is_empty());
|
||||||
"".parse().unwrap()
|
"".parse().unwrap()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
|
@ -15,6 +15,8 @@ PRINT-BANG INPUT (DISPLAY): 1 + 1, { "a" }, let a = 1;, String, my_name, 'a, my_
|
|||||||
std::option::Option, pub(in some::path) , [a b c], -30
|
std::option::Option, pub(in some::path) , [a b c], -30
|
||||||
PRINT-BANG RE-COLLECTED (DISPLAY): 1 + 1, { "a" }, let a = 1, String, my_name, 'a, my_val = 30,
|
PRINT-BANG RE-COLLECTED (DISPLAY): 1 + 1, { "a" }, let a = 1, String, my_name, 'a, my_val = 30,
|
||||||
std::option::Option, pub(in some::path), [a b c], -30
|
std::option::Option, pub(in some::path), [a b c], -30
|
||||||
|
PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): 1 + 1, { "a" }, let a = 1, String, my_name, 'a, my_val = 30,
|
||||||
|
std :: option :: Option, pub(in some :: path), [a b c], - 30
|
||||||
PRINT-BANG INPUT (DEBUG): TokenStream [
|
PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
Group {
|
Group {
|
||||||
delimiter: None,
|
delimiter: None,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
PRINT-BANG INPUT (DISPLAY): Vec<u8>
|
PRINT-BANG INPUT (DISPLAY): Vec<u8>
|
||||||
PRINT-BANG RE-COLLECTED (DISPLAY): Vec < u8 >
|
PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): Vec < u8 >
|
||||||
PRINT-BANG INPUT (DEBUG): TokenStream [
|
PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
Group {
|
Group {
|
||||||
delimiter: None,
|
delimiter: None,
|
||||||
|
@ -1,4 +1,16 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): impl Foo <
|
PRINT-ATTR INPUT (DISPLAY): impl
|
||||||
|
Foo<[u8;
|
||||||
|
{
|
||||||
|
#![rustc_dummy(cursed_inner)] #![allow(unused)] struct Inner
|
||||||
|
{ field: [u8; { #![rustc_dummy(another_cursed_inner)] 1 }] } 0
|
||||||
|
}] > { #![rustc_dummy(evaluated_attr)] fn bar() {} }
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): impl Foo <
|
||||||
|
[u8;
|
||||||
|
{
|
||||||
|
#![rustc_dummy(cursed_inner)] #![allow(unused)] struct Inner
|
||||||
|
{ field: [u8; { #![rustc_dummy(another_cursed_inner)] 1 }] } 0
|
||||||
|
}] > { #![rustc_dummy(evaluated_attr)] fn bar() {} }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): impl Foo <
|
||||||
[u8 ;
|
[u8 ;
|
||||||
{
|
{
|
||||||
#! [rustc_dummy(cursed_inner)] #! [allow(unused)] struct Inner
|
#! [rustc_dummy(cursed_inner)] #! [allow(unused)] struct Inner
|
||||||
@ -35,7 +47,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
stream: TokenStream [
|
stream: TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
spacing: Alone,
|
spacing: Joint,
|
||||||
span: $DIR/cfg-eval-inner.rs:19:5: 19:6 (#0),
|
span: $DIR/cfg-eval-inner.rs:19:5: 19:6 (#0),
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
@ -130,7 +142,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
stream: TokenStream [
|
stream: TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
spacing: Alone,
|
spacing: Joint,
|
||||||
span: $DIR/cfg-eval-inner.rs:23:13: 23:14 (#0),
|
span: $DIR/cfg-eval-inner.rs:23:13: 23:14 (#0),
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
@ -195,7 +207,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
stream: TokenStream [
|
stream: TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
spacing: Alone,
|
spacing: Joint,
|
||||||
span: $DIR/cfg-eval-inner.rs:32:5: 32:6 (#0),
|
span: $DIR/cfg-eval-inner.rs:32:5: 32:6 (#0),
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): struct S1 { #[cfg(all())] #[allow()] field_true: u8, }
|
PRINT-ATTR INPUT (DISPLAY): struct S1 { #[cfg(all())] #[allow()] field_true: u8, }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): struct S1 { #[cfg(all())] #[allow()] field_true : u8, }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -3,6 +3,11 @@ PRINT-DERIVE INPUT (DISPLAY): struct Foo
|
|||||||
field :
|
field :
|
||||||
[bool ; { #[rustc_dummy] struct Inner { other_inner_field: u8, } 0 }]
|
[bool ; { #[rustc_dummy] struct Inner { other_inner_field: u8, } 0 }]
|
||||||
}
|
}
|
||||||
|
PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): struct Foo
|
||||||
|
{
|
||||||
|
field :
|
||||||
|
[bool ; { #[rustc_dummy] struct Inner { other_inner_field : u8, } 0 }]
|
||||||
|
}
|
||||||
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): /// 1
|
PRINT-ATTR INPUT (DISPLAY): /// 1
|
||||||
#[rustfmt::attr2] #[doc = "3"] #[doc = "4"] #[rustfmt::attr5] /// 6
|
#[rustfmt::attr2] #[doc = "3"] #[doc = "4"] #[rustfmt::attr5] /// 6
|
||||||
#[print_attr(nodebug)] struct S;
|
#[print_attr(nodebug)] struct S;
|
||||||
PRINT-ATTR RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
|
PRINT-ATTR RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt::attr2] #[doc = "3"] #[doc = "4"] #[rustfmt::attr5]
|
||||||
|
#[doc = " 6"] #[print_attr(nodebug)] struct S ;
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
|
||||||
#[rustfmt :: attr5] #[doc = " 6"] #[print_attr(nodebug)] struct S ;
|
#[rustfmt :: attr5] #[doc = " 6"] #[print_attr(nodebug)] struct S ;
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
|
PRINT-ATTR INPUT (DISPLAY): #[doc = " 1"] #[rustfmt::attr2] #[doc = "3"] #[doc = "4"] #[rustfmt::attr5]
|
||||||
|
#[doc = " 6"] struct S ;
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
|
||||||
#[rustfmt :: attr5] #[doc = " 6"] struct S ;
|
#[rustfmt :: attr5] #[doc = " 6"] struct S ;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): #[deny(unused_attributes)] mod module_with_attrs { #![rustfmt::skip] }
|
PRINT-ATTR INPUT (DISPLAY): #[deny(unused_attributes)] mod module_with_attrs { #![rustfmt::skip] }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[deny(unused_attributes)] mod module_with_attrs { #! [rustfmt :: skip] }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
|
@ -7,6 +7,8 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second)] fn foo()
|
PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second)] fn foo()
|
||||||
{ #![print_target_and_args(third)] #![print_target_and_args(fourth)] }
|
{ #![print_target_and_args(third)] #![print_target_and_args(fourth)] }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[print_target_and_args(second)] fn foo()
|
||||||
|
{ #! [print_target_and_args(third)] #! [print_target_and_args(fourth)] }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
@ -122,6 +124,8 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): fn foo()
|
PRINT-ATTR INPUT (DISPLAY): fn foo()
|
||||||
{ #![print_target_and_args(third)] #![print_target_and_args(fourth)] }
|
{ #![print_target_and_args(third)] #![print_target_and_args(fourth)] }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): fn foo()
|
||||||
|
{ #! [print_target_and_args(third)] #! [print_target_and_args(fourth)] }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "fn",
|
ident: "fn",
|
||||||
@ -211,6 +215,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): fn foo() { #![print_target_and_args(fourth)] }
|
PRINT-ATTR INPUT (DISPLAY): fn foo() { #![print_target_and_args(fourth)] }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): fn foo() { #! [print_target_and_args(fourth)] }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "fn",
|
ident: "fn",
|
||||||
@ -298,6 +303,8 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(mod_second)] mod inline_mod
|
PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(mod_second)] mod inline_mod
|
||||||
|
{ #![print_target_and_args(mod_third)] #![print_target_and_args(mod_fourth)] }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[print_target_and_args(mod_second)] mod inline_mod
|
||||||
{
|
{
|
||||||
#! [print_target_and_args(mod_third)] #!
|
#! [print_target_and_args(mod_third)] #!
|
||||||
[print_target_and_args(mod_fourth)]
|
[print_target_and_args(mod_fourth)]
|
||||||
@ -411,6 +418,8 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): mod inline_mod
|
PRINT-ATTR INPUT (DISPLAY): mod inline_mod
|
||||||
|
{ #![print_target_and_args(mod_third)] #![print_target_and_args(mod_fourth)] }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): mod inline_mod
|
||||||
{
|
{
|
||||||
#! [print_target_and_args(mod_third)] #!
|
#! [print_target_and_args(mod_third)] #!
|
||||||
[print_target_and_args(mod_fourth)]
|
[print_target_and_args(mod_fourth)]
|
||||||
@ -499,6 +508,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): mod inline_mod { #![print_target_and_args(mod_fourth)] }
|
PRINT-ATTR INPUT (DISPLAY): mod inline_mod { #![print_target_and_args(mod_fourth)] }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): mod inline_mod { #! [print_target_and_args(mod_fourth)] }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "mod",
|
ident: "mod",
|
||||||
@ -569,6 +579,8 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-DERIVE INPUT (DISPLAY): struct MyDerivePrint
|
PRINT-DERIVE INPUT (DISPLAY): struct MyDerivePrint
|
||||||
|
{ field: [u8; { match true { _ => { #![rustc_dummy(third)] true } } ; 0 }] }
|
||||||
|
PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): struct MyDerivePrint
|
||||||
{
|
{
|
||||||
field :
|
field :
|
||||||
[u8 ; { match true { _ => { #! [rustc_dummy(third)] true } } ; 0 }]
|
[u8 ; { match true { _ => { #! [rustc_dummy(third)] true } } ; 0 }]
|
||||||
@ -639,7 +651,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
|||||||
stream: TokenStream [
|
stream: TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
spacing: Alone,
|
spacing: Joint,
|
||||||
span: $DIR/inner-attrs.rs:40:17: 40:18 (#0),
|
span: $DIR/inner-attrs.rs:40:17: 40:18 (#0),
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
@ -706,6 +718,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): (3, 4, { #![cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
|
PRINT-ATTR INPUT (DISPLAY): (3, 4, { #![cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Group {
|
Group {
|
||||||
delimiter: Parenthesis,
|
delimiter: Parenthesis,
|
||||||
@ -820,6 +833,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): (3, 4, { #![cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
|
PRINT-ATTR INPUT (DISPLAY): (3, 4, { #![cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Group {
|
Group {
|
||||||
delimiter: Parenthesis,
|
delimiter: Parenthesis,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): fn main() { &|_: u8| {} ; mul_2!(1 + 1) ; }
|
PRINT-ATTR INPUT (DISPLAY): fn main() { &|_: u8| {} ; mul_2!(1 + 1) ; }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): fn main() { &| _ : u8 | {} ; mul_2! (1 + 1) ; }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "fn",
|
ident: "fn",
|
||||||
|
@ -22,6 +22,54 @@ struct Foo < #[cfg(FALSE)] A, B >
|
|||||||
{ #![cfg_attr(not(FALSE), cfg(FALSE))] } 0
|
{ #![cfg_attr(not(FALSE), cfg(FALSE))] } 0
|
||||||
}], #[print_helper(d)] fourth: B
|
}], #[print_helper(d)] fourth: B
|
||||||
}
|
}
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[derive(Print)] #[print_helper(b)]
|
||||||
|
struct Foo <#[cfg(FALSE)] A, B >
|
||||||
|
{
|
||||||
|
#[cfg(FALSE)] first: String, #[cfg_attr(FALSE, deny(warnings))] second:
|
||||||
|
bool, third:
|
||||||
|
[u8;
|
||||||
|
{
|
||||||
|
#[cfg(FALSE)] struct Bar; #[cfg(not(FALSE))] struct Inner;
|
||||||
|
#[cfg(FALSE)] let a = 25; match true
|
||||||
|
{
|
||||||
|
#[cfg(FALSE)] true => {}, #[cfg_attr(not(FALSE), allow(warnings))]
|
||||||
|
false => {}, _ => {}
|
||||||
|
} ; #[print_helper(should_be_removed)] fn removed_fn()
|
||||||
|
{ #![cfg(FALSE)] } #[print_helper(c)] #[cfg(not(FALSE))] fn kept_fn()
|
||||||
|
{ #![cfg(not(FALSE))] let my_val = true; } enum TupleEnum
|
||||||
|
{
|
||||||
|
Foo(#[cfg(FALSE)] u8, #[cfg(FALSE)] bool, #[cfg(not(FALSE))] i32,
|
||||||
|
#[cfg(FALSE)] String, u8)
|
||||||
|
} struct
|
||||||
|
TupleStruct(#[cfg(FALSE)] String, #[cfg(not(FALSE))] i32,
|
||||||
|
#[cfg(FALSE)] bool, u8) ; fn plain_removed_fn()
|
||||||
|
{ #![cfg_attr(not(FALSE), cfg(FALSE))] } 0
|
||||||
|
}], #[print_helper(d)] fourth: B
|
||||||
|
}
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[derive(Print)] #[print_helper(b)]
|
||||||
|
struct Foo <#[cfg(FALSE)] A, B >
|
||||||
|
{
|
||||||
|
#[cfg(FALSE)] first : String, #[cfg_attr(FALSE, deny(warnings))] second :
|
||||||
|
bool, third :
|
||||||
|
[u8 ;
|
||||||
|
{
|
||||||
|
#[cfg(FALSE)] struct Bar ; #[cfg(not(FALSE))] struct Inner ;
|
||||||
|
#[cfg(FALSE)] let a = 25 ; match true
|
||||||
|
{
|
||||||
|
#[cfg(FALSE)] true => {}, #[cfg_attr(not(FALSE), allow(warnings))]
|
||||||
|
false => {}, _ => {}
|
||||||
|
} ; #[print_helper(should_be_removed)] fn removed_fn()
|
||||||
|
{ #! [cfg(FALSE)] } #[print_helper(c)] #[cfg(not(FALSE))] fn kept_fn()
|
||||||
|
{ #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum
|
||||||
|
{
|
||||||
|
Foo(#[cfg(FALSE)] u8, #[cfg(FALSE)] bool, #[cfg(not(FALSE))] i32,
|
||||||
|
#[cfg(FALSE)] String, u8)
|
||||||
|
} struct
|
||||||
|
TupleStruct(#[cfg(FALSE)] String, #[cfg(not(FALSE))] i32,
|
||||||
|
#[cfg(FALSE)] bool, u8) ; fn plain_removed_fn()
|
||||||
|
{ #! [cfg_attr(not(FALSE), cfg(FALSE))] } 0
|
||||||
|
}], #[print_helper(d)] fourth : B
|
||||||
|
}
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
@ -1285,6 +1333,19 @@ PRINT-DERIVE INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[print_hel
|
|||||||
TupleStruct(#[cfg(not(FALSE))] i32, u8) ; 0
|
TupleStruct(#[cfg(not(FALSE))] i32, u8) ; 0
|
||||||
}], #[print_helper(d)] fourth: B
|
}], #[print_helper(d)] fourth: B
|
||||||
}
|
}
|
||||||
|
PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[print_helper(b)] struct Foo <B >
|
||||||
|
{
|
||||||
|
second : bool, third :
|
||||||
|
[u8 ;
|
||||||
|
{
|
||||||
|
#[cfg(not(FALSE))] struct Inner ; match true
|
||||||
|
{ #[allow(warnings)] false => {}, _ => {} } ; #[print_helper(c)]
|
||||||
|
#[cfg(not(FALSE))] fn kept_fn()
|
||||||
|
{ #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum
|
||||||
|
{ Foo(#[cfg(not(FALSE))] i32, u8) } struct
|
||||||
|
TupleStruct(#[cfg(not(FALSE))] i32, u8) ; 0
|
||||||
|
}], #[print_helper(d)] fourth : B
|
||||||
|
}
|
||||||
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
|
@ -46,7 +46,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
|
|||||||
stream: TokenStream [
|
stream: TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
spacing: Alone,
|
spacing: Joint,
|
||||||
span: $DIR/issue-78675-captured-inner-attrs.rs:28:9: 28:16 (#0),
|
span: $DIR/issue-78675-captured-inner-attrs.rs:28:9: 28:16 (#0),
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] { 1 +1; }
|
PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] { 1 +1; }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[rustc_dummy] { 1 + 1 ; }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
|
@ -7,6 +7,15 @@ PRINT-DERIVE INPUT (DISPLAY): struct Foo
|
|||||||
{ #![allow(unused)] 30 } ; 0
|
{ #![allow(unused)] 30 } ; 0
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): struct Foo
|
||||||
|
{
|
||||||
|
val :
|
||||||
|
[bool ;
|
||||||
|
{
|
||||||
|
let a = #[rustc_dummy(first)] #[rustc_dummy(second)]
|
||||||
|
{ #! [allow(unused)] 30 } ; 0
|
||||||
|
}]
|
||||||
|
}
|
||||||
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
@ -111,7 +120,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
|||||||
stream: TokenStream [
|
stream: TokenStream [
|
||||||
Punct {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
spacing: Alone,
|
spacing: Joint,
|
||||||
span: $DIR/macro-rules-derive-cfg.rs:27:5: 27:6 (#0),
|
span: $DIR/macro-rules-derive-cfg.rs:27:5: 27:6 (#0),
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
PRINT-DERIVE INPUT (DISPLAY): struct Foo
|
PRINT-DERIVE INPUT (DISPLAY): struct Foo
|
||||||
{ my_array: [bool; { struct Inner { non_removed_inner_field: usize } 0 }] }
|
{ my_array: [bool; { struct Inner { non_removed_inner_field: usize } 0 }] }
|
||||||
|
PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): struct Foo
|
||||||
|
{ my_array : [bool ; { struct Inner { non_removed_inner_field : usize } 0 }] }
|
||||||
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
PRINT-ATTR_ARGS INPUT (DISPLAY): a, line!(), b
|
PRINT-ATTR_ARGS INPUT (DISPLAY): a, line!(), b
|
||||||
PRINT-ATTR_ARGS RE-COLLECTED (DISPLAY): a, line! (), b
|
PRINT-ATTR_ARGS DEEP-RE-COLLECTED (DISPLAY): a, line! (), b
|
||||||
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "a",
|
ident: "a",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
PRINT-BANG INPUT (DISPLAY): struct S;
|
PRINT-BANG INPUT (DISPLAY): struct S;
|
||||||
PRINT-BANG RE-COLLECTED (DISPLAY): struct S ;
|
PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): struct S ;
|
||||||
PRINT-BANG INPUT (DEBUG): TokenStream [
|
PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
Group {
|
Group {
|
||||||
delimiter: None,
|
delimiter: None,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PRINT-BANG INPUT (DISPLAY): { #![rustc_dummy] let a = "hello".len() ; matches!(a, 5) ; }
|
PRINT-BANG INPUT (DISPLAY): { #![rustc_dummy] let a = "hello".len() ; matches!(a, 5) ; }
|
||||||
|
PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): { #! [rustc_dummy] let a = "hello".len() ; matches! (a, 5) ; }
|
||||||
PRINT-BANG INPUT (DEBUG): TokenStream [
|
PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
Group {
|
Group {
|
||||||
delimiter: Brace,
|
delimiter: Brace,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PRINT-ATTR INPUT (DISPLAY): fn foo<T>() where T: Copy + {}
|
PRINT-ATTR INPUT (DISPLAY): fn foo<T>() where T: Copy + {}
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): fn foo < T > () where T : Copy + {}
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "fn",
|
ident: "fn",
|
||||||
|
@ -5,7 +5,18 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
span: $DIR/weird-braces.rs:16:25: 16:36 (#0),
|
span: $DIR/weird-braces.rs:16:25: 16:36 (#0),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second_outer)] impl Bar < { 1 > 0 } > for Foo <
|
PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second_outer)] impl Bar<{ 1 > 0 } > for Foo<{ true } >
|
||||||
|
{
|
||||||
|
#![print_target_and_args(first_inner)]
|
||||||
|
#![print_target_and_args(second_inner)]
|
||||||
|
}
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): #[print_target_and_args(second_outer)] impl Bar < { 1 > 0 } > for Foo <
|
||||||
|
{ true } >
|
||||||
|
{
|
||||||
|
#![print_target_and_args(first_inner)]
|
||||||
|
#![print_target_and_args(second_inner)]
|
||||||
|
}
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[print_target_and_args(second_outer)] impl Bar < { 1 > 0 } > for Foo <
|
||||||
{ true } >
|
{ true } >
|
||||||
{
|
{
|
||||||
#! [print_target_and_args(first_inner)] #!
|
#! [print_target_and_args(first_inner)] #!
|
||||||
@ -181,6 +192,16 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 } > for Foo<{ true } >
|
PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 } > for Foo<{ true } >
|
||||||
|
{
|
||||||
|
#![print_target_and_args(first_inner)]
|
||||||
|
#![print_target_and_args(second_inner)]
|
||||||
|
}
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } >
|
||||||
|
{
|
||||||
|
#![print_target_and_args(first_inner)]
|
||||||
|
#![print_target_and_args(second_inner)]
|
||||||
|
}
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } >
|
||||||
{
|
{
|
||||||
#! [print_target_and_args(first_inner)] #!
|
#! [print_target_and_args(first_inner)] #!
|
||||||
[print_target_and_args(second_inner)]
|
[print_target_and_args(second_inner)]
|
||||||
@ -331,6 +352,10 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 } > for Foo<{ true } >
|
PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 } > for Foo<{ true } >
|
||||||
{ #![print_target_and_args(second_inner)] }
|
{ #![print_target_and_args(second_inner)] }
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } >
|
||||||
|
{ #![print_target_and_args(second_inner)] }
|
||||||
|
PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } >
|
||||||
|
{ #! [print_target_and_args(second_inner)] }
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "impl",
|
ident: "impl",
|
||||||
@ -446,6 +471,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 } > for Foo<{ true } > {}
|
PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 } > for Foo<{ true } > {}
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } > {}
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "impl",
|
ident: "impl",
|
||||||
|
@ -29,15 +29,14 @@ checker!(attr_inherent_issue_64682, "fn inherent5(#[a1] #[a2] arg1 : u8, #[a3] a
|
|||||||
checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1: u8) ;");
|
checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1: u8) ;");
|
||||||
checker!(attr_trait_2, "fn trait2(#[a1] &self, #[a2] arg1: u8) ;");
|
checker!(attr_trait_2, "fn trait2(#[a1] &self, #[a2] arg1: u8) ;");
|
||||||
checker!(attr_trait_3, "fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) ;");
|
checker!(attr_trait_3, "fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) ;");
|
||||||
checker!(attr_trait_4, r#"fn trait4 < 'a >
|
checker!(attr_trait_4, r#"fn trait4<'a>(#[a1] self: Box<Self>, #[a2] arg1: u8, #[a3] Vec<u8>) ;"#);
|
||||||
(#[a1] self : Box < Self >, #[a2] arg1 : u8, #[a3] Vec < u8 >) ;"#);
|
|
||||||
checker!(attr_trait_issue_64682, "fn trait5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8) ;");
|
checker!(attr_trait_issue_64682, "fn trait5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8) ;");
|
||||||
checker!(rename_params, r#"impl Foo
|
checker!(rename_params, r#"impl Foo
|
||||||
{
|
{
|
||||||
fn hello(#[angery(true)] a : i32, #[a2] b : i32, #[what = "how"] c : u32)
|
fn hello(#[angery(true)] a: i32, #[a2] b: i32, #[what = "how"] c: u32) {}
|
||||||
|
fn
|
||||||
|
hello2(#[a1] #[a2] a: i32, #[what = "how"] b: i32, #[angery(true)] c: u32)
|
||||||
{} fn
|
{} fn
|
||||||
hello2(#[a1] #[a2] a : i32, #[what = "how"] b : i32, #[angery(true)] c :
|
hello_self(#[a1] #[a2] &self, #[a1] #[a2] a: i32, #[what = "how"] b: i32,
|
||||||
u32) {} fn
|
#[angery(true)] c: u32) {}
|
||||||
hello_self(#[a1] #[a2] & self, #[a1] #[a2] a : i32, #[what = "how"] b :
|
|
||||||
i32, #[angery(true)] c : u32) {}
|
|
||||||
}"#);
|
}"#);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user