Split the stack in make_attr_token_stream.

It makes for shorter code, and fewer allocations.
This commit is contained in:
Nicholas Nethercote 2024-07-08 18:05:18 +10:00
parent b16201317e
commit a88c4d67d9

View File

@ -376,18 +376,19 @@ fn make_attr_token_stream(
open_delim_sp: Option<(Delimiter, Span, Spacing)>, open_delim_sp: Option<(Delimiter, Span, Spacing)>,
inner: Vec<AttrTokenTree>, inner: Vec<AttrTokenTree>,
} }
let mut stack = vec![FrameData { open_delim_sp: None, inner: vec![] }]; // The stack always has at least one element. Storing it separately makes for shorter code.
let mut stack_top = FrameData { open_delim_sp: None, inner: vec![] };
let mut stack_rest = vec![];
for (token, spacing) in iter { for (token, spacing) in iter {
match token { match token {
FlatToken::Token(Token { kind: TokenKind::OpenDelim(delim), span }) => { FlatToken::Token(Token { kind: TokenKind::OpenDelim(delim), span }) => {
stack stack_rest.push(mem::replace(
.push(FrameData { open_delim_sp: Some((delim, span, spacing)), inner: vec![] }); &mut stack_top,
FrameData { open_delim_sp: Some((delim, span, spacing)), inner: vec![] },
));
} }
FlatToken::Token(Token { kind: TokenKind::CloseDelim(delim), span }) => { FlatToken::Token(Token { kind: TokenKind::CloseDelim(delim), span }) => {
let frame_data = stack let frame_data = mem::replace(&mut stack_top, stack_rest.pop().unwrap());
.pop()
.unwrap_or_else(|| panic!("Token stack was empty for token: {token:?}"));
let (open_delim, open_sp, open_spacing) = frame_data.open_delim_sp.unwrap(); let (open_delim, open_sp, open_spacing) = frame_data.open_delim_sp.unwrap();
assert_eq!( assert_eq!(
open_delim, delim, open_delim, delim,
@ -397,28 +398,18 @@ fn make_attr_token_stream(
let dspacing = DelimSpacing::new(open_spacing, spacing); let dspacing = DelimSpacing::new(open_spacing, spacing);
let stream = AttrTokenStream::new(frame_data.inner); let stream = AttrTokenStream::new(frame_data.inner);
let delimited = AttrTokenTree::Delimited(dspan, dspacing, delim, stream); let delimited = AttrTokenTree::Delimited(dspan, dspacing, delim, stream);
stack stack_top.inner.push(delimited);
.last_mut() }
.unwrap_or_else(|| panic!("Bottom token frame is missing for token: {token:?}")) FlatToken::Token(token) => stack_top.inner.push(AttrTokenTree::Token(token, spacing)),
.inner FlatToken::AttrsTarget(target) => {
.push(delimited); stack_top.inner.push(AttrTokenTree::AttrsTarget(target))
} }
FlatToken::Token(token) => stack
.last_mut()
.expect("Bottom token frame is missing!")
.inner
.push(AttrTokenTree::Token(token, spacing)),
FlatToken::AttrsTarget(target) => stack
.last_mut()
.expect("Bottom token frame is missing!")
.inner
.push(AttrTokenTree::AttrsTarget(target)),
FlatToken::Empty => {} FlatToken::Empty => {}
} }
} }
let mut final_buf = stack.pop().expect("Missing final buf!");
if break_last_token { if break_last_token {
let last_token = final_buf.inner.pop().unwrap(); let last_token = stack_top.inner.pop().unwrap();
if let AttrTokenTree::Token(last_token, spacing) = last_token { if let AttrTokenTree::Token(last_token, spacing) = last_token {
let unglued_first = last_token.kind.break_two_token_op().unwrap().0; let unglued_first = last_token.kind.break_two_token_op().unwrap().0;
@ -426,14 +417,14 @@ fn make_attr_token_stream(
let mut first_span = last_token.span.shrink_to_lo(); let mut first_span = last_token.span.shrink_to_lo();
first_span = first_span.with_hi(first_span.lo() + rustc_span::BytePos(1)); first_span = first_span.with_hi(first_span.lo() + rustc_span::BytePos(1));
final_buf stack_top
.inner .inner
.push(AttrTokenTree::Token(Token::new(unglued_first, first_span), spacing)); .push(AttrTokenTree::Token(Token::new(unglued_first, first_span), spacing));
} else { } else {
panic!("Unexpected last token {last_token:?}") panic!("Unexpected last token {last_token:?}")
} }
} }
AttrTokenStream::new(final_buf.inner) AttrTokenStream::new(stack_top.inner)
} }
// Some types are used a lot. Make sure they don't unintentionally get bigger. // Some types are used a lot. Make sure they don't unintentionally get bigger.