Skip to content

Commit 80045d6

Browse files
authored
Rollup merge of #96421 - nnethercote:less-NoDelim, r=petrochenkov
Less `NoDelim` Currently there are several places where `NoDelim` (which really means "implicit delimiter" or "invisible delimiter") is used to mean "no delimiter". The name `NoDelim` is a bit misleading, and may be a cause. This PR changes these places, e.g. by changing a `DelimToken` to `Option<DelimToken>` and then using `None` to mean "no delimiter". As a result, the *only* place where `NoDelim` values are now produced is within: - `Delimiter::to_internal()`, when converting from `Delimiter::None`. - `FlattenNonterminals::process_token()`, when converting `TokenKind::Interpolated`. r? ````@petrochenkov````
2 parents c4dd0d3 + 86f0117 commit 80045d6

File tree

10 files changed

+86
-84
lines changed

10 files changed

+86
-84
lines changed

compiler/rustc_ast/src/ast.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1542,10 +1542,10 @@ pub enum MacArgs {
15421542
}
15431543

15441544
impl MacArgs {
1545-
pub fn delim(&self) -> DelimToken {
1545+
pub fn delim(&self) -> Option<DelimToken> {
15461546
match self {
1547-
MacArgs::Delimited(_, delim, _) => delim.to_token(),
1548-
MacArgs::Empty | MacArgs::Eq(..) => token::NoDelim,
1547+
MacArgs::Delimited(_, delim, _) => Some(delim.to_token()),
1548+
MacArgs::Empty | MacArgs::Eq(..) => None,
15491549
}
15501550
}
15511551

compiler/rustc_ast_pretty/src/pprust/state.rs

+20-18
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
464464
Some(MacHeader::Path(&item.path)),
465465
false,
466466
None,
467-
delim.to_token(),
467+
Some(delim.to_token()),
468468
tokens,
469469
true,
470470
span,
@@ -530,7 +530,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
530530
None,
531531
false,
532532
None,
533-
*delim,
533+
Some(*delim),
534534
tts,
535535
convert_dollar_crate,
536536
dspan.entire(),
@@ -556,12 +556,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
556556
header: Option<MacHeader<'_>>,
557557
has_bang: bool,
558558
ident: Option<Ident>,
559-
delim: DelimToken,
559+
delim: Option<DelimToken>,
560560
tts: &TokenStream,
561561
convert_dollar_crate: bool,
562562
span: Span,
563563
) {
564-
if delim == DelimToken::Brace {
564+
if delim == Some(DelimToken::Brace) {
565565
self.cbox(INDENT_UNIT);
566566
}
567567
match header {
@@ -577,31 +577,33 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
577577
self.print_ident(ident);
578578
}
579579
match delim {
580-
DelimToken::Brace => {
580+
Some(DelimToken::Brace) => {
581581
if header.is_some() || has_bang || ident.is_some() {
582582
self.nbsp();
583583
}
584584
self.word("{");
585585
if !tts.is_empty() {
586586
self.space();
587587
}
588-
}
589-
_ => {
590-
let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
591-
self.word(token_str)
592-
}
593-
}
594-
self.ibox(0);
595-
self.print_tts(tts, convert_dollar_crate);
596-
self.end();
597-
match delim {
598-
DelimToken::Brace => {
588+
self.ibox(0);
589+
self.print_tts(tts, convert_dollar_crate);
590+
self.end();
599591
let empty = tts.is_empty();
600592
self.bclose(span, empty);
601593
}
602-
_ => {
594+
Some(delim) => {
595+
let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
596+
self.word(token_str);
597+
self.ibox(0);
598+
self.print_tts(tts, convert_dollar_crate);
599+
self.end();
603600
let token_str = self.token_kind_to_string(&token::CloseDelim(delim));
604-
self.word(token_str)
601+
self.word(token_str);
602+
}
603+
None => {
604+
self.ibox(0);
605+
self.print_tts(tts, convert_dollar_crate);
606+
self.end();
605607
}
606608
}
607609
}

compiler/rustc_expand/src/mbe/macro_rules.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -260,16 +260,15 @@ fn generic_extension<'cx, 'tt>(
260260
// Merge the gated spans from parsing the matcher with the pre-existing ones.
261261
sess.gated_spans.merge(gated_spans_snapshot);
262262

263-
// Ignore the delimiters on the RHS.
264-
let rhs = match &rhses[i] {
265-
mbe::TokenTree::Delimited(_, delimited) => &delimited.tts,
263+
let (rhs, rhs_span): (&mbe::Delimited, DelimSpan) = match &rhses[i] {
264+
mbe::TokenTree::Delimited(span, delimited) => (&delimited, *span),
266265
_ => cx.span_bug(sp, "malformed macro rhs"),
267266
};
268267
let arm_span = rhses[i].span();
269268

270-
let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>();
269+
let rhs_spans = rhs.tts.iter().map(|t| t.span()).collect::<Vec<_>>();
271270
// rhs has holes ( `$id` and `$(...)` that need filled)
272-
let mut tts = match transcribe(cx, &named_matches, &rhs, transparency) {
271+
let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) {
273272
Ok(tts) => tts,
274273
Err(mut err) => {
275274
err.emit();

compiler/rustc_expand/src/mbe/transcribe.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ impl MutVisitor for Marker {
2929
enum Frame<'a> {
3030
Delimited {
3131
tts: &'a [mbe::TokenTree],
32-
delim_token: token::DelimToken,
3332
idx: usize,
33+
delim_token: token::DelimToken,
3434
span: DelimSpan,
3535
},
3636
Sequence {
@@ -42,8 +42,8 @@ enum Frame<'a> {
4242

4343
impl<'a> Frame<'a> {
4444
/// Construct a new frame around the delimited set of tokens.
45-
fn new(tts: &'a [mbe::TokenTree]) -> Frame<'a> {
46-
Frame::Delimited { tts, delim_token: token::NoDelim, idx: 0, span: DelimSpan::dummy() }
45+
fn new(src: &'a mbe::Delimited, span: DelimSpan) -> Frame<'a> {
46+
Frame::Delimited { tts: &src.tts, idx: 0, delim_token: src.delim, span }
4747
}
4848
}
4949

@@ -85,17 +85,18 @@ impl<'a> Iterator for Frame<'a> {
8585
pub(super) fn transcribe<'a>(
8686
cx: &ExtCtxt<'a>,
8787
interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
88-
src: &[mbe::TokenTree],
88+
src: &mbe::Delimited,
89+
src_span: DelimSpan,
8990
transparency: Transparency,
9091
) -> PResult<'a, TokenStream> {
9192
// Nothing for us to transcribe...
92-
if src.is_empty() {
93+
if src.tts.is_empty() {
9394
return Ok(TokenStream::default());
9495
}
9596

9697
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
9798
// we have yet to expand/are still expanding. We start the stack off with the whole RHS.
98-
let mut stack: SmallVec<[Frame<'_>; 1]> = smallvec![Frame::new(&src)];
99+
let mut stack: SmallVec<[Frame<'_>; 1]> = smallvec![Frame::new(&src, src_span)];
99100

100101
// As we descend in the RHS, we will need to be able to match nested sequences of matchers.
101102
// `repeats` keeps track of where we are in matching at each level, with the last element being

compiler/rustc_parse/src/parser/attr_wrapper.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::tokenstream::{AttrAnnotatedTokenTree, DelimSpan, LazyTokenStream,
55
use rustc_ast::{self as ast};
66
use rustc_ast::{AstLike, AttrVec, Attribute};
77
use rustc_errors::PResult;
8-
use rustc_span::{sym, Span, DUMMY_SP};
8+
use rustc_span::{sym, Span};
99

1010
use std::convert::TryInto;
1111
use std::ops::Range;
@@ -400,24 +400,26 @@ fn make_token_stream(
400400
) -> AttrAnnotatedTokenStream {
401401
#[derive(Debug)]
402402
struct FrameData {
403-
open: Span,
404-
open_delim: DelimToken,
403+
// This is `None` for the first frame, `Some` for all others.
404+
open_delim_sp: Option<(DelimToken, Span)>,
405405
inner: Vec<(AttrAnnotatedTokenTree, Spacing)>,
406406
}
407-
let mut stack =
408-
vec![FrameData { open: DUMMY_SP, open_delim: DelimToken::NoDelim, inner: vec![] }];
407+
let mut stack = vec![FrameData { open_delim_sp: None, inner: vec![] }];
409408
let mut token_and_spacing = iter.next();
410409
while let Some((token, spacing)) = token_and_spacing {
411410
match token {
412411
FlatToken::Token(Token { kind: TokenKind::OpenDelim(delim), span }) => {
413-
stack.push(FrameData { open: span, open_delim: delim, inner: vec![] });
412+
stack.push(FrameData { open_delim_sp: Some((delim, span)), inner: vec![] });
414413
}
415414
FlatToken::Token(Token { kind: TokenKind::CloseDelim(delim), span }) => {
416415
// HACK: If we encounter a mismatched `None` delimiter at the top
417416
// level, just ignore it.
418417
if matches!(delim, DelimToken::NoDelim)
419418
&& (stack.len() == 1
420-
|| !matches!(stack.last_mut().unwrap().open_delim, DelimToken::NoDelim))
419+
|| !matches!(
420+
stack.last_mut().unwrap().open_delim_sp.unwrap().0,
421+
DelimToken::NoDelim
422+
))
421423
{
422424
token_and_spacing = iter.next();
423425
continue;
@@ -430,7 +432,7 @@ fn make_token_stream(
430432
// merge our current frame with the one above it. That is, transform
431433
// `[ { < first second } third ]` into `[ { first second } third ]`
432434
if !matches!(delim, DelimToken::NoDelim)
433-
&& matches!(frame_data.open_delim, DelimToken::NoDelim)
435+
&& matches!(frame_data.open_delim_sp.unwrap().0, DelimToken::NoDelim)
434436
{
435437
stack.last_mut().unwrap().inner.extend(frame_data.inner);
436438
// Process our closing delimiter again, this time at the previous
@@ -439,12 +441,13 @@ fn make_token_stream(
439441
continue;
440442
}
441443

444+
let (open_delim, open_sp) = frame_data.open_delim_sp.unwrap();
442445
assert_eq!(
443-
frame_data.open_delim, delim,
446+
open_delim, delim,
444447
"Mismatched open/close delims: open={:?} close={:?}",
445-
frame_data.open, span
448+
open_delim, span
446449
);
447-
let dspan = DelimSpan::from_pair(frame_data.open, span);
450+
let dspan = DelimSpan::from_pair(open_sp, span);
448451
let stream = AttrAnnotatedTokenStream::new(frame_data.inner);
449452
let delimited = AttrAnnotatedTokenTree::Delimited(dspan, delim, stream);
450453
stack
@@ -472,7 +475,7 @@ fn make_token_stream(
472475
// HACK: If we don't have a closing `None` delimiter for our last
473476
// frame, merge the frame with the top-level frame. That is,
474477
// turn `< first second` into `first second`
475-
if stack.len() == 2 && stack[1].open_delim == DelimToken::NoDelim {
478+
if stack.len() == 2 && stack[1].open_delim_sp.unwrap().0 == DelimToken::NoDelim {
476479
let temp_buf = stack.pop().unwrap();
477480
stack.last_mut().unwrap().inner.extend(temp_buf.inner);
478481
}

compiler/rustc_parse/src/parser/expr.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2043,7 +2043,8 @@ impl<'a> Parser<'a> {
20432043
self.sess.gated_spans.gate(sym::async_closure, span);
20442044
}
20452045

2046-
if self.token.kind == TokenKind::Semi && self.token_cursor.frame.delim == DelimToken::Paren
2046+
if self.token.kind == TokenKind::Semi
2047+
&& matches!(self.token_cursor.frame.delim_sp, Some((DelimToken::Paren, _)))
20472048
{
20482049
// It is likely that the closure body is a block but where the
20492050
// braces have been removed. We will recover and eat the next

compiler/rustc_parse/src/parser/mod.rs

+13-21
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,13 @@ struct TokenCursor {
244244

245245
#[derive(Clone)]
246246
struct TokenCursorFrame {
247-
delim: token::DelimToken,
248-
span: DelimSpan,
247+
delim_sp: Option<(DelimToken, DelimSpan)>,
249248
tree_cursor: tokenstream::Cursor,
250249
}
251250

252251
impl TokenCursorFrame {
253-
fn new(span: DelimSpan, delim: DelimToken, tts: TokenStream) -> Self {
254-
TokenCursorFrame { delim, span, tree_cursor: tts.into_trees() }
252+
fn new(delim_sp: Option<(DelimToken, DelimSpan)>, tts: TokenStream) -> Self {
253+
TokenCursorFrame { delim_sp, tree_cursor: tts.into_trees() }
255254
}
256255
}
257256

@@ -266,7 +265,7 @@ impl TokenCursor {
266265
loop {
267266
// FIXME: we currently don't return `NoDelim` open/close delims. To fix #67062 we will
268267
// need to, whereupon the `delim != DelimToken::NoDelim` conditions below can be
269-
// removed, as well as the loop.
268+
// removed.
270269
if let Some((tree, spacing)) = self.frame.tree_cursor.next_with_spacing_ref() {
271270
match tree {
272271
&TokenTree::Token(ref token) => match (desugar_doc_comments, token) {
@@ -277,7 +276,7 @@ impl TokenCursor {
277276
},
278277
&TokenTree::Delimited(sp, delim, ref tts) => {
279278
// Set `open_delim` to true here because we deal with it immediately.
280-
let frame = TokenCursorFrame::new(sp, delim, tts.clone());
279+
let frame = TokenCursorFrame::new(Some((delim, sp)), tts.clone());
281280
self.stack.push(mem::replace(&mut self.frame, frame));
282281
if delim != DelimToken::NoDelim {
283282
return (Token::new(token::OpenDelim(delim), sp.open), Spacing::Alone);
@@ -286,12 +285,11 @@ impl TokenCursor {
286285
}
287286
};
288287
} else if let Some(frame) = self.stack.pop() {
289-
let delim = self.frame.delim;
290-
let span = self.frame.span;
291-
self.frame = frame;
292-
if delim != DelimToken::NoDelim {
288+
if let Some((delim, span)) = self.frame.delim_sp && delim != DelimToken::NoDelim {
289+
self.frame = frame;
293290
return (Token::new(token::CloseDelim(delim), span.close), Spacing::Alone);
294291
}
292+
self.frame = frame;
295293
// No close delimiter to return; continue on to the next iteration.
296294
} else {
297295
return (Token::new(token::Eof, DUMMY_SP), Spacing::Alone);
@@ -330,8 +328,7 @@ impl TokenCursor {
330328
self.stack.push(mem::replace(
331329
&mut self.frame,
332330
TokenCursorFrame::new(
333-
delim_span,
334-
token::NoDelim,
331+
None,
335332
if attr_style == AttrStyle::Inner {
336333
[TokenTree::token(token::Pound, span), TokenTree::token(token::Not, span), body]
337334
.iter()
@@ -431,10 +428,6 @@ impl<'a> Parser<'a> {
431428
desugar_doc_comments: bool,
432429
subparser_name: Option<&'static str>,
433430
) -> Self {
434-
// Note: because of the way `TokenCursor::inlined_next` is structured, the `span` and
435-
// `delim` arguments here are never used.
436-
let start_frame = TokenCursorFrame::new(DelimSpan::dummy(), token::NoDelim, tokens);
437-
438431
let mut parser = Parser {
439432
sess,
440433
token: Token::dummy(),
@@ -444,7 +437,7 @@ impl<'a> Parser<'a> {
444437
restrictions: Restrictions::empty(),
445438
expected_tokens: Vec::new(),
446439
token_cursor: TokenCursor {
447-
frame: start_frame,
440+
frame: TokenCursorFrame::new(None, tokens),
448441
stack: Vec::new(),
449442
num_next_calls: 0,
450443
desugar_doc_comments,
@@ -1025,7 +1018,7 @@ impl<'a> Parser<'a> {
10251018
}
10261019

10271020
let frame = &self.token_cursor.frame;
1028-
if frame.delim != DelimToken::NoDelim {
1021+
if let Some((delim, span)) = frame.delim_sp && delim != DelimToken::NoDelim {
10291022
let all_normal = (0..dist).all(|i| {
10301023
let token = frame.tree_cursor.look_ahead(i);
10311024
!matches!(token, Some(TokenTree::Delimited(_, DelimToken::NoDelim, _)))
@@ -1038,7 +1031,7 @@ impl<'a> Parser<'a> {
10381031
looker(&Token::new(token::OpenDelim(*delim), dspan.open))
10391032
}
10401033
},
1041-
None => looker(&Token::new(token::CloseDelim(frame.delim), frame.span.close)),
1034+
None => looker(&Token::new(token::CloseDelim(delim), span.close)),
10421035
};
10431036
}
10441037
}
@@ -1198,8 +1191,7 @@ impl<'a> Parser<'a> {
11981191
// Grab the tokens from this frame.
11991192
let frame = &self.token_cursor.frame;
12001193
let stream = frame.tree_cursor.stream.clone();
1201-
let span = frame.span;
1202-
let delim = frame.delim;
1194+
let (delim, span) = frame.delim_sp.unwrap();
12031195

12041196
// Advance the token cursor through the entire delimited
12051197
// sequence. After getting the `OpenDelim` we are *within* the

0 commit comments

Comments
 (0)