1
Fork 0

ast: Remove some indirection layers from values in key-value attributes

This commit is contained in:
Vadim Petrochenkov 2020-12-19 23:38:22 +03:00
parent ef589490a7
commit 71cd6f42a6
12 changed files with 72 additions and 50 deletions

View file

@ -23,8 +23,8 @@ pub use GenericArgs::*;
pub use UnsafeSource::*;
use crate::ptr::P;
use crate::token::{self, CommentKind, DelimToken};
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream};
use crate::token::{self, CommentKind, DelimToken, Token};
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stack::ensure_sufficient_stack;
@ -1464,8 +1464,8 @@ pub enum MacArgs {
Eq(
/// Span of the `=` token.
Span,
/// Token stream of the "value".
TokenStream,
/// "value" as a nonterminal token.
Token,
),
}
@ -1478,10 +1478,10 @@ impl MacArgs {
}
pub fn span(&self) -> Option<Span> {
match *self {
match self {
MacArgs::Empty => None,
MacArgs::Delimited(dspan, ..) => Some(dspan.entire()),
MacArgs::Eq(eq_span, ref tokens) => Some(eq_span.to(tokens.span().unwrap_or(eq_span))),
MacArgs::Eq(eq_span, token) => Some(eq_span.to(token.span)),
}
}
@ -1490,7 +1490,8 @@ impl MacArgs {
pub fn inner_tokens(&self) -> TokenStream {
match self {
MacArgs::Empty => TokenStream::default(),
MacArgs::Delimited(.., tokens) | MacArgs::Eq(.., tokens) => tokens.clone(),
MacArgs::Delimited(.., tokens) => tokens.clone(),
MacArgs::Eq(.., token) => TokenTree::Token(token.clone()).into(),
}
}

View file

@ -476,7 +476,7 @@ impl MetaItemKind {
pub fn mac_args(&self, span: Span) -> MacArgs {
match self {
MetaItemKind::Word => MacArgs::Empty,
MetaItemKind::NameValue(lit) => MacArgs::Eq(span, lit.token_tree().into()),
MetaItemKind::NameValue(lit) => MacArgs::Eq(span, lit.to_token()),
MetaItemKind::List(list) => {
let mut tts = Vec::new();
for (i, item) in list.iter().enumerate() {
@ -498,7 +498,10 @@ impl MetaItemKind {
match *self {
MetaItemKind::Word => vec![],
MetaItemKind::NameValue(ref lit) => {
vec![TokenTree::token(token::Eq, span).into(), lit.token_tree().into()]
vec![
TokenTree::token(token::Eq, span).into(),
TokenTree::Token(lit.to_token()).into(),
]
}
MetaItemKind::List(ref list) => {
let mut tokens = Vec::new();
@ -554,10 +557,7 @@ impl MetaItemKind {
MetaItemKind::list_from_tokens(tokens.clone())
}
MacArgs::Delimited(..) => None,
MacArgs::Eq(_, tokens) => {
assert!(tokens.len() == 1);
MetaItemKind::name_value_from_tokens(&mut tokens.trees())
}
MacArgs::Eq(_, token) => Lit::from_token(token).ok().map(MetaItemKind::NameValue),
MacArgs::Empty => Some(MetaItemKind::Word),
}
}
@ -592,7 +592,7 @@ impl NestedMetaItem {
fn token_trees_and_spacings(&self) -> Vec<TreeAndSpacing> {
match *self {
NestedMetaItem::MetaItem(ref item) => item.token_trees_and_spacings(),
NestedMetaItem::Literal(ref lit) => vec![lit.token_tree().into()],
NestedMetaItem::Literal(ref lit) => vec![TokenTree::Token(lit.to_token()).into()],
}
}

View file

@ -365,18 +365,16 @@ pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) {
visit_delim_span(dspan, vis);
visit_tts(tokens, vis);
}
MacArgs::Eq(eq_span, tokens) => {
MacArgs::Eq(eq_span, token) => {
vis.visit_span(eq_span);
visit_tts(tokens, vis);
// The value in `#[key = VALUE]` must be visited as an expression for backward
// compatibility, so that macros can be expanded in that position.
if !vis.token_visiting_enabled() {
match Lrc::make_mut(&mut tokens.0).get_mut(0) {
Some((TokenTree::Token(token), _spacing)) => match &mut token.kind {
token::Interpolated(nt) => match Lrc::make_mut(nt) {
token::NtExpr(expr) => vis.visit_expr(expr),
t => panic!("unexpected token in key-value attribute: {:?}", t),
},
if vis.token_visiting_enabled() {
visit_token(token, vis);
} else {
// The value in `#[key = VALUE]` must be visited as an expression for backward
// compatibility, so that macros can be expanded in that position.
match &mut token.kind {
token::Interpolated(nt) => match Lrc::make_mut(nt) {
token::NtExpr(expr) => vis.visit_expr(expr),
t => panic!("unexpected token in key-value attribute: {:?}", t),
},
t => panic!("unexpected token in key-value attribute: {:?}", t),

View file

@ -2,7 +2,6 @@
use crate::ast::{self, Lit, LitKind};
use crate::token::{self, Token};
use crate::tokenstream::TokenTree;
use rustc_lexer::unescape::{unescape_byte, unescape_char};
use rustc_lexer::unescape::{unescape_byte_literal, unescape_literal, Mode};
@ -225,13 +224,13 @@ impl Lit {
Lit { token: kind.to_lit_token(), kind, span }
}
/// Losslessly convert an AST literal into a token stream.
pub fn token_tree(&self) -> TokenTree {
let token = match self.token.kind {
/// Losslessly convert an AST literal into a token.
pub fn to_token(&self) -> Token {
let kind = match self.token.kind {
token::Bool => token::Ident(self.token.symbol, false),
_ => token::Literal(self.token),
};
TokenTree::token(token, self.span)
Token::new(kind, self.span)
}
}

View file

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