Auto merge of #78782 - petrochenkov:nodoctok, r=Aaron1011
Do not collect tokens for doc comments Doc comment is a single token and AST has all the information to re-create it precisely. Doc comments are also responsible for majority of calls to `collect_tokens` (with `num_calls == 1` and `num_calls == 0`, cc https://github.com/rust-lang/rust/pull/78736). (I also moved token collection into `fn parse_attribute` to deduplicate code a bit.) r? `@Aaron1011`
This commit is contained in:
commit
5a6a41e784
@ -2439,13 +2439,12 @@ pub struct Attribute {
|
||||
/// or the construct this attribute is contained within (inner).
|
||||
pub style: AttrStyle,
|
||||
pub span: Span,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum AttrKind {
|
||||
/// A normal attribute.
|
||||
Normal(AttrItem),
|
||||
Normal(AttrItem, Option<LazyTokenStream>),
|
||||
|
||||
/// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
|
||||
/// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
|
||||
|
@ -8,7 +8,7 @@ use crate::ast::{Path, PathSegment};
|
||||
use crate::mut_visit::visit_clobber;
|
||||
use crate::ptr::P;
|
||||
use crate::token::{self, CommentKind, Token};
|
||||
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndSpacing};
|
||||
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree, TreeAndSpacing};
|
||||
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
use rustc_span::source_map::{BytePos, Spanned};
|
||||
@ -120,7 +120,7 @@ impl NestedMetaItem {
|
||||
impl Attribute {
|
||||
pub fn has_name(&self, name: Symbol) -> bool {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref item) => item.path == name,
|
||||
AttrKind::Normal(ref item, _) => item.path == name,
|
||||
AttrKind::DocComment(..) => false,
|
||||
}
|
||||
}
|
||||
@ -128,7 +128,7 @@ impl Attribute {
|
||||
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
|
||||
pub fn ident(&self) -> Option<Ident> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref item) => {
|
||||
AttrKind::Normal(ref item, _) => {
|
||||
if item.path.segments.len() == 1 {
|
||||
Some(item.path.segments[0].ident)
|
||||
} else {
|
||||
@ -144,14 +144,14 @@ impl Attribute {
|
||||
|
||||
pub fn value_str(&self) -> Option<Symbol> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref item) => item.meta(self.span).and_then(|meta| meta.value_str()),
|
||||
AttrKind::Normal(ref item, _) => item.meta(self.span).and_then(|meta| meta.value_str()),
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref item) => match item.meta(self.span) {
|
||||
AttrKind::Normal(ref item, _) => match item.meta(self.span) {
|
||||
Some(MetaItem { kind: MetaItemKind::List(list), .. }) => Some(list),
|
||||
_ => None,
|
||||
},
|
||||
@ -160,7 +160,7 @@ impl Attribute {
|
||||
}
|
||||
|
||||
pub fn is_word(&self) -> bool {
|
||||
if let AttrKind::Normal(item) = &self.kind {
|
||||
if let AttrKind::Normal(item, _) = &self.kind {
|
||||
matches!(item.args, MacArgs::Empty)
|
||||
} else {
|
||||
false
|
||||
@ -246,7 +246,7 @@ impl AttrItem {
|
||||
impl Attribute {
|
||||
pub fn is_doc_comment(&self) -> bool {
|
||||
match self.kind {
|
||||
AttrKind::Normal(_) => false,
|
||||
AttrKind::Normal(..) => false,
|
||||
AttrKind::DocComment(..) => true,
|
||||
}
|
||||
}
|
||||
@ -254,7 +254,7 @@ impl Attribute {
|
||||
pub fn doc_str(&self) -> Option<Symbol> {
|
||||
match self.kind {
|
||||
AttrKind::DocComment(.., data) => Some(data),
|
||||
AttrKind::Normal(ref item) if item.path == sym::doc => {
|
||||
AttrKind::Normal(ref item, _) if item.path == sym::doc => {
|
||||
item.meta(self.span).and_then(|meta| meta.value_str())
|
||||
}
|
||||
_ => None,
|
||||
@ -263,14 +263,14 @@ impl Attribute {
|
||||
|
||||
pub fn get_normal_item(&self) -> &AttrItem {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref item) => item,
|
||||
AttrKind::Normal(ref item, _) => item,
|
||||
AttrKind::DocComment(..) => panic!("unexpected doc comment"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_normal_item(self) -> AttrItem {
|
||||
match self.kind {
|
||||
AttrKind::Normal(item) => item,
|
||||
AttrKind::Normal(item, _) => item,
|
||||
AttrKind::DocComment(..) => panic!("unexpected doc comment"),
|
||||
}
|
||||
}
|
||||
@ -278,10 +278,22 @@ impl Attribute {
|
||||
/// Extracts the MetaItem from inside this Attribute.
|
||||
pub fn meta(&self) -> Option<MetaItem> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref item) => item.meta(self.span),
|
||||
AttrKind::Normal(ref item, _) => item.meta(self.span),
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tokens(&self) -> TokenStream {
|
||||
match self.kind {
|
||||
AttrKind::Normal(_, ref tokens) => tokens
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self))
|
||||
.create_token_stream(),
|
||||
AttrKind::DocComment(comment_kind, data) => TokenStream::from(TokenTree::Token(
|
||||
Token::new(token::DocComment(comment_kind, self.style, data), self.span),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Constructors */
|
||||
@ -321,11 +333,16 @@ crate fn mk_attr_id() -> AttrId {
|
||||
}
|
||||
|
||||
pub fn mk_attr(style: AttrStyle, path: Path, args: MacArgs, span: Span) -> Attribute {
|
||||
mk_attr_from_item(style, AttrItem { path, args, tokens: None }, span)
|
||||
mk_attr_from_item(AttrItem { path, args, tokens: None }, None, style, span)
|
||||
}
|
||||
|
||||
pub fn mk_attr_from_item(style: AttrStyle, item: AttrItem, span: Span) -> Attribute {
|
||||
Attribute { kind: AttrKind::Normal(item), id: mk_attr_id(), style, span, tokens: None }
|
||||
pub fn mk_attr_from_item(
|
||||
item: AttrItem,
|
||||
tokens: Option<LazyTokenStream>,
|
||||
style: AttrStyle,
|
||||
span: Span,
|
||||
) -> Attribute {
|
||||
Attribute { kind: AttrKind::Normal(item, tokens), id: mk_attr_id(), style, span }
|
||||
}
|
||||
|
||||
/// Returns an inner attribute with the given value and span.
|
||||
@ -344,13 +361,7 @@ pub fn mk_doc_comment(
|
||||
data: Symbol,
|
||||
span: Span,
|
||||
) -> Attribute {
|
||||
Attribute {
|
||||
kind: AttrKind::DocComment(comment_kind, data),
|
||||
id: mk_attr_id(),
|
||||
style,
|
||||
span,
|
||||
tokens: None,
|
||||
}
|
||||
Attribute { kind: AttrKind::DocComment(comment_kind, data), id: mk_attr_id(), style, span }
|
||||
}
|
||||
|
||||
pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
|
||||
|
@ -586,17 +586,17 @@ pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
|
||||
}
|
||||
|
||||
pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
|
||||
let Attribute { kind, id: _, style: _, span, tokens } = attr;
|
||||
let Attribute { kind, id: _, style: _, span } = attr;
|
||||
match kind {
|
||||
AttrKind::Normal(AttrItem { path, args, tokens }) => {
|
||||
AttrKind::Normal(AttrItem { path, args, tokens }, attr_tokens) => {
|
||||
vis.visit_path(path);
|
||||
visit_mac_args(args, vis);
|
||||
visit_lazy_tts(tokens, vis);
|
||||
visit_lazy_tts(attr_tokens, vis);
|
||||
}
|
||||
AttrKind::DocComment(..) => {}
|
||||
}
|
||||
vis.visit_span(span);
|
||||
visit_lazy_tts(tokens, vis);
|
||||
}
|
||||
|
||||
pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) {
|
||||
|
@ -881,7 +881,7 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) {
|
||||
|
||||
pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) {
|
||||
match attr.kind {
|
||||
AttrKind::Normal(ref item) => walk_mac_args(visitor, &item.args),
|
||||
AttrKind::Normal(ref item, ref _tokens) => walk_mac_args(visitor, &item.args),
|
||||
AttrKind::DocComment(..) => {}
|
||||
}
|
||||
}
|
||||
|
@ -966,17 +966,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// Note that we explicitly do not walk the path. Since we don't really
|
||||
// lower attributes (we use the AST version) there is nowhere to keep
|
||||
// the `HirId`s. We don't actually need HIR version of attributes anyway.
|
||||
// Tokens are also not needed after macro expansion and parsing.
|
||||
let kind = match attr.kind {
|
||||
AttrKind::Normal(ref item) => AttrKind::Normal(AttrItem {
|
||||
path: item.path.clone(),
|
||||
args: self.lower_mac_args(&item.args),
|
||||
tokens: None,
|
||||
}),
|
||||
AttrKind::Normal(ref item, _) => AttrKind::Normal(
|
||||
AttrItem {
|
||||
path: item.path.clone(),
|
||||
args: self.lower_mac_args(&item.args),
|
||||
tokens: None,
|
||||
},
|
||||
None,
|
||||
),
|
||||
AttrKind::DocComment(comment_kind, data) => AttrKind::DocComment(comment_kind, data),
|
||||
};
|
||||
|
||||
// Tokens aren't needed after macro expansion and parsing
|
||||
Attribute { kind, id: attr.id, style: attr.style, span: attr.span, tokens: None }
|
||||
Attribute { kind, id: attr.id, style: attr.style, span: attr.span }
|
||||
}
|
||||
|
||||
fn lower_mac_args(&mut self, args: &MacArgs) -> MacArgs {
|
||||
|
@ -426,7 +426,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
}
|
||||
self.maybe_print_comment(attr.span.lo());
|
||||
match attr.kind {
|
||||
ast::AttrKind::Normal(ref item) => {
|
||||
ast::AttrKind::Normal(ref item, _) => {
|
||||
match attr.style {
|
||||
ast::AttrStyle::Inner => self.word("#!["),
|
||||
ast::AttrStyle::Outer => self.word("#["),
|
||||
|
@ -291,8 +291,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||
expanded_attrs
|
||||
.into_iter()
|
||||
.flat_map(|(item, span)| {
|
||||
let orig_tokens =
|
||||
attr.tokens.as_ref().unwrap_or_else(|| panic!("Missing tokens for {:?}", attr));
|
||||
let orig_tokens = attr.tokens();
|
||||
|
||||
// We are taking an attribute of the form `#[cfg_attr(pred, attr)]`
|
||||
// and producing an attribute of the form `#[attr]`. We
|
||||
@ -302,7 +301,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||
|
||||
// Use the `#` in `#[cfg_attr(pred, attr)]` as the `#` token
|
||||
// for `attr` when we expand it to `#[attr]`
|
||||
let pound_token = orig_tokens.create_token_stream().trees().next().unwrap();
|
||||
let pound_token = orig_tokens.trees().next().unwrap();
|
||||
if !matches!(pound_token, TokenTree::Token(Token { kind: TokenKind::Pound, .. })) {
|
||||
panic!("Bad tokens for attribute {:?}", attr);
|
||||
}
|
||||
@ -316,13 +315,12 @@ impl<'a> StripUnconfigured<'a> {
|
||||
.unwrap_or_else(|| panic!("Missing tokens for {:?}", item))
|
||||
.create_token_stream(),
|
||||
);
|
||||
|
||||
let mut attr = attr::mk_attr_from_item(attr.style, item, span);
|
||||
attr.tokens = Some(LazyTokenStream::new(TokenStream::new(vec![
|
||||
let tokens = Some(LazyTokenStream::new(TokenStream::new(vec![
|
||||
(pound_token, Spacing::Alone),
|
||||
(bracket_group, Spacing::Alone),
|
||||
])));
|
||||
self.process_cfg_attr(attr)
|
||||
|
||||
self.process_cfg_attr(attr::mk_attr_from_item(item, tokens, attr.style, span))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -1776,15 +1776,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||
|
||||
let meta = attr::mk_list_item(Ident::with_dummy_span(sym::doc), items);
|
||||
*at = ast::Attribute {
|
||||
kind: ast::AttrKind::Normal(AttrItem {
|
||||
path: meta.path,
|
||||
args: meta.kind.mac_args(meta.span),
|
||||
tokens: None,
|
||||
}),
|
||||
kind: ast::AttrKind::Normal(
|
||||
AttrItem { path: meta.path, args: meta.kind.mac_args(meta.span), tokens: None },
|
||||
None,
|
||||
),
|
||||
span: at.span,
|
||||
id: at.id,
|
||||
style: at.style,
|
||||
tokens: None,
|
||||
};
|
||||
} else {
|
||||
noop_visit_attribute(at, self)
|
||||
|
@ -40,8 +40,8 @@ impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
|
||||
debug_assert!(!attr.ident().map_or(false, |ident| self.is_ignored_attr(ident.name)));
|
||||
debug_assert!(!attr.is_doc_comment());
|
||||
|
||||
let ast::Attribute { kind, id: _, style, span, tokens } = attr;
|
||||
if let ast::AttrKind::Normal(item) = kind {
|
||||
let ast::Attribute { kind, id: _, style, span } = attr;
|
||||
if let ast::AttrKind::Normal(item, tokens) = kind {
|
||||
item.hash_stable(self, hasher);
|
||||
style.hash_stable(self, hasher);
|
||||
span.hash_stable(self, hasher);
|
||||
|
@ -616,12 +616,7 @@ fn prepend_attrs(
|
||||
if attr.style == ast::AttrStyle::Inner {
|
||||
return None;
|
||||
}
|
||||
builder.push(
|
||||
attr.tokens
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| panic!("Attribute {:?} is missing tokens!", attr))
|
||||
.create_token_stream(),
|
||||
);
|
||||
builder.push(attr.tokens());
|
||||
}
|
||||
builder.push(tokens);
|
||||
Some(builder.build())
|
||||
|
@ -30,52 +30,44 @@ impl<'a> Parser<'a> {
|
||||
let mut just_parsed_doc_comment = false;
|
||||
loop {
|
||||
debug!("parse_outer_attributes: self.token={:?}", self.token);
|
||||
let (attr, tokens) = if self.check(&token::Pound) {
|
||||
self.collect_tokens(|this| {
|
||||
let inner_error_reason = if just_parsed_doc_comment {
|
||||
"an inner attribute is not permitted following an outer doc comment"
|
||||
} else if !attrs.is_empty() {
|
||||
"an inner attribute is not permitted following an outer attribute"
|
||||
} else {
|
||||
DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
|
||||
};
|
||||
let inner_parse_policy = InnerAttrPolicy::Forbidden {
|
||||
reason: inner_error_reason,
|
||||
saw_doc_comment: just_parsed_doc_comment,
|
||||
prev_attr_sp: attrs.last().map(|a| a.span),
|
||||
};
|
||||
let attr = this.parse_attribute_with_inner_parse_policy(inner_parse_policy)?;
|
||||
just_parsed_doc_comment = false;
|
||||
Ok(Some(attr))
|
||||
})?
|
||||
let attr = if self.check(&token::Pound) {
|
||||
let inner_error_reason = if just_parsed_doc_comment {
|
||||
"an inner attribute is not permitted following an outer doc comment"
|
||||
} else if !attrs.is_empty() {
|
||||
"an inner attribute is not permitted following an outer attribute"
|
||||
} else {
|
||||
DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
|
||||
};
|
||||
let inner_parse_policy = InnerAttrPolicy::Forbidden {
|
||||
reason: inner_error_reason,
|
||||
saw_doc_comment: just_parsed_doc_comment,
|
||||
prev_attr_sp: attrs.last().map(|a| a.span),
|
||||
};
|
||||
just_parsed_doc_comment = false;
|
||||
Some(self.parse_attribute(inner_parse_policy)?)
|
||||
} else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind {
|
||||
self.collect_tokens(|this| {
|
||||
let attr =
|
||||
attr::mk_doc_comment(comment_kind, attr_style, data, this.token.span);
|
||||
if attr.style != ast::AttrStyle::Outer {
|
||||
this.sess
|
||||
.span_diagnostic
|
||||
.struct_span_err_with_code(
|
||||
this.token.span,
|
||||
"expected outer doc comment",
|
||||
error_code!(E0753),
|
||||
)
|
||||
.note(
|
||||
"inner doc comments like this (starting with \
|
||||
`//!` or `/*!`) can only appear before items",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
this.bump();
|
||||
just_parsed_doc_comment = true;
|
||||
Ok(Some(attr))
|
||||
})?
|
||||
if attr_style != ast::AttrStyle::Outer {
|
||||
self.sess
|
||||
.span_diagnostic
|
||||
.struct_span_err_with_code(
|
||||
self.token.span,
|
||||
"expected outer doc comment",
|
||||
error_code!(E0753),
|
||||
)
|
||||
.note(
|
||||
"inner doc comments like this (starting with \
|
||||
`//!` or `/*!`) can only appear before items",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
self.bump();
|
||||
just_parsed_doc_comment = true;
|
||||
Some(attr::mk_doc_comment(comment_kind, attr_style, data, self.prev_token.span))
|
||||
} else {
|
||||
(None, None)
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(mut attr) = attr {
|
||||
attr.tokens = tokens;
|
||||
if let Some(attr) = attr {
|
||||
attrs.push(attr);
|
||||
} else {
|
||||
break;
|
||||
@ -85,49 +77,43 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Matches `attribute = # ! [ meta_item ]`.
|
||||
///
|
||||
/// If `permit_inner` is `true`, then a leading `!` indicates an inner
|
||||
/// attribute.
|
||||
pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<'a, ast::Attribute> {
|
||||
debug!("parse_attribute: permit_inner={:?} self.token={:?}", permit_inner, self.token);
|
||||
let inner_parse_policy =
|
||||
if permit_inner { InnerAttrPolicy::Permitted } else { DEFAULT_INNER_ATTR_FORBIDDEN };
|
||||
self.parse_attribute_with_inner_parse_policy(inner_parse_policy)
|
||||
}
|
||||
|
||||
/// The same as `parse_attribute`, except it takes in an `InnerAttrPolicy`
|
||||
/// that prescribes how to handle inner attributes.
|
||||
fn parse_attribute_with_inner_parse_policy(
|
||||
/// `inner_parse_policy` prescribes how to handle inner attributes.
|
||||
fn parse_attribute(
|
||||
&mut self,
|
||||
inner_parse_policy: InnerAttrPolicy<'_>,
|
||||
) -> PResult<'a, ast::Attribute> {
|
||||
debug!(
|
||||
"parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}",
|
||||
"parse_attribute: inner_parse_policy={:?} self.token={:?}",
|
||||
inner_parse_policy, self.token
|
||||
);
|
||||
let lo = self.token.span;
|
||||
let (span, item, style) = if self.eat(&token::Pound) {
|
||||
let style =
|
||||
if self.eat(&token::Not) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer };
|
||||
let ((item, style, span), tokens) = self.collect_tokens(|this| {
|
||||
if this.eat(&token::Pound) {
|
||||
let style = if this.eat(&token::Not) {
|
||||
ast::AttrStyle::Inner
|
||||
} else {
|
||||
ast::AttrStyle::Outer
|
||||
};
|
||||
|
||||
self.expect(&token::OpenDelim(token::Bracket))?;
|
||||
let item = self.parse_attr_item(false)?;
|
||||
self.expect(&token::CloseDelim(token::Bracket))?;
|
||||
let attr_sp = lo.to(self.prev_token.span);
|
||||
this.expect(&token::OpenDelim(token::Bracket))?;
|
||||
let item = this.parse_attr_item(false)?;
|
||||
this.expect(&token::CloseDelim(token::Bracket))?;
|
||||
let attr_sp = lo.to(this.prev_token.span);
|
||||
|
||||
// Emit error if inner attribute is encountered and forbidden.
|
||||
if style == ast::AttrStyle::Inner {
|
||||
self.error_on_forbidden_inner_attr(attr_sp, inner_parse_policy);
|
||||
// Emit error if inner attribute is encountered and forbidden.
|
||||
if style == ast::AttrStyle::Inner {
|
||||
this.error_on_forbidden_inner_attr(attr_sp, inner_parse_policy);
|
||||
}
|
||||
|
||||
Ok((item, style, attr_sp))
|
||||
} else {
|
||||
let token_str = pprust::token_to_string(&this.token);
|
||||
let msg = &format!("expected `#`, found `{}`", token_str);
|
||||
Err(this.struct_span_err(this.token.span, msg))
|
||||
}
|
||||
})?;
|
||||
|
||||
(attr_sp, item, style)
|
||||
} else {
|
||||
let token_str = pprust::token_to_string(&self.token);
|
||||
let msg = &format!("expected `#`, found `{}`", token_str);
|
||||
return Err(self.struct_span_err(self.token.span, msg));
|
||||
};
|
||||
|
||||
Ok(attr::mk_attr_from_item(style, item, span))
|
||||
Ok(attr::mk_attr_from_item(item, tokens, style, span))
|
||||
}
|
||||
|
||||
pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy<'_>) {
|
||||
@ -196,30 +182,19 @@ impl<'a> Parser<'a> {
|
||||
let mut attrs: Vec<ast::Attribute> = vec![];
|
||||
loop {
|
||||
// Only try to parse if it is an inner attribute (has `!`).
|
||||
let (attr, tokens) =
|
||||
if self.check(&token::Pound) && self.look_ahead(1, |t| t == &token::Not) {
|
||||
self.collect_tokens(|this| {
|
||||
let attr = this.parse_attribute(true)?;
|
||||
assert_eq!(attr.style, ast::AttrStyle::Inner);
|
||||
Ok(Some(attr))
|
||||
})?
|
||||
} else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind {
|
||||
self.collect_tokens(|this| {
|
||||
// We need to get the position of this token before we bump.
|
||||
let attr =
|
||||
attr::mk_doc_comment(comment_kind, attr_style, data, this.token.span);
|
||||
if attr.style == ast::AttrStyle::Inner {
|
||||
this.bump();
|
||||
Ok(Some(attr))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})?
|
||||
let attr = if self.check(&token::Pound) && self.look_ahead(1, |t| t == &token::Not) {
|
||||
Some(self.parse_attribute(InnerAttrPolicy::Permitted)?)
|
||||
} else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind {
|
||||
if attr_style == ast::AttrStyle::Inner {
|
||||
self.bump();
|
||||
Some(attr::mk_doc_comment(comment_kind, attr_style, data, self.prev_token.span))
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
if let Some(mut attr) = attr {
|
||||
attr.tokens = tokens;
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(attr) = attr {
|
||||
attrs.push(attr);
|
||||
} else {
|
||||
break;
|
||||
|
@ -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":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"tokens":null}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0},"tokens":{"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"]]}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
|
||||
{"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":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":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 +1 @@
|
||||
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0},"tokens":null}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0},"tokens":null}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"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":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"tokens":null}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0},"tokens":{"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"]]}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
|
||||
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"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":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":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":[]}
|
||||
|
@ -588,7 +588,7 @@ impl EarlyLintPass for EarlyAttributes {
|
||||
|
||||
fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
|
||||
for attr in &item.attrs {
|
||||
let attr_item = if let AttrKind::Normal(ref attr) = attr.kind {
|
||||
let attr_item = if let AttrKind::Normal(ref attr, _) = attr.kind {
|
||||
attr
|
||||
} else {
|
||||
return;
|
||||
|
@ -509,7 +509,7 @@ pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool {
|
||||
l.style == r.style
|
||||
&& match (&l.kind, &r.kind) {
|
||||
(DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2,
|
||||
(Normal(l), Normal(r)) => eq_path(&l.path, &r.path) && eq_mac_args(&l.args, &r.args),
|
||||
(Normal(l, _), Normal(r, _)) => eq_path(&l.path, &r.path) && eq_mac_args(&l.args, &r.args),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ pub fn get_attr<'a>(
|
||||
name: &'static str,
|
||||
) -> impl Iterator<Item = &'a ast::Attribute> {
|
||||
attrs.iter().filter(move |attr| {
|
||||
let attr = if let ast::AttrKind::Normal(ref attr) = attr.kind {
|
||||
let attr = if let ast::AttrKind::Normal(ref attr, _) = attr.kind {
|
||||
attr
|
||||
} else {
|
||||
return false;
|
||||
|
@ -1349,7 +1349,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
|
||||
pub fn is_no_std_crate(krate: &Crate<'_>) -> bool {
|
||||
krate.item.attrs.iter().any(|attr| {
|
||||
if let ast::AttrKind::Normal(ref attr) = attr.kind {
|
||||
if let ast::AttrKind::Normal(ref attr, _) = attr.kind {
|
||||
attr.path == symbol::sym::no_std
|
||||
} else {
|
||||
false
|
||||
|
Loading…
Reference in New Issue
Block a user