Skip to content

Commit d6c4de0

Browse files
committed
Auto merge of #104861 - nnethercote:attr-cleanups, r=petrochenkov
Attribute cleanups Best reviewed one commit at a time. r? `@petrochenkov`
2 parents 744a97b + ba1751a commit d6c4de0

File tree

29 files changed

+231
-307
lines changed

29 files changed

+231
-307
lines changed

compiler/rustc_ast/src/ast.rs

+38-34
Original file line numberDiff line numberDiff line change
@@ -479,20 +479,10 @@ pub struct Crate {
479479
pub is_placeholder: bool,
480480
}
481481

482-
/// Possible values inside of compile-time attribute lists.
483-
///
484-
/// E.g., the '..' in `#[name(..)]`.
485-
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
486-
pub enum NestedMetaItem {
487-
/// A full MetaItem, for recursive meta items.
488-
MetaItem(MetaItem),
489-
/// A literal.
490-
///
491-
/// E.g., `"foo"`, `64`, `true`.
492-
Lit(MetaItemLit),
493-
}
494-
495-
/// A spanned compile-time attribute item.
482+
/// A semantic representation of a meta item. A meta item is a slightly
483+
/// restricted form of an attribute -- it can only contain expressions in
484+
/// certain leaf positions, rather than arbitrary token streams -- that is used
485+
/// for most built-in attributes.
496486
///
497487
/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
498488
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
@@ -502,25 +492,39 @@ pub struct MetaItem {
502492
pub span: Span,
503493
}
504494

505-
/// A compile-time attribute item.
506-
///
507-
/// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`.
495+
/// The meta item kind, containing the data after the initial path.
508496
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
509497
pub enum MetaItemKind {
510498
/// Word meta item.
511499
///
512-
/// E.g., `test` as in `#[test]`.
500+
/// E.g., `#[test]`, which lacks any arguments after `test`.
513501
Word,
502+
514503
/// List meta item.
515504
///
516-
/// E.g., `derive(..)` as in `#[derive(..)]`.
505+
/// E.g., `#[derive(..)]`, where the field represents the `..`.
517506
List(Vec<NestedMetaItem>),
507+
518508
/// Name value meta item.
519509
///
520-
/// E.g., `feature = "foo"` as in `#[feature = "foo"]`.
510+
/// E.g., `#[feature = "foo"]`, where the field represents the `"foo"`.
521511
NameValue(MetaItemLit),
522512
}
523513

514+
/// Values inside meta item lists.
515+
///
516+
/// E.g., each of `Clone`, `Copy` in `#[derive(Clone, Copy)]`.
517+
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
518+
pub enum NestedMetaItem {
519+
/// A full MetaItem, for recursive meta items.
520+
MetaItem(MetaItem),
521+
522+
/// A literal.
523+
///
524+
/// E.g., `"foo"`, `64`, `true`.
525+
Lit(MetaItemLit),
526+
}
527+
524528
/// A block (`{ .. }`).
525529
///
526530
/// E.g., `{ .. }` as in `fn foo() { .. }`.
@@ -2570,17 +2574,10 @@ impl<D: Decoder> Decodable<D> for AttrId {
25702574
}
25712575
}
25722576

2573-
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2574-
pub struct AttrItem {
2575-
pub path: Path,
2576-
pub args: AttrArgs,
2577-
pub tokens: Option<LazyAttrTokenStream>,
2578-
}
2579-
25802577
/// A list of attributes.
25812578
pub type AttrVec = ThinVec<Attribute>;
25822579

2583-
/// Metadata associated with an item.
2580+
/// A syntax-level representation of an attribute.
25842581
#[derive(Clone, Encodable, Decodable, Debug)]
25852582
pub struct Attribute {
25862583
pub kind: AttrKind,
@@ -2591,12 +2588,6 @@ pub struct Attribute {
25912588
pub span: Span,
25922589
}
25932590

2594-
#[derive(Clone, Encodable, Decodable, Debug)]
2595-
pub struct NormalAttr {
2596-
pub item: AttrItem,
2597-
pub tokens: Option<LazyAttrTokenStream>,
2598-
}
2599-
26002591
#[derive(Clone, Encodable, Decodable, Debug)]
26012592
pub enum AttrKind {
26022593
/// A normal attribute.
@@ -2608,6 +2599,19 @@ pub enum AttrKind {
26082599
DocComment(CommentKind, Symbol),
26092600
}
26102601

2602+
#[derive(Clone, Encodable, Decodable, Debug)]
2603+
pub struct NormalAttr {
2604+
pub item: AttrItem,
2605+
pub tokens: Option<LazyAttrTokenStream>,
2606+
}
2607+
2608+
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2609+
pub struct AttrItem {
2610+
pub path: Path,
2611+
pub args: AttrArgs,
2612+
pub tokens: Option<LazyAttrTokenStream>,
2613+
}
2614+
26112615
/// `TraitRef`s appear in impls.
26122616
///
26132617
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all

compiler/rustc_ast/src/attr/mod.rs

+54-117
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
//! Functions dealing with attributes and meta items.
22
33
use crate::ast;
4-
use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
5-
use crate::ast::{DelimArgs, LitKind, MetaItemLit};
6-
use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
7-
use crate::ast::{Path, PathSegment};
4+
use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute};
5+
use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit};
6+
use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem, NormalAttr};
7+
use crate::ast::{Path, PathSegment, StrStyle, DUMMY_NODE_ID};
88
use crate::ptr::P;
99
use crate::token::{self, CommentKind, Delimiter, Token};
1010
use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
1111
use crate::tokenstream::{LazyAttrTokenStream, TokenStream};
1212
use crate::util::comments;
1313
use rustc_data_structures::sync::WorkerLocal;
1414
use rustc_index::bit_set::GrowableBitSet;
15-
use rustc_span::source_map::BytePos;
1615
use rustc_span::symbol::{sym, Ident, Symbol};
1716
use rustc_span::Span;
1817
use std::cell::Cell;
@@ -223,11 +222,7 @@ impl AttrItem {
223222
}
224223

225224
pub fn meta(&self, span: Span) -> Option<MetaItem> {
226-
Some(MetaItem {
227-
path: self.path.clone(),
228-
kind: MetaItemKind::from_attr_args(&self.args)?,
229-
span,
230-
})
225+
Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span })
231226
}
232227

233228
pub fn meta_kind(&self) -> Option<MetaItemKind> {
@@ -329,26 +324,13 @@ impl Attribute {
329324
/* Constructors */
330325

331326
pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> MetaItem {
332-
let lit_kind = LitKind::Str(str, ast::StrStyle::Cooked);
333-
mk_name_value_item(ident, lit_kind, str_span)
327+
mk_name_value_item(ident, LitKind::Str(str, ast::StrStyle::Cooked), str_span)
334328
}
335329

336-
pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem {
337-
let lit = MetaItemLit::from_lit_kind(lit_kind, lit_span);
330+
pub fn mk_name_value_item(ident: Ident, kind: LitKind, lit_span: Span) -> MetaItem {
331+
let lit = MetaItemLit { token_lit: kind.to_token_lit(), kind, span: lit_span };
338332
let span = ident.span.to(lit_span);
339-
MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit) }
340-
}
341-
342-
pub fn mk_list_item(ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
343-
MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::List(items) }
344-
}
345-
346-
pub fn mk_word_item(ident: Ident) -> MetaItem {
347-
MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::Word }
348-
}
349-
350-
pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
351-
NestedMetaItem::MetaItem(mk_word_item(ident))
333+
MetaItem { path: Path::from_ident(ident), kind: MetaItemKind::NameValue(lit), span }
352334
}
353335

354336
pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>);
@@ -406,21 +388,58 @@ pub fn mk_attr_from_item(
406388
span: Span,
407389
) -> Attribute {
408390
Attribute {
409-
kind: AttrKind::Normal(P(ast::NormalAttr { item, tokens })),
391+
kind: AttrKind::Normal(P(NormalAttr { item, tokens })),
410392
id: g.mk_attr_id(),
411393
style,
412394
span,
413395
}
414396
}
415397

416-
/// Returns an inner attribute with the given value and span.
417-
pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
418-
mk_attr(g, AttrStyle::Inner, item.path, item.kind.attr_args(item.span), item.span)
398+
pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute {
399+
let path = Path::from_ident(Ident::new(name, span));
400+
let args = AttrArgs::Empty;
401+
mk_attr(g, style, path, args, span)
402+
}
403+
404+
pub fn mk_attr_name_value_str(
405+
g: &AttrIdGenerator,
406+
style: AttrStyle,
407+
name: Symbol,
408+
val: Symbol,
409+
span: Span,
410+
) -> Attribute {
411+
let lit = LitKind::Str(val, StrStyle::Cooked).to_token_lit();
412+
let expr = P(Expr {
413+
id: DUMMY_NODE_ID,
414+
kind: ExprKind::Lit(lit),
415+
span,
416+
attrs: AttrVec::new(),
417+
tokens: None,
418+
});
419+
let path = Path::from_ident(Ident::new(name, span));
420+
let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr));
421+
mk_attr(g, style, path, args, span)
419422
}
420423

421-
/// Returns an outer attribute with the given value and span.
422-
pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
423-
mk_attr(g, AttrStyle::Outer, item.path, item.kind.attr_args(item.span), item.span)
424+
pub fn mk_attr_nested_word(
425+
g: &AttrIdGenerator,
426+
style: AttrStyle,
427+
outer: Symbol,
428+
inner: Symbol,
429+
span: Span,
430+
) -> Attribute {
431+
let inner_tokens = TokenStream::new(vec![TokenTree::Token(
432+
Token::from_ast_ident(Ident::new(inner, span)),
433+
Spacing::Alone,
434+
)]);
435+
let outer_ident = Ident::new(outer, span);
436+
let path = Path::from_ident(outer_ident);
437+
let attr_args = AttrArgs::Delimited(DelimArgs {
438+
dspan: DelimSpan::from_single(span),
439+
delim: MacDelimiter::Parenthesis,
440+
tokens: inner_tokens,
441+
});
442+
mk_attr(g, style, path, attr_args, span)
424443
}
425444

426445
pub fn mk_doc_comment(
@@ -438,23 +457,6 @@ pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
438457
}
439458

440459
impl MetaItem {
441-
fn token_trees(&self) -> Vec<TokenTree> {
442-
let mut idents = vec![];
443-
let mut last_pos = BytePos(0_u32);
444-
for (i, segment) in self.path.segments.iter().enumerate() {
445-
let is_first = i == 0;
446-
if !is_first {
447-
let mod_sep_span =
448-
Span::new(last_pos, segment.ident.span.lo(), segment.ident.span.ctxt(), None);
449-
idents.push(TokenTree::token_alone(token::ModSep, mod_sep_span));
450-
}
451-
idents.push(TokenTree::Token(Token::from_ast_ident(segment.ident), Spacing::Alone));
452-
last_pos = segment.ident.span.hi();
453-
}
454-
idents.extend(self.kind.token_trees(self.span));
455-
idents
456-
}
457-
458460
fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
459461
where
460462
I: Iterator<Item = TokenTree>,
@@ -526,62 +528,6 @@ impl MetaItemKind {
526528
}
527529
}
528530

529-
pub fn attr_args(&self, span: Span) -> AttrArgs {
530-
match self {
531-
MetaItemKind::Word => AttrArgs::Empty,
532-
MetaItemKind::NameValue(lit) => {
533-
let expr = P(ast::Expr {
534-
id: ast::DUMMY_NODE_ID,
535-
kind: ast::ExprKind::Lit(lit.token_lit.clone()),
536-
span: lit.span,
537-
attrs: ast::AttrVec::new(),
538-
tokens: None,
539-
});
540-
AttrArgs::Eq(span, AttrArgsEq::Ast(expr))
541-
}
542-
MetaItemKind::List(list) => {
543-
let mut tts = Vec::new();
544-
for (i, item) in list.iter().enumerate() {
545-
if i > 0 {
546-
tts.push(TokenTree::token_alone(token::Comma, span));
547-
}
548-
tts.extend(item.token_trees())
549-
}
550-
AttrArgs::Delimited(DelimArgs {
551-
dspan: DelimSpan::from_single(span),
552-
delim: MacDelimiter::Parenthesis,
553-
tokens: TokenStream::new(tts),
554-
})
555-
}
556-
}
557-
}
558-
559-
fn token_trees(&self, span: Span) -> Vec<TokenTree> {
560-
match self {
561-
MetaItemKind::Word => vec![],
562-
MetaItemKind::NameValue(lit) => {
563-
vec![
564-
TokenTree::token_alone(token::Eq, span),
565-
TokenTree::Token(lit.to_token(), Spacing::Alone),
566-
]
567-
}
568-
MetaItemKind::List(list) => {
569-
let mut tokens = Vec::new();
570-
for (i, item) in list.iter().enumerate() {
571-
if i > 0 {
572-
tokens.push(TokenTree::token_alone(token::Comma, span));
573-
}
574-
tokens.extend(item.token_trees())
575-
}
576-
vec![TokenTree::Delimited(
577-
DelimSpan::from_single(span),
578-
Delimiter::Parenthesis,
579-
TokenStream::new(tokens),
580-
)]
581-
}
582-
}
583-
}
584-
585531
fn list_from_tokens(tokens: TokenStream) -> Option<MetaItemKind> {
586532
let mut tokens = tokens.into_trees().peekable();
587533
let mut result = Vec::new();
@@ -620,7 +566,7 @@ impl MetaItemKind {
620566
}) => MetaItemKind::list_from_tokens(tokens.clone()),
621567
AttrArgs::Delimited(..) => None,
622568
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind {
623-
ast::ExprKind::Lit(token_lit) => {
569+
ExprKind::Lit(token_lit) => {
624570
// Turn failures to `None`, we'll get parse errors elsewhere.
625571
MetaItemLit::from_token_lit(token_lit, expr.span)
626572
.ok()
@@ -659,15 +605,6 @@ impl NestedMetaItem {
659605
}
660606
}
661607

662-
fn token_trees(&self) -> Vec<TokenTree> {
663-
match self {
664-
NestedMetaItem::MetaItem(item) => item.token_trees(),
665-
NestedMetaItem::Lit(lit) => {
666-
vec![TokenTree::Token(lit.to_token(), Spacing::Alone)]
667-
}
668-
}
669-
}
670-
671608
fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItem>
672609
where
673610
I: Iterator<Item = TokenTree>,

compiler/rustc_ast/src/util/literal.rs

-16
Original file line numberDiff line numberDiff line change
@@ -206,22 +206,6 @@ impl MetaItemLit {
206206
token::Lit::from_token(token)
207207
.and_then(|token_lit| MetaItemLit::from_token_lit(token_lit, token.span).ok())
208208
}
209-
210-
/// Attempts to create a meta item literal from a `LitKind`.
211-
/// This function is used when the original token doesn't exist (e.g. the literal is created
212-
/// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
213-
pub fn from_lit_kind(kind: LitKind, span: Span) -> MetaItemLit {
214-
MetaItemLit { token_lit: kind.to_token_lit(), kind, span }
215-
}
216-
217-
/// Losslessly convert a meta item literal into a token.
218-
pub fn to_token(&self) -> Token {
219-
let kind = match self.token_lit.kind {
220-
token::Bool => token::Ident(self.token_lit.symbol, false),
221-
_ => token::Literal(self.token_lit),
222-
};
223-
Token::new(kind, self.span)
224-
}
225209
}
226210

227211
fn strip_underscores(symbol: Symbol) -> Symbol {

0 commit comments

Comments
 (0)