diff options
Diffstat (limited to 'compiler/rustc_ast/src')
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 72 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/attr/mod.rs | 171 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/literal.rs | 16 |
3 files changed, 92 insertions, 167 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index d0bb05c3654..6a2f1f0c574 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -479,20 +479,10 @@ pub struct Crate { pub is_placeholder: bool, } -/// Possible values inside of compile-time attribute lists. -/// -/// E.g., the '..' in `#[name(..)]`. -#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] -pub enum NestedMetaItem { - /// A full MetaItem, for recursive meta items. - MetaItem(MetaItem), - /// A literal. - /// - /// E.g., `"foo"`, `64`, `true`. - Lit(MetaItemLit), -} - -/// A spanned compile-time attribute item. +/// A semantic representation of a meta item. A meta item is a slightly +/// restricted form of an attribute -- it can only contain expressions in +/// certain leaf positions, rather than arbitrary token streams -- that is used +/// for most built-in attributes. /// /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] @@ -502,25 +492,39 @@ pub struct MetaItem { pub span: Span, } -/// A compile-time attribute item. -/// -/// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`. +/// The meta item kind, containing the data after the initial path. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub enum MetaItemKind { /// Word meta item. /// - /// E.g., `test` as in `#[test]`. + /// E.g., `#[test]`, which lacks any arguments after `test`. Word, + /// List meta item. /// - /// E.g., `derive(..)` as in `#[derive(..)]`. + /// E.g., `#[derive(..)]`, where the field represents the `..`. List(Vec<NestedMetaItem>), + /// Name value meta item. /// - /// E.g., `feature = "foo"` as in `#[feature = "foo"]`. + /// E.g., `#[feature = "foo"]`, where the field represents the `"foo"`. NameValue(MetaItemLit), } +/// Values inside meta item lists. +/// +/// E.g., each of `Clone`, `Copy` in `#[derive(Clone, Copy)]`. +#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum NestedMetaItem { + /// A full MetaItem, for recursive meta items. + MetaItem(MetaItem), + + /// A literal. + /// + /// E.g., `"foo"`, `64`, `true`. + Lit(MetaItemLit), +} + /// A block (`{ .. }`). /// /// E.g., `{ .. }` as in `fn foo() { .. }`. @@ -2570,17 +2574,10 @@ impl<D: Decoder> Decodable<D> for AttrId { } } -#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] -pub struct AttrItem { - pub path: Path, - pub args: AttrArgs, - pub tokens: Option<LazyAttrTokenStream>, -} - /// A list of attributes. pub type AttrVec = ThinVec<Attribute>; -/// Metadata associated with an item. +/// A syntax-level representation of an attribute. #[derive(Clone, Encodable, Decodable, Debug)] pub struct Attribute { pub kind: AttrKind, @@ -2592,12 +2589,6 @@ pub struct Attribute { } #[derive(Clone, Encodable, Decodable, Debug)] -pub struct NormalAttr { - pub item: AttrItem, - pub tokens: Option<LazyAttrTokenStream>, -} - -#[derive(Clone, Encodable, Decodable, Debug)] pub enum AttrKind { /// A normal attribute. Normal(P<NormalAttr>), @@ -2608,6 +2599,19 @@ pub enum AttrKind { DocComment(CommentKind, Symbol), } +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct NormalAttr { + pub item: AttrItem, + pub tokens: Option<LazyAttrTokenStream>, +} + +#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +pub struct AttrItem { + pub path: Path, + pub args: AttrArgs, + pub tokens: Option<LazyAttrTokenStream>, +} + /// `TraitRef`s appear in impls. /// /// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 7a86b471ba2..057cc26b579 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,10 +1,10 @@ //! Functions dealing with attributes and meta items. use crate::ast; -use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, Attribute}; -use crate::ast::{DelimArgs, LitKind, MetaItemLit}; -use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; -use crate::ast::{Path, PathSegment}; +use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute}; +use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit}; +use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem, NormalAttr}; +use crate::ast::{Path, PathSegment, StrStyle, DUMMY_NODE_ID}; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter, Token}; use crate::tokenstream::{DelimSpan, Spacing, TokenTree}; @@ -12,7 +12,6 @@ use crate::tokenstream::{LazyAttrTokenStream, TokenStream}; use crate::util::comments; use rustc_data_structures::sync::WorkerLocal; use rustc_index::bit_set::GrowableBitSet; -use rustc_span::source_map::BytePos; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use std::cell::Cell; @@ -223,11 +222,7 @@ impl AttrItem { } pub fn meta(&self, span: Span) -> Option<MetaItem> { - Some(MetaItem { - path: self.path.clone(), - kind: MetaItemKind::from_attr_args(&self.args)?, - span, - }) + Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span }) } pub fn meta_kind(&self) -> Option<MetaItemKind> { @@ -329,26 +324,13 @@ impl Attribute { /* Constructors */ pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> MetaItem { - let lit_kind = LitKind::Str(str, ast::StrStyle::Cooked); - mk_name_value_item(ident, lit_kind, str_span) + mk_name_value_item(ident, LitKind::Str(str, ast::StrStyle::Cooked), str_span) } -pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem { - let lit = MetaItemLit::from_lit_kind(lit_kind, lit_span); +pub fn mk_name_value_item(ident: Ident, kind: LitKind, lit_span: Span) -> MetaItem { + let lit = MetaItemLit { token_lit: kind.to_token_lit(), kind, span: lit_span }; let span = ident.span.to(lit_span); - MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit) } -} - -pub fn mk_list_item(ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem { - MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::List(items) } -} - -pub fn mk_word_item(ident: Ident) -> MetaItem { - MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::Word } -} - -pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem { - NestedMetaItem::MetaItem(mk_word_item(ident)) + MetaItem { path: Path::from_ident(ident), kind: MetaItemKind::NameValue(lit), span } } pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>); @@ -406,21 +388,58 @@ pub fn mk_attr_from_item( span: Span, ) -> Attribute { Attribute { - kind: AttrKind::Normal(P(ast::NormalAttr { item, tokens })), + kind: AttrKind::Normal(P(NormalAttr { item, tokens })), id: g.mk_attr_id(), style, span, } } -/// Returns an inner attribute with the given value and span. -pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Inner, item.path, item.kind.attr_args(item.span), item.span) +pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute { + let path = Path::from_ident(Ident::new(name, span)); + let args = AttrArgs::Empty; + mk_attr(g, style, path, args, span) +} + +pub fn mk_attr_name_value_str( + g: &AttrIdGenerator, + style: AttrStyle, + name: Symbol, + val: Symbol, + span: Span, +) -> Attribute { + let lit = LitKind::Str(val, StrStyle::Cooked).to_token_lit(); + let expr = P(Expr { + id: DUMMY_NODE_ID, + kind: ExprKind::Lit(lit), + span, + attrs: AttrVec::new(), + tokens: None, + }); + let path = Path::from_ident(Ident::new(name, span)); + let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr)); + mk_attr(g, style, path, args, span) } -/// Returns an outer attribute with the given value and span. -pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Outer, item.path, item.kind.attr_args(item.span), item.span) +pub fn mk_attr_nested_word( + g: &AttrIdGenerator, + style: AttrStyle, + outer: Symbol, + inner: Symbol, + span: Span, +) -> Attribute { + let inner_tokens = TokenStream::new(vec![TokenTree::Token( + Token::from_ast_ident(Ident::new(inner, span)), + Spacing::Alone, + )]); + let outer_ident = Ident::new(outer, span); + let path = Path::from_ident(outer_ident); + let attr_args = AttrArgs::Delimited(DelimArgs { + dspan: DelimSpan::from_single(span), + delim: MacDelimiter::Parenthesis, + tokens: inner_tokens, + }); + mk_attr(g, style, path, attr_args, span) } pub fn mk_doc_comment( @@ -438,23 +457,6 @@ pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool { } impl MetaItem { - fn token_trees(&self) -> Vec<TokenTree> { - let mut idents = vec![]; - let mut last_pos = BytePos(0_u32); - for (i, segment) in self.path.segments.iter().enumerate() { - let is_first = i == 0; - if !is_first { - let mod_sep_span = - Span::new(last_pos, segment.ident.span.lo(), segment.ident.span.ctxt(), None); - idents.push(TokenTree::token_alone(token::ModSep, mod_sep_span)); - } - idents.push(TokenTree::Token(Token::from_ast_ident(segment.ident), Spacing::Alone)); - last_pos = segment.ident.span.hi(); - } - idents.extend(self.kind.token_trees(self.span)); - idents - } - fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem> where I: Iterator<Item = TokenTree>, @@ -526,62 +528,6 @@ impl MetaItemKind { } } - pub fn attr_args(&self, span: Span) -> AttrArgs { - match self { - MetaItemKind::Word => AttrArgs::Empty, - MetaItemKind::NameValue(lit) => { - let expr = P(ast::Expr { - id: ast::DUMMY_NODE_ID, - kind: ast::ExprKind::Lit(lit.token_lit.clone()), - span: lit.span, - attrs: ast::AttrVec::new(), - tokens: None, - }); - AttrArgs::Eq(span, AttrArgsEq::Ast(expr)) - } - MetaItemKind::List(list) => { - let mut tts = Vec::new(); - for (i, item) in list.iter().enumerate() { - if i > 0 { - tts.push(TokenTree::token_alone(token::Comma, span)); - } - tts.extend(item.token_trees()) - } - AttrArgs::Delimited(DelimArgs { - dspan: DelimSpan::from_single(span), - delim: MacDelimiter::Parenthesis, - tokens: TokenStream::new(tts), - }) - } - } - } - - fn token_trees(&self, span: Span) -> Vec<TokenTree> { - match self { - MetaItemKind::Word => vec![], - MetaItemKind::NameValue(lit) => { - vec![ - TokenTree::token_alone(token::Eq, span), - TokenTree::Token(lit.to_token(), Spacing::Alone), - ] - } - MetaItemKind::List(list) => { - let mut tokens = Vec::new(); - for (i, item) in list.iter().enumerate() { - if i > 0 { - tokens.push(TokenTree::token_alone(token::Comma, span)); - } - tokens.extend(item.token_trees()) - } - vec![TokenTree::Delimited( - DelimSpan::from_single(span), - Delimiter::Parenthesis, - TokenStream::new(tokens), - )] - } - } - } - fn list_from_tokens(tokens: TokenStream) -> Option<MetaItemKind> { let mut tokens = tokens.into_trees().peekable(); let mut result = Vec::new(); @@ -620,7 +566,7 @@ impl MetaItemKind { }) => MetaItemKind::list_from_tokens(tokens.clone()), AttrArgs::Delimited(..) => None, AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind { - ast::ExprKind::Lit(token_lit) => { + ExprKind::Lit(token_lit) => { // Turn failures to `None`, we'll get parse errors elsewhere. MetaItemLit::from_token_lit(token_lit, expr.span) .ok() @@ -659,15 +605,6 @@ impl NestedMetaItem { } } - fn token_trees(&self) -> Vec<TokenTree> { - match self { - NestedMetaItem::MetaItem(item) => item.token_trees(), - NestedMetaItem::Lit(lit) => { - vec![TokenTree::Token(lit.to_token(), Spacing::Alone)] - } - } - } - fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItem> where I: Iterator<Item = TokenTree>, diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 42cba07fcef..1d6e7914f3a 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -206,22 +206,6 @@ impl MetaItemLit { token::Lit::from_token(token) .and_then(|token_lit| MetaItemLit::from_token_lit(token_lit, token.span).ok()) } - - /// Attempts to create a meta item literal from a `LitKind`. - /// This function is used when the original token doesn't exist (e.g. the literal is created - /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). - pub fn from_lit_kind(kind: LitKind, span: Span) -> MetaItemLit { - MetaItemLit { token_lit: kind.to_token_lit(), kind, span } - } - - /// Losslessly convert a meta item literal into a token. - pub fn to_token(&self) -> Token { - let kind = match self.token_lit.kind { - token::Bool => token::Ident(self.token_lit.symbol, false), - _ => token::Literal(self.token_lit), - }; - Token::new(kind, self.span) - } } fn strip_underscores(symbol: Symbol) -> Symbol { |
