Skip to content

Commit a88c4d6

Browse files
committed
Split the stack in make_attr_token_stream.
It makes for shorter code, and fewer allocations.
1 parent b162013 commit a88c4d6

File tree

1 file changed

+17
-26
lines changed

1 file changed

+17
-26
lines changed

compiler/rustc_parse/src/parser/attr_wrapper.rs

+17-26
Original file line numberDiff line numberDiff line change
@@ -376,18 +376,19 @@ fn make_attr_token_stream(
376376
open_delim_sp: Option<(Delimiter, Span, Spacing)>,
377377
inner: Vec<AttrTokenTree>,
378378
}
379-
let mut stack = vec![FrameData { open_delim_sp: None, inner: vec![] }];
379+
// The stack always has at least one element. Storing it separately makes for shorter code.
380+
let mut stack_top = FrameData { open_delim_sp: None, inner: vec![] };
381+
let mut stack_rest = vec![];
380382
for (token, spacing) in iter {
381383
match token {
382384
FlatToken::Token(Token { kind: TokenKind::OpenDelim(delim), span }) => {
383-
stack
384-
.push(FrameData { open_delim_sp: Some((delim, span, spacing)), inner: vec![] });
385+
stack_rest.push(mem::replace(
386+
&mut stack_top,
387+
FrameData { open_delim_sp: Some((delim, span, spacing)), inner: vec![] },
388+
));
385389
}
386390
FlatToken::Token(Token { kind: TokenKind::CloseDelim(delim), span }) => {
387-
let frame_data = stack
388-
.pop()
389-
.unwrap_or_else(|| panic!("Token stack was empty for token: {token:?}"));
390-
391+
let frame_data = mem::replace(&mut stack_top, stack_rest.pop().unwrap());
391392
let (open_delim, open_sp, open_spacing) = frame_data.open_delim_sp.unwrap();
392393
assert_eq!(
393394
open_delim, delim,
@@ -397,43 +398,33 @@ fn make_attr_token_stream(
397398
let dspacing = DelimSpacing::new(open_spacing, spacing);
398399
let stream = AttrTokenStream::new(frame_data.inner);
399400
let delimited = AttrTokenTree::Delimited(dspan, dspacing, delim, stream);
400-
stack
401-
.last_mut()
402-
.unwrap_or_else(|| panic!("Bottom token frame is missing for token: {token:?}"))
403-
.inner
404-
.push(delimited);
401+
stack_top.inner.push(delimited);
402+
}
403+
FlatToken::Token(token) => stack_top.inner.push(AttrTokenTree::Token(token, spacing)),
404+
FlatToken::AttrsTarget(target) => {
405+
stack_top.inner.push(AttrTokenTree::AttrsTarget(target))
405406
}
406-
FlatToken::Token(token) => stack
407-
.last_mut()
408-
.expect("Bottom token frame is missing!")
409-
.inner
410-
.push(AttrTokenTree::Token(token, spacing)),
411-
FlatToken::AttrsTarget(target) => stack
412-
.last_mut()
413-
.expect("Bottom token frame is missing!")
414-
.inner
415-
.push(AttrTokenTree::AttrsTarget(target)),
416407
FlatToken::Empty => {}
417408
}
418409
}
419-
let mut final_buf = stack.pop().expect("Missing final buf!");
410+
420411
if break_last_token {
421-
let last_token = final_buf.inner.pop().unwrap();
412+
let last_token = stack_top.inner.pop().unwrap();
422413
if let AttrTokenTree::Token(last_token, spacing) = last_token {
423414
let unglued_first = last_token.kind.break_two_token_op().unwrap().0;
424415

425416
// An 'unglued' token is always two ASCII characters
426417
let mut first_span = last_token.span.shrink_to_lo();
427418
first_span = first_span.with_hi(first_span.lo() + rustc_span::BytePos(1));
428419

429-
final_buf
420+
stack_top
430421
.inner
431422
.push(AttrTokenTree::Token(Token::new(unglued_first, first_span), spacing));
432423
} else {
433424
panic!("Unexpected last token {last_token:?}")
434425
}
435426
}
436-
AttrTokenStream::new(final_buf.inner)
427+
AttrTokenStream::new(stack_top.inner)
437428
}
438429

439430
// Some types are used a lot. Make sure they don't unintentionally get bigger.

0 commit comments

Comments
 (0)