Skip to content

Commit f30733a

Browse files
committed
Auto merge of #80441 - petrochenkov:kwtok, r=Aaron1011
ast: Remove some indirection layers from values in key-value attributes Trying to address some perf regressions from #78837 (comment).
2 parents 6184f23 + 71cd6f4 commit f30733a

File tree

12 files changed

+72
-50
lines changed

12 files changed

+72
-50
lines changed

compiler/rustc_ast/src/ast.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ pub use GenericArgs::*;
2323
pub use UnsafeSource::*;
2424

2525
use crate::ptr::P;
26-
use crate::token::{self, CommentKind, DelimToken};
27-
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream};
26+
use crate::token::{self, CommentKind, DelimToken, Token};
27+
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree};
2828

2929
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3030
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -1464,8 +1464,8 @@ pub enum MacArgs {
14641464
Eq(
14651465
/// Span of the `=` token.
14661466
Span,
1467-
/// Token stream of the "value".
1468-
TokenStream,
1467+
/// "value" as a nonterminal token.
1468+
Token,
14691469
),
14701470
}
14711471

@@ -1478,10 +1478,10 @@ impl MacArgs {
14781478
}
14791479

14801480
pub fn span(&self) -> Option<Span> {
1481-
match *self {
1481+
match self {
14821482
MacArgs::Empty => None,
14831483
MacArgs::Delimited(dspan, ..) => Some(dspan.entire()),
1484-
MacArgs::Eq(eq_span, ref tokens) => Some(eq_span.to(tokens.span().unwrap_or(eq_span))),
1484+
MacArgs::Eq(eq_span, token) => Some(eq_span.to(token.span)),
14851485
}
14861486
}
14871487

@@ -1490,7 +1490,8 @@ impl MacArgs {
14901490
pub fn inner_tokens(&self) -> TokenStream {
14911491
match self {
14921492
MacArgs::Empty => TokenStream::default(),
1493-
MacArgs::Delimited(.., tokens) | MacArgs::Eq(.., tokens) => tokens.clone(),
1493+
MacArgs::Delimited(.., tokens) => tokens.clone(),
1494+
MacArgs::Eq(.., token) => TokenTree::Token(token.clone()).into(),
14941495
}
14951496
}
14961497

compiler/rustc_ast/src/attr/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ impl MetaItemKind {
476476
pub fn mac_args(&self, span: Span) -> MacArgs {
477477
match self {
478478
MetaItemKind::Word => MacArgs::Empty,
479-
MetaItemKind::NameValue(lit) => MacArgs::Eq(span, lit.token_tree().into()),
479+
MetaItemKind::NameValue(lit) => MacArgs::Eq(span, lit.to_token()),
480480
MetaItemKind::List(list) => {
481481
let mut tts = Vec::new();
482482
for (i, item) in list.iter().enumerate() {
@@ -498,7 +498,10 @@ impl MetaItemKind {
498498
match *self {
499499
MetaItemKind::Word => vec![],
500500
MetaItemKind::NameValue(ref lit) => {
501-
vec![TokenTree::token(token::Eq, span).into(), lit.token_tree().into()]
501+
vec![
502+
TokenTree::token(token::Eq, span).into(),
503+
TokenTree::Token(lit.to_token()).into(),
504+
]
502505
}
503506
MetaItemKind::List(ref list) => {
504507
let mut tokens = Vec::new();
@@ -554,10 +557,7 @@ impl MetaItemKind {
554557
MetaItemKind::list_from_tokens(tokens.clone())
555558
}
556559
MacArgs::Delimited(..) => None,
557-
MacArgs::Eq(_, tokens) => {
558-
assert!(tokens.len() == 1);
559-
MetaItemKind::name_value_from_tokens(&mut tokens.trees())
560-
}
560+
MacArgs::Eq(_, token) => Lit::from_token(token).ok().map(MetaItemKind::NameValue),
561561
MacArgs::Empty => Some(MetaItemKind::Word),
562562
}
563563
}
@@ -592,7 +592,7 @@ impl NestedMetaItem {
592592
fn token_trees_and_spacings(&self) -> Vec<TreeAndSpacing> {
593593
match *self {
594594
NestedMetaItem::MetaItem(ref item) => item.token_trees_and_spacings(),
595-
NestedMetaItem::Literal(ref lit) => vec![lit.token_tree().into()],
595+
NestedMetaItem::Literal(ref lit) => vec![TokenTree::Token(lit.to_token()).into()],
596596
}
597597
}
598598

compiler/rustc_ast/src/mut_visit.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -365,18 +365,16 @@ pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) {
365365
visit_delim_span(dspan, vis);
366366
visit_tts(tokens, vis);
367367
}
368-
MacArgs::Eq(eq_span, tokens) => {
368+
MacArgs::Eq(eq_span, token) => {
369369
vis.visit_span(eq_span);
370-
visit_tts(tokens, vis);
371-
// The value in `#[key = VALUE]` must be visited as an expression for backward
372-
// compatibility, so that macros can be expanded in that position.
373-
if !vis.token_visiting_enabled() {
374-
match Lrc::make_mut(&mut tokens.0).get_mut(0) {
375-
Some((TokenTree::Token(token), _spacing)) => match &mut token.kind {
376-
token::Interpolated(nt) => match Lrc::make_mut(nt) {
377-
token::NtExpr(expr) => vis.visit_expr(expr),
378-
t => panic!("unexpected token in key-value attribute: {:?}", t),
379-
},
370+
if vis.token_visiting_enabled() {
371+
visit_token(token, vis);
372+
} else {
373+
// The value in `#[key = VALUE]` must be visited as an expression for backward
374+
// compatibility, so that macros can be expanded in that position.
375+
match &mut token.kind {
376+
token::Interpolated(nt) => match Lrc::make_mut(nt) {
377+
token::NtExpr(expr) => vis.visit_expr(expr),
380378
t => panic!("unexpected token in key-value attribute: {:?}", t),
381379
},
382380
t => panic!("unexpected token in key-value attribute: {:?}", t),

compiler/rustc_ast/src/util/literal.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use crate::ast::{self, Lit, LitKind};
44
use crate::token::{self, Token};
5-
use crate::tokenstream::TokenTree;
65

76
use rustc_lexer::unescape::{unescape_byte, unescape_char};
87
use rustc_lexer::unescape::{unescape_byte_literal, unescape_literal, Mode};
@@ -225,13 +224,13 @@ impl Lit {
225224
Lit { token: kind.to_lit_token(), kind, span }
226225
}
227226

228-
/// Losslessly convert an AST literal into a token stream.
229-
pub fn token_tree(&self) -> TokenTree {
230-
let token = match self.token.kind {
227+
/// Losslessly convert an AST literal into a token.
228+
pub fn to_token(&self) -> Token {
229+
let kind = match self.token.kind {
231230
token::Bool => token::Ident(self.token.symbol, false),
232231
_ => token::Literal(self.token),
233232
};
234-
TokenTree::token(token, self.span)
233+
Token::new(kind, self.span)
235234
}
236235
}
237236

compiler/rustc_ast/src/visit.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
1616
use crate::ast::*;
1717
use crate::token;
18-
use crate::tokenstream::TokenTree;
1918

2019
use rustc_span::symbol::{Ident, Symbol};
2120
use rustc_span::Span;
@@ -905,12 +904,9 @@ pub fn walk_mac_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a MacArgs) {
905904
MacArgs::Delimited(_dspan, _delim, _tokens) => {}
906905
// The value in `#[key = VALUE]` must be visited as an expression for backward
907906
// compatibility, so that macros can be expanded in that position.
908-
MacArgs::Eq(_eq_span, tokens) => match tokens.trees_ref().next() {
909-
Some(TokenTree::Token(token)) => match &token.kind {
910-
token::Interpolated(nt) => match &**nt {
911-
token::NtExpr(expr) => visitor.visit_expr(expr),
912-
t => panic!("unexpected token in key-value attribute: {:?}", t),
913-
},
907+
MacArgs::Eq(_eq_span, token) => match &token.kind {
908+
token::Interpolated(nt) => match &**nt {
909+
token::NtExpr(expr) => visitor.visit_expr(expr),
914910
t => panic!("unexpected token in key-value attribute: {:?}", t),
915911
},
916912
t => panic!("unexpected token in key-value attribute: {:?}", t),

compiler/rustc_ast_lowering/src/lib.rs

+30-4
Original file line numberDiff line numberDiff line change
@@ -1013,10 +1013,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10131013
// This is an inert key-value attribute - it will never be visible to macros
10141014
// after it gets lowered to HIR. Therefore, we can synthesize tokens with fake
10151015
// spans to handle nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
1016-
MacArgs::Eq(eq_span, ref tokens) => MacArgs::Eq(
1017-
eq_span,
1018-
self.lower_token_stream(tokens.clone(), CanSynthesizeMissingTokens::Yes),
1019-
),
1016+
MacArgs::Eq(eq_span, ref token) => {
1017+
// In valid code the value is always representable as a single literal token.
1018+
fn unwrap_single_token(sess: &Session, tokens: TokenStream, span: Span) -> Token {
1019+
if tokens.len() != 1 {
1020+
sess.diagnostic()
1021+
.delay_span_bug(span, "multiple tokens in key-value attribute's value");
1022+
}
1023+
match tokens.into_trees().next() {
1024+
Some(TokenTree::Token(token)) => token,
1025+
Some(TokenTree::Delimited(_, delim, tokens)) => {
1026+
if delim != token::NoDelim {
1027+
sess.diagnostic().delay_span_bug(
1028+
span,
1029+
"unexpected delimiter in key-value attribute's value",
1030+
)
1031+
}
1032+
unwrap_single_token(sess, tokens, span)
1033+
}
1034+
None => Token::dummy(),
1035+
}
1036+
}
1037+
1038+
let tokens = TokenStreamLowering {
1039+
parse_sess: &self.sess.parse_sess,
1040+
synthesize_tokens: CanSynthesizeMissingTokens::Yes,
1041+
nt_to_tokenstream: self.nt_to_tokenstream,
1042+
}
1043+
.lower_token(token.clone());
1044+
MacArgs::Eq(eq_span, unwrap_single_token(self.sess, tokens, token.span))
1045+
}
10201046
}
10211047
}
10221048

compiler/rustc_ast_pretty/src/pprust/state.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,11 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
445445
),
446446
MacArgs::Empty | MacArgs::Eq(..) => {
447447
self.print_path(&item.path, false, 0);
448-
if let MacArgs::Eq(_, tokens) = &item.args {
448+
if let MacArgs::Eq(_, token) = &item.args {
449449
self.space();
450450
self.word_space("=");
451-
self.print_tts(tokens, true);
451+
let token_str = self.token_to_string_ext(token, true);
452+
self.word(token_str);
452453
}
453454
}
454455
}

compiler/rustc_parse/src/parser/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -983,8 +983,8 @@ impl<'a> Parser<'a> {
983983
_ => self.sess.gated_spans.gate(sym::extended_key_value_attributes, span),
984984
}
985985

986-
let token = token::Interpolated(Lrc::new(token::NtExpr(expr)));
987-
MacArgs::Eq(eq_span, TokenTree::token(token, span).into())
986+
let token_kind = token::Interpolated(Lrc::new(token::NtExpr(expr)));
987+
MacArgs::Eq(eq_span, Token::new(token_kind, span))
988988
} else {
989989
MacArgs::Empty
990990
}

compiler/rustc_parse/src/validate_attr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::parse_in;
44

5-
use rustc_ast::tokenstream::DelimSpan;
5+
use rustc_ast::tokenstream::{DelimSpan, TokenTree};
66
use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
77
use rustc_errors::{Applicability, PResult};
88
use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP};
@@ -45,7 +45,8 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
4545
kind: match &item.args {
4646
MacArgs::Empty => MetaItemKind::Word,
4747
MacArgs::Eq(_, t) => {
48-
let v = parse_in(sess, t.clone(), "name value", |p| p.parse_unsuffixed_lit())?;
48+
let t = TokenTree::Token(t.clone()).into();
49+
let v = parse_in(sess, t, "name value", |p| p.parse_unsuffixed_lit())?;
4950
MetaItemKind::NameValue(v)
5051
}
5152
MacArgs::Delimited(dspan, delim, t) => {
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Interpolated","fields":[{"variant":"NtExpr","fields":[{"id":0,"kind":{"variant":"Lit","fields":[{"token":{"kind":"Str","symbol":"lib","suffix":null},"kind":{"variant":"Str","fields":["lib","Cooked"]},"span":{"lo":0,"hi":0}}]},"span":{"lo":0,"hi":0},"attrs":{"0":null},"tokens":null}]}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
1+
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"kind":{"variant":"Interpolated","fields":[{"variant":"NtExpr","fields":[{"id":0,"kind":{"variant":"Lit","fields":[{"token":{"kind":"Str","symbol":"lib","suffix":null},"kind":{"variant":"Str","fields":["lib","Cooked"]},"span":{"lo":0,"hi":0}}]},"span":{"lo":0,"hi":0},"attrs":{"0":null},"tokens":null}]}]},"span":{"lo":0,"hi":0}}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}

0 commit comments

Comments
 (0)