Skip to content

Commit 9c6d84c

Browse files
committed
Auto merge of rust-lang#133793 - nnethercote:speed-up-expected_tokens, r=spastorino
Speed up `Parser::expected_tokens` The constant pushing/clearing of `Parser::expected_tokens` during parsing is slow. This PR speeds it up greatly. r? `@estebank`
2 parents 3bf62cc + 0f7dccf commit 9c6d84c

File tree

22 files changed

+1415
-844
lines changed

22 files changed

+1415
-844
lines changed

compiler/rustc_builtin_macros/src/asm.rs

+56-56
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
use ast::token::IdentIsRaw;
22
use lint::BuiltinLintDiag;
3-
use rustc_ast::AsmMacro;
43
use rustc_ast::ptr::P;
5-
use rustc_ast::token::{self, Delimiter};
64
use rustc_ast::tokenstream::TokenStream;
5+
use rustc_ast::{AsmMacro, token};
76
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
87
use rustc_errors::PResult;
98
use rustc_expand::base::*;
109
use rustc_index::bit_set::GrowableBitSet;
11-
use rustc_parse::parser::Parser;
10+
use rustc_parse::exp;
11+
use rustc_parse::parser::{ExpKeywordPair, Parser};
1212
use rustc_session::lint;
13-
use rustc_span::{ErrorGuaranteed, Ident, InnerSpan, Span, Symbol, kw, sym};
13+
use rustc_span::{ErrorGuaranteed, Ident, InnerSpan, Span, Symbol, kw};
1414
use rustc_target::asm::InlineAsmArch;
1515
use smallvec::smallvec;
1616
use {rustc_ast as ast, rustc_parse_format as parse};
@@ -38,16 +38,16 @@ pub struct AsmArgs {
3838
/// - `Err(_)` if the current token matches the keyword, but was not expected
3939
fn eat_operand_keyword<'a>(
4040
p: &mut Parser<'a>,
41-
symbol: Symbol,
41+
exp: ExpKeywordPair,
4242
asm_macro: AsmMacro,
4343
) -> PResult<'a, bool> {
4444
if matches!(asm_macro, AsmMacro::Asm) {
45-
Ok(p.eat_keyword(symbol))
45+
Ok(p.eat_keyword(exp))
4646
} else {
4747
let span = p.token.span;
48-
if p.eat_keyword_noexpect(symbol) {
48+
if p.eat_keyword_noexpect(exp.kw) {
4949
// in gets printed as `r#in` otherwise
50-
let symbol = if symbol == kw::In { "in" } else { symbol.as_str() };
50+
let symbol = if exp.kw == kw::In { "in" } else { exp.kw.as_str() };
5151
Err(p.dcx().create_err(errors::AsmUnsupportedOperand {
5252
span,
5353
symbol,
@@ -95,28 +95,28 @@ pub fn parse_asm_args<'a>(
9595

9696
let mut allow_templates = true;
9797
while p.token != token::Eof {
98-
if !p.eat(&token::Comma) {
98+
if !p.eat(exp!(Comma)) {
9999
if allow_templates {
100100
// After a template string, we always expect *only* a comma...
101101
return Err(dcx.create_err(errors::AsmExpectedComma { span: p.token.span }));
102102
} else {
103103
// ...after that delegate to `expect` to also include the other expected tokens.
104-
return Err(p.expect(&token::Comma).err().unwrap());
104+
return Err(p.expect(exp!(Comma)).err().unwrap());
105105
}
106106
}
107107
if p.token == token::Eof {
108108
break;
109109
} // accept trailing commas
110110

111111
// Parse clobber_abi
112-
if p.eat_keyword(sym::clobber_abi) {
112+
if p.eat_keyword(exp!(ClobberAbi)) {
113113
parse_clobber_abi(p, &mut args)?;
114114
allow_templates = false;
115115
continue;
116116
}
117117

118118
// Parse options
119-
if p.eat_keyword(sym::options) {
119+
if p.eat_keyword(exp!(Options)) {
120120
parse_options(p, &mut args, asm_macro)?;
121121
allow_templates = false;
122122
continue;
@@ -128,65 +128,65 @@ pub fn parse_asm_args<'a>(
128128
let name = if p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq) {
129129
let (ident, _) = p.token.ident().unwrap();
130130
p.bump();
131-
p.expect(&token::Eq)?;
131+
p.expect(exp!(Eq))?;
132132
allow_templates = false;
133133
Some(ident.name)
134134
} else {
135135
None
136136
};
137137

138138
let mut explicit_reg = false;
139-
let op = if eat_operand_keyword(p, kw::In, asm_macro)? {
139+
let op = if eat_operand_keyword(p, exp!(In), asm_macro)? {
140140
let reg = parse_reg(p, &mut explicit_reg)?;
141-
if p.eat_keyword(kw::Underscore) {
141+
if p.eat_keyword(exp!(Underscore)) {
142142
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
143143
return Err(err);
144144
}
145145
let expr = p.parse_expr()?;
146146
ast::InlineAsmOperand::In { reg, expr }
147-
} else if eat_operand_keyword(p, sym::out, asm_macro)? {
147+
} else if eat_operand_keyword(p, exp!(Out), asm_macro)? {
148148
let reg = parse_reg(p, &mut explicit_reg)?;
149-
let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
149+
let expr = if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
150150
ast::InlineAsmOperand::Out { reg, expr, late: false }
151-
} else if eat_operand_keyword(p, sym::lateout, asm_macro)? {
151+
} else if eat_operand_keyword(p, exp!(Lateout), asm_macro)? {
152152
let reg = parse_reg(p, &mut explicit_reg)?;
153-
let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
153+
let expr = if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
154154
ast::InlineAsmOperand::Out { reg, expr, late: true }
155-
} else if eat_operand_keyword(p, sym::inout, asm_macro)? {
155+
} else if eat_operand_keyword(p, exp!(Inout), asm_macro)? {
156156
let reg = parse_reg(p, &mut explicit_reg)?;
157-
if p.eat_keyword(kw::Underscore) {
157+
if p.eat_keyword(exp!(Underscore)) {
158158
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
159159
return Err(err);
160160
}
161161
let expr = p.parse_expr()?;
162-
if p.eat(&token::FatArrow) {
162+
if p.eat(exp!(FatArrow)) {
163163
let out_expr =
164-
if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
164+
if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
165165
ast::InlineAsmOperand::SplitInOut { reg, in_expr: expr, out_expr, late: false }
166166
} else {
167167
ast::InlineAsmOperand::InOut { reg, expr, late: false }
168168
}
169-
} else if eat_operand_keyword(p, sym::inlateout, asm_macro)? {
169+
} else if eat_operand_keyword(p, exp!(Inlateout), asm_macro)? {
170170
let reg = parse_reg(p, &mut explicit_reg)?;
171-
if p.eat_keyword(kw::Underscore) {
171+
if p.eat_keyword(exp!(Underscore)) {
172172
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
173173
return Err(err);
174174
}
175175
let expr = p.parse_expr()?;
176-
if p.eat(&token::FatArrow) {
176+
if p.eat(exp!(FatArrow)) {
177177
let out_expr =
178-
if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
178+
if p.eat_keyword(exp!(Underscore)) { None } else { Some(p.parse_expr()?) };
179179
ast::InlineAsmOperand::SplitInOut { reg, in_expr: expr, out_expr, late: true }
180180
} else {
181181
ast::InlineAsmOperand::InOut { reg, expr, late: true }
182182
}
183-
} else if eat_operand_keyword(p, sym::label, asm_macro)? {
183+
} else if eat_operand_keyword(p, exp!(Label), asm_macro)? {
184184
let block = p.parse_block()?;
185185
ast::InlineAsmOperand::Label { block }
186-
} else if p.eat_keyword(kw::Const) {
186+
} else if p.eat_keyword(exp!(Const)) {
187187
let anon_const = p.parse_expr_anon_const()?;
188188
ast::InlineAsmOperand::Const { anon_const }
189-
} else if p.eat_keyword(sym::sym) {
189+
} else if p.eat_keyword(exp!(Sym)) {
190190
let expr = p.parse_expr()?;
191191
let ast::ExprKind::Path(qself, path) = &expr.kind else {
192192
let err = dcx.create_err(errors::AsmSymNoPath { span: expr.span });
@@ -389,31 +389,31 @@ fn parse_options<'a>(
389389
) -> PResult<'a, ()> {
390390
let span_start = p.prev_token.span;
391391

392-
p.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
393-
394-
while !p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
395-
const OPTIONS: [(Symbol, ast::InlineAsmOptions); ast::InlineAsmOptions::COUNT] = [
396-
(sym::pure, ast::InlineAsmOptions::PURE),
397-
(sym::nomem, ast::InlineAsmOptions::NOMEM),
398-
(sym::readonly, ast::InlineAsmOptions::READONLY),
399-
(sym::preserves_flags, ast::InlineAsmOptions::PRESERVES_FLAGS),
400-
(sym::noreturn, ast::InlineAsmOptions::NORETURN),
401-
(sym::nostack, ast::InlineAsmOptions::NOSTACK),
402-
(sym::may_unwind, ast::InlineAsmOptions::MAY_UNWIND),
403-
(sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX),
404-
(kw::Raw, ast::InlineAsmOptions::RAW),
392+
p.expect(exp!(OpenParen))?;
393+
394+
while !p.eat(exp!(CloseParen)) {
395+
const OPTIONS: [(ExpKeywordPair, ast::InlineAsmOptions); ast::InlineAsmOptions::COUNT] = [
396+
(exp!(Pure), ast::InlineAsmOptions::PURE),
397+
(exp!(Nomem), ast::InlineAsmOptions::NOMEM),
398+
(exp!(Readonly), ast::InlineAsmOptions::READONLY),
399+
(exp!(PreservesFlags), ast::InlineAsmOptions::PRESERVES_FLAGS),
400+
(exp!(Noreturn), ast::InlineAsmOptions::NORETURN),
401+
(exp!(Nostack), ast::InlineAsmOptions::NOSTACK),
402+
(exp!(MayUnwind), ast::InlineAsmOptions::MAY_UNWIND),
403+
(exp!(AttSyntax), ast::InlineAsmOptions::ATT_SYNTAX),
404+
(exp!(Raw), ast::InlineAsmOptions::RAW),
405405
];
406406

407407
'blk: {
408-
for (symbol, option) in OPTIONS {
408+
for (exp, option) in OPTIONS {
409409
let kw_matched = if asm_macro.is_supported_option(option) {
410-
p.eat_keyword(symbol)
410+
p.eat_keyword(exp)
411411
} else {
412-
p.eat_keyword_noexpect(symbol)
412+
p.eat_keyword_noexpect(exp.kw)
413413
};
414414

415415
if kw_matched {
416-
try_set_option(p, args, asm_macro, symbol, option);
416+
try_set_option(p, args, asm_macro, exp.kw, option);
417417
break 'blk;
418418
}
419419
}
@@ -422,10 +422,10 @@ fn parse_options<'a>(
422422
}
423423

424424
// Allow trailing commas
425-
if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
425+
if p.eat(exp!(CloseParen)) {
426426
break;
427427
}
428-
p.expect(&token::Comma)?;
428+
p.expect(exp!(Comma))?;
429429
}
430430

431431
let new_span = span_start.to(p.prev_token.span);
@@ -437,14 +437,14 @@ fn parse_options<'a>(
437437
fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a, ()> {
438438
let span_start = p.prev_token.span;
439439

440-
p.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
440+
p.expect(exp!(OpenParen))?;
441441

442-
if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
442+
if p.eat(exp!(CloseParen)) {
443443
return Err(p.dcx().create_err(errors::NonABI { span: p.token.span }));
444444
}
445445

446446
let mut new_abis = Vec::new();
447-
while !p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
447+
while !p.eat(exp!(CloseParen)) {
448448
match p.parse_str_lit() {
449449
Ok(str_lit) => {
450450
new_abis.push((str_lit.symbol_unescaped, str_lit.span));
@@ -456,10 +456,10 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a,
456456
};
457457

458458
// Allow trailing commas
459-
if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
459+
if p.eat(exp!(CloseParen)) {
460460
break;
461461
}
462-
p.expect(&token::Comma)?;
462+
p.expect(exp!(Comma))?;
463463
}
464464

465465
let full_span = span_start.to(p.prev_token.span);
@@ -482,7 +482,7 @@ fn parse_reg<'a>(
482482
p: &mut Parser<'a>,
483483
explicit_reg: &mut bool,
484484
) -> PResult<'a, ast::InlineAsmRegOrRegClass> {
485-
p.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
485+
p.expect(exp!(OpenParen))?;
486486
let result = match p.token.uninterpolate().kind {
487487
token::Ident(name, IdentIsRaw::No) => ast::InlineAsmRegOrRegClass::RegClass(name),
488488
token::Literal(token::Lit { kind: token::LitKind::Str, symbol, suffix: _ }) => {
@@ -496,7 +496,7 @@ fn parse_reg<'a>(
496496
}
497497
};
498498
p.bump();
499-
p.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
499+
p.expect(exp!(CloseParen))?;
500500
Ok(result)
501501
}
502502

compiler/rustc_builtin_macros/src/assert.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, Path, PathSegment, UnOp, tok
77
use rustc_ast_pretty::pprust;
88
use rustc_errors::PResult;
99
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
10+
use rustc_parse::exp;
1011
use rustc_parse::parser::Parser;
1112
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
1213
use thin_vec::thin_vec;
@@ -143,7 +144,7 @@ fn parse_assert<'a>(cx: &ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PResult<
143144
cx.dcx().emit_err(errors::AssertMissingComma { span: parser.token.span, comma });
144145

145146
parse_custom_message(&mut parser)
146-
} else if parser.eat(&token::Comma) {
147+
} else if parser.eat(exp!(Comma)) {
147148
parse_custom_message(&mut parser)
148149
} else {
149150
None

compiler/rustc_builtin_macros/src/cfg.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_ast::token;
66
use rustc_ast::tokenstream::TokenStream;
77
use rustc_errors::PResult;
88
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
9+
use rustc_parse::exp;
910
use rustc_span::Span;
1011
use {rustc_ast as ast, rustc_attr_parsing as attr};
1112

@@ -48,9 +49,9 @@ fn parse_cfg<'a>(
4849

4950
let cfg = p.parse_meta_item_inner()?;
5051

51-
let _ = p.eat(&token::Comma);
52+
let _ = p.eat(exp!(Comma));
5253

53-
if !p.eat(&token::Eof) {
54+
if !p.eat(exp!(Eof)) {
5455
return Err(cx.dcx().create_err(errors::OneCfgPattern { span }));
5556
}
5657

compiler/rustc_builtin_macros/src/format.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_errors::{Applicability, Diag, MultiSpan, PResult, SingleLabelManySpans
1212
use rustc_expand::base::*;
1313
use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
1414
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId};
15+
use rustc_parse::exp;
1516
use rustc_parse_format as parse;
1617
use rustc_span::{BytePos, ErrorGuaranteed, Ident, InnerSpan, Span, Symbol};
1718

@@ -93,12 +94,12 @@ fn parse_args<'a>(ecx: &ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a,
9394
let mut first = true;
9495

9596
while p.token != token::Eof {
96-
if !p.eat(&token::Comma) {
97+
if !p.eat(exp!(Comma)) {
9798
if first {
98-
p.clear_expected_tokens();
99+
p.clear_expected_token_types();
99100
}
100101

101-
match p.expect(&token::Comma) {
102+
match p.expect(exp!(Comma)) {
102103
Err(err) => {
103104
match token::TokenKind::Comma.similar_tokens() {
104105
Some(tks) if tks.contains(&p.token.kind) => {
@@ -122,7 +123,7 @@ fn parse_args<'a>(ecx: &ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a,
122123
match p.token.ident() {
123124
Some((ident, _)) if p.look_ahead(1, |t| *t == token::Eq) => {
124125
p.bump();
125-
p.expect(&token::Eq)?;
126+
p.expect(exp!(Eq))?;
126127
let expr = p.parse_expr()?;
127128
if let Some((_, prev)) = args.by_name(ident.name) {
128129
ecx.dcx().emit_err(errors::FormatDuplicateArg {

compiler/rustc_builtin_macros/src/pattern_type.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use rustc_ast::tokenstream::TokenStream;
33
use rustc_ast::{Pat, Ty, ast};
44
use rustc_errors::PResult;
55
use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
6-
use rustc_span::{Span, sym};
6+
use rustc_parse::exp;
7+
use rustc_span::Span;
78

89
pub(crate) fn expand<'cx>(
910
cx: &'cx mut ExtCtxt<'_>,
@@ -24,7 +25,7 @@ fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P
2425
let mut parser = cx.new_parser_from_tts(stream);
2526

2627
let ty = parser.parse_ty()?;
27-
parser.expect_keyword(sym::is)?;
28+
parser.expect_keyword(exp!(Is))?;
2829
let pat = parser.parse_pat_no_top_alt(None, None)?;
2930

3031
Ok((ty, pat))

compiler/rustc_builtin_macros/src/util.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_expand::expand::AstFragment;
77
use rustc_feature::AttributeTemplate;
88
use rustc_lint_defs::BuiltinLintDiag;
99
use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES;
10-
use rustc_parse::{parser, validate_attr};
10+
use rustc_parse::{exp, parser, validate_attr};
1111
use rustc_session::errors::report_lit_error;
1212
use rustc_span::{BytePos, Span, Symbol};
1313

@@ -204,7 +204,7 @@ pub(crate) fn get_single_expr_from_tts(
204204
Ok(ret) => ret,
205205
Err(guar) => return ExpandResult::Ready(Err(guar)),
206206
};
207-
let _ = p.eat(&token::Comma);
207+
let _ = p.eat(exp!(Comma));
208208

209209
if p.token != token::Eof {
210210
cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
@@ -237,7 +237,7 @@ pub(crate) fn get_exprs_from_tts(
237237
let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
238238

239239
es.push(expr);
240-
if p.eat(&token::Comma) {
240+
if p.eat(exp!(Comma)) {
241241
continue;
242242
}
243243
if p.token != token::Eof {

0 commit comments

Comments
 (0)