Skip to content

Commit

Permalink
Add spacing information to delimiters.
Browse files Browse the repository at this point in the history
This is an extension of the previous commit. It means the output of
something like this:
```
stringify!(let a: Vec<u32> = vec![];)
```
goes from this:
```
let a: Vec<u32> = vec![] ;
```
With this PR, it now produces this string:
```
let a: Vec<u32> = vec![];
```
  • Loading branch information
nnethercote committed Dec 10, 2023
1 parent 925f7fa commit 4cfdbd3
Show file tree
Hide file tree
Showing 47 changed files with 307 additions and 231 deletions.
6 changes: 3 additions & 3 deletions compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ impl MetaItemKind {
tokens: &mut impl Iterator<Item = &'a TokenTree>,
) -> Option<MetaItemKind> {
match tokens.next() {
Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => {
Some(TokenTree::Delimited(.., Delimiter::Invisible, inner_tokens)) => {
MetaItemKind::name_value_from_tokens(&mut inner_tokens.trees())
}
Some(TokenTree::Token(token, _)) => {
Expand All @@ -401,7 +401,7 @@ impl MetaItemKind {
tokens: &mut iter::Peekable<impl Iterator<Item = &'a TokenTree>>,
) -> Option<MetaItemKind> {
match tokens.peek() {
Some(TokenTree::Delimited(_, Delimiter::Parenthesis, inner_tokens)) => {
Some(TokenTree::Delimited(.., Delimiter::Parenthesis, inner_tokens)) => {
let inner_tokens = inner_tokens.clone();
tokens.next();
MetaItemKind::list_from_tokens(inner_tokens).map(MetaItemKind::List)
Expand Down Expand Up @@ -524,7 +524,7 @@ impl NestedMetaItem {
tokens.next();
return Some(NestedMetaItem::Lit(lit));
}
Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => {
Some(TokenTree::Delimited(.., Delimiter::Invisible, inner_tokens)) => {
tokens.next();
return NestedMetaItem::from_tokens(&mut inner_tokens.trees().peekable());
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ pub fn visit_attr_tt<T: MutVisitor>(tt: &mut AttrTokenTree, vis: &mut T) {
AttrTokenTree::Token(token, _) => {
visit_token(token, vis);
}
AttrTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => {
AttrTokenTree::Delimited(DelimSpan { open, close }, _spacing, _delim, tts) => {
vis.visit_span(open);
vis.visit_span(close);
visit_attr_tts(tts, vis);
Expand All @@ -709,7 +709,7 @@ pub fn visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {
TokenTree::Token(token, _) => {
visit_token(token, vis);
}
TokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => {
TokenTree::Delimited(DelimSpan { open, close }, _spacing, _delim, tts) => {
vis.visit_span(open);
vis.visit_span(close);
visit_tts(tts, vis);
Expand Down
55 changes: 35 additions & 20 deletions compiler/rustc_ast/src/tokenstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub enum TokenTree {
/// delimiters are implicitly represented by `Delimited`.
Token(Token, Spacing),
/// A delimited sequence of token trees.
Delimited(DelimSpan, Delimiter, TokenStream),
Delimited(DelimSpan, DelimSpacing, Delimiter, TokenStream),
}

// Ensure all fields of `TokenTree` are `DynSend` and `DynSync`.
Expand All @@ -62,11 +62,11 @@ where
}

impl TokenTree {
/// Checks if this `TokenTree` is equal to the other, regardless of span information.
/// Checks if this `TokenTree` is equal to the other, regardless of span/spacing information.
pub fn eq_unspanned(&self, other: &TokenTree) -> bool {
match (self, other) {
(TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind,
(TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
(TokenTree::Delimited(.., delim, tts), TokenTree::Delimited(.., delim2, tts2)) => {
delim == delim2 && tts.eq_unspanned(tts2)
}
_ => false,
Expand Down Expand Up @@ -188,7 +188,7 @@ pub struct AttrTokenStream(pub Lrc<Vec<AttrTokenTree>>);
#[derive(Clone, Debug, Encodable, Decodable)]
pub enum AttrTokenTree {
Token(Token, Spacing),
Delimited(DelimSpan, Delimiter, AttrTokenStream),
Delimited(DelimSpan, DelimSpacing, Delimiter, AttrTokenStream),
/// Stores the attributes for an attribute target,
/// along with the tokens for that attribute target.
/// See `AttributesData` for more information
Expand All @@ -213,9 +213,14 @@ impl AttrTokenStream {
AttrTokenTree::Token(inner, spacing) => {
smallvec![TokenTree::Token(inner.clone(), *spacing)].into_iter()
}
AttrTokenTree::Delimited(span, delim, stream) => {
smallvec![TokenTree::Delimited(*span, *delim, stream.to_tokenstream()),]
.into_iter()
AttrTokenTree::Delimited(span, spacing, delim, stream) => {
smallvec![TokenTree::Delimited(
*span,
*spacing,
*delim,
stream.to_tokenstream()
),]
.into_iter()
}
AttrTokenTree::Attributes(data) => {
let idx = data
Expand All @@ -235,7 +240,7 @@ impl AttrTokenStream {
let mut found = false;
// Check the last two trees (to account for a trailing semi)
for tree in target_tokens.iter_mut().rev().take(2) {
if let TokenTree::Delimited(span, delim, delim_tokens) = tree {
if let TokenTree::Delimited(span, spacing, delim, delim_tokens) = tree {
// Inner attributes are only supported on extern blocks, functions,
// impls, and modules. All of these have their inner attributes
// placed at the beginning of the rightmost outermost braced group:
Expand All @@ -255,7 +260,7 @@ impl AttrTokenStream {
stream.push_stream(inner_attr.tokens());
}
stream.push_stream(delim_tokens.clone());
*tree = TokenTree::Delimited(*span, *delim, stream);
*tree = TokenTree::Delimited(*span, *spacing, *delim, stream);
found = true;
break;
}
Expand Down Expand Up @@ -477,11 +482,6 @@ impl TokenStream {
TokenStream::new(vec![TokenTree::token_alone(kind, span)])
}

/// Create a token stream containing a single `Delimited`.
pub fn delimited(span: DelimSpan, delim: Delimiter, tts: TokenStream) -> TokenStream {
TokenStream::new(vec![TokenTree::Delimited(span, delim, tts)])
}

pub fn from_ast(node: &(impl HasAttrs + HasSpan + HasTokens + fmt::Debug)) -> TokenStream {
let Some(tokens) = node.tokens() else {
panic!("missing tokens for node at {:?}: {:?}", node.span(), node);
Expand Down Expand Up @@ -528,6 +528,7 @@ impl TokenStream {
}
token::Interpolated(nt) => TokenTree::Delimited(
DelimSpan::from_single(token.span),
DelimSpacing::new(Spacing::JointHidden, spacing),
Delimiter::Invisible,
TokenStream::from_nonterminal_ast(&nt.0).flattened(),
),
Expand All @@ -538,8 +539,8 @@ impl TokenStream {
fn flatten_token_tree(tree: &TokenTree) -> TokenTree {
match tree {
TokenTree::Token(token, spacing) => TokenStream::flatten_token(token, *spacing),
TokenTree::Delimited(span, delim, tts) => {
TokenTree::Delimited(*span, *delim, tts.flattened())
TokenTree::Delimited(span, spacing, delim, tts) => {
TokenTree::Delimited(*span, *spacing, *delim, tts.flattened())
}
}
}
Expand All @@ -549,7 +550,7 @@ impl TokenStream {
fn can_skip(stream: &TokenStream) -> bool {
stream.trees().all(|tree| match tree {
TokenTree::Token(token, _) => !matches!(token.kind, token::Interpolated(_)),
TokenTree::Delimited(_, _, inner) => can_skip(inner),
TokenTree::Delimited(.., inner) => can_skip(inner),
})
}

Expand Down Expand Up @@ -638,9 +639,10 @@ impl TokenStream {

&TokenTree::Token(..) => i += 1,

&TokenTree::Delimited(sp, delim, ref delim_stream) => {
&TokenTree::Delimited(sp, spacing, delim, ref delim_stream) => {
if let Some(desugared_delim_stream) = desugar_inner(delim_stream.clone()) {
let new_tt = TokenTree::Delimited(sp, delim, desugared_delim_stream);
let new_tt =
TokenTree::Delimited(sp, spacing, delim, desugared_delim_stream);
Lrc::make_mut(&mut stream.0)[i] = new_tt;
modified = true;
}
Expand Down Expand Up @@ -668,10 +670,11 @@ impl TokenStream {
num_of_hashes = cmp::max(num_of_hashes, count);
}

// `/// foo` becomes `doc = r"foo"`.
// `/// foo` becomes `[doc = r"foo"]`.
let delim_span = DelimSpan::from_single(span);
let body = TokenTree::Delimited(
delim_span,
DelimSpacing::new(Spacing::JointHidden, Spacing::Alone),
Delimiter::Bracket,
[
TokenTree::token_alone(token::Ident(sym::doc, false), span),
Expand Down Expand Up @@ -784,6 +787,18 @@ impl DelimSpan {
}
}

#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
pub struct DelimSpacing {
pub open: Spacing,
pub close: Spacing,
}

impl DelimSpacing {
pub fn new(open: Spacing, close: Spacing) -> DelimSpacing {
DelimSpacing { open, close }
}
}

// Some types are used a lot. Make sure they don't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,10 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool {
//
// FIXME: Incorrect cases:
// - Let: `let(a, b) = (1, 2)`
(Tok(Token { kind: Ident(..), .. }, _), Del(_, Parenthesis, _)) => false,
(Tok(Token { kind: Ident(..), .. }, _), Del(_, _, Parenthesis, _)) => false,

// `#` + `[`: `#[attr]`
(Tok(Token { kind: Pound, .. }, _), Del(_, Bracket, _)) => false,
(Tok(Token { kind: Pound, .. }, _), Del(_, _, Bracket, _)) => false,

_ => true,
}
Expand Down Expand Up @@ -519,7 +519,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
}
*spacing
}
TokenTree::Delimited(dspan, delim, tts) => {
TokenTree::Delimited(dspan, spacing, delim, tts) => {
self.print_mac_common(
None,
false,
Expand All @@ -529,9 +529,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
convert_dollar_crate,
dspan.entire(),
);
// FIXME: add two `Spacing` fields to `TokenTree::Delimited`
// and use the close delim one here.
Spacing::Alone
spacing.close
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_expand/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use crate::errors::{
};
use rustc_ast::ptr::P;
use rustc_ast::token::{Delimiter, Token, TokenKind};
use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree};
use rustc_ast::tokenstream::{DelimSpan, Spacing};
use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree, DelimSpacing, DelimSpan, Spacing};
use rustc_ast::tokenstream::{LazyAttrTokenStream, TokenTree};
use rustc_ast::NodeId;
use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem};
Expand Down Expand Up @@ -242,7 +241,7 @@ impl<'a> StripUnconfigured<'a> {
stream.0.iter().all(|tree| match tree {
AttrTokenTree::Attributes(_) => false,
AttrTokenTree::Token(..) => true,
AttrTokenTree::Delimited(_, _, inner) => can_skip(inner),
AttrTokenTree::Delimited(.., inner) => can_skip(inner),
})
}

Expand All @@ -266,9 +265,9 @@ impl<'a> StripUnconfigured<'a> {
None.into_iter()
}
}
AttrTokenTree::Delimited(sp, delim, mut inner) => {
AttrTokenTree::Delimited(sp, spacing, delim, mut inner) => {
inner = self.configure_tokens(&inner);
Some(AttrTokenTree::Delimited(sp, delim, inner)).into_iter()
Some(AttrTokenTree::Delimited(sp, spacing, delim, inner)).into_iter()
}
AttrTokenTree::Token(ref token, _)
if let TokenKind::Interpolated(nt) = &token.kind =>
Expand Down Expand Up @@ -376,6 +375,7 @@ impl<'a> StripUnconfigured<'a> {
// in `#[attr]`, so just use the span of the `#` token.
let bracket_group = AttrTokenTree::Delimited(
DelimSpan::from_single(pound_span),
DelimSpacing::new(Spacing::JointHidden, Spacing::Alone),
Delimiter::Bracket,
item.tokens
.as_ref()
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_expand/src/mbe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub(crate) mod transcribe;

use metavar_expr::MetaVarExpr;
use rustc_ast::token::{Delimiter, NonterminalKind, Token, TokenKind};
use rustc_ast::tokenstream::DelimSpan;
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan};
use rustc_span::symbol::Ident;
use rustc_span::Span;

Expand Down Expand Up @@ -68,7 +68,7 @@ pub(crate) enum KleeneOp {
enum TokenTree {
Token(Token),
/// A delimited sequence, e.g. `($e:expr)` (RHS) or `{ $e }` (LHS).
Delimited(DelimSpan, Delimited),
Delimited(DelimSpan, DelimSpacing, Delimited),
/// A kleene-style repetition sequence, e.g. `$($e:expr)*` (RHS) or `$($e),*` (LHS).
Sequence(DelimSpan, SequenceRepetition),
/// e.g., `$var`.
Expand Down Expand Up @@ -99,7 +99,7 @@ impl TokenTree {
TokenTree::Token(Token { span, .. })
| TokenTree::MetaVar(span, _)
| TokenTree::MetaVarDecl(span, _, _) => span,
TokenTree::Delimited(span, _)
TokenTree::Delimited(span, ..)
| TokenTree::MetaVarExpr(span, _)
| TokenTree::Sequence(span, _) => span.entire(),
}
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_expand/src/mbe/macro_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ fn check_binders(
}
// `MetaVarExpr` can not appear in the LHS of a macro arm
TokenTree::MetaVarExpr(..) => {}
TokenTree::Delimited(_, ref del) => {
TokenTree::Delimited(.., ref del) => {
for tt in &del.tts {
check_binders(sess, node_id, tt, macros, binders, ops, valid);
}
Expand Down Expand Up @@ -353,7 +353,7 @@ fn check_occurrences(
};
check_ops_is_prefix(sess, node_id, macros, binders, ops, dl.entire(), name);
}
TokenTree::Delimited(_, ref del) => {
TokenTree::Delimited(.., ref del) => {
check_nested_occurrences(sess, node_id, &del.tts, macros, binders, ops, valid);
}
TokenTree::Sequence(_, ref seq) => {
Expand Down Expand Up @@ -435,8 +435,8 @@ fn check_nested_occurrences(
// We check that the meta-variable is correctly used.
check_occurrences(sess, node_id, tt, macros, binders, ops, valid);
}
(NestedMacroState::MacroRulesNotName, TokenTree::Delimited(_, del))
| (NestedMacroState::MacroName, TokenTree::Delimited(_, del))
(NestedMacroState::MacroRulesNotName, TokenTree::Delimited(.., del))
| (NestedMacroState::MacroName, TokenTree::Delimited(.., del))
if del.delim == Delimiter::Brace =>
{
let macro_rules = state == NestedMacroState::MacroRulesNotName;
Expand Down Expand Up @@ -466,7 +466,7 @@ fn check_nested_occurrences(
// We check that the meta-variable is correctly used.
check_occurrences(sess, node_id, tt, macros, binders, ops, valid);
}
(NestedMacroState::MacroName, TokenTree::Delimited(_, del))
(NestedMacroState::MacroName, TokenTree::Delimited(.., del))
if del.delim == Delimiter::Parenthesis =>
{
state = NestedMacroState::MacroNameParen;
Expand All @@ -481,7 +481,7 @@ fn check_nested_occurrences(
valid,
);
}
(NestedMacroState::MacroNameParen, TokenTree::Delimited(_, del))
(NestedMacroState::MacroNameParen, TokenTree::Delimited(.., del))
if del.delim == Delimiter::Brace =>
{
state = NestedMacroState::Empty;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/mbe/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ pub(super) fn compute_locs(matcher: &[TokenTree]) -> Vec<MatcherLoc> {
TokenTree::Token(token) => {
locs.push(MatcherLoc::Token { token: token.clone() });
}
TokenTree::Delimited(span, delimited) => {
TokenTree::Delimited(span, _, delimited) => {
let open_token = Token::new(token::OpenDelim(delimited.delim), span.open);
let close_token = Token::new(token::CloseDelim(delimited.delim), span.close);

Expand Down Expand Up @@ -335,7 +335,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
.map(|tt| match tt {
TokenTree::MetaVarDecl(..) => 1,
TokenTree::Sequence(_, seq) => seq.num_captures,
TokenTree::Delimited(_, delim) => count_metavar_decls(&delim.tts),
TokenTree::Delimited(.., delim) => count_metavar_decls(&delim.tts),
TokenTree::Token(..) => 0,
TokenTree::MetaVar(..) | TokenTree::MetaVarExpr(..) => unreachable!(),
})
Expand Down
Loading

0 comments on commit 4cfdbd3

Please sign in to comment.