diff options
| author | Nicholas Nethercote <nnethercote@mozilla.com> | 2019-10-24 06:33:12 +1100 |
|---|---|---|
| committer | Nicholas Nethercote <nnethercote@mozilla.com> | 2019-11-06 23:05:07 +1100 |
| commit | eea6f23a0ed67fd8c6b8e1b02cda3628fee56b2f (patch) | |
| tree | effdb244138f311440b21c9fd52e4028edb575ea /src/libsyntax_expand | |
| parent | 69bc4aba785e071740d2d46f109623b9951aae5d (diff) | |
| download | rust-eea6f23a0ed67fd8c6b8e1b02cda3628fee56b2f.tar.gz rust-eea6f23a0ed67fd8c6b8e1b02cda3628fee56b2f.zip | |
Make doc comments cheaper with `AttrKind`.
`AttrKind` is a new type with two variants, `Normal` and `DocComment`. It's a
big performance win (over 10% in some cases) because `DocComment` lets doc
comments (which are common) be represented very cheaply.
`Attribute` gets some new helper methods to ease the transition:
- `has_name()`: check if the attribute name matches a single `Symbol`; for
`DocComment` variants it succeeds if the symbol is `sym::doc`.
- `is_doc_comment()`: check if it has a `DocComment` kind.
- `{get,unwrap}_normal_item()`: extract the item from a `Normal` variant;
panic otherwise.
Fixes #60935.
Diffstat (limited to 'src/libsyntax_expand')
| -rw-r--r-- | src/libsyntax_expand/expand.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax_expand/proc_macro.rs | 4 |
2 files changed, 12 insertions, 10 deletions
diff --git a/src/libsyntax_expand/expand.rs b/src/libsyntax_expand/expand.rs index 392563587ba..7dbc7787010 100644 --- a/src/libsyntax_expand/expand.rs +++ b/src/libsyntax_expand/expand.rs @@ -419,7 +419,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } let mut item = self.fully_configure(item); - item.visit_attrs(|attrs| attrs.retain(|a| a.item.path != sym::derive)); + item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive))); let mut helper_attrs = Vec::new(); let mut has_copy = false; for ext in exts { @@ -634,9 +634,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { | Annotatable::Variant(..) => panic!("unexpected annotatable"), })), DUMMY_SP).into(); - let input = self.extract_proc_macro_attr_input(attr.item.tokens, span); + let item = attr.unwrap_normal_item(); + let input = self.extract_proc_macro_attr_input(item.tokens, span); let tok_result = expander.expand(self.cx, span, input, item_tok); - self.parse_ast_fragment(tok_result, fragment_kind, &attr.item.path, span) + self.parse_ast_fragment(tok_result, fragment_kind, &item.path, span) } SyntaxExtensionKind::LegacyAttr(expander) => { match attr.parse_meta(self.cx.parse_sess) { @@ -974,7 +975,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { -> Option<ast::Attribute> { let attr = attrs.iter() .position(|a| { - if a.item.path == sym::derive { + if a.has_name(sym::derive) { *after_derive = true; } !attr::is_known(a) && !is_builtin_attr(a) @@ -982,7 +983,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { .map(|i| attrs.remove(i)); if let Some(attr) = &attr { if !self.cx.ecfg.custom_inner_attributes() && - attr.style == ast::AttrStyle::Inner && attr.item.path != sym::test { + attr.style == ast::AttrStyle::Inner && !attr.has_name(sym::test) { emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes, attr.span, GateIssue::Language, "non-builtin inner attributes are unstable"); @@ -1032,7 +1033,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { feature_gate::check_attribute(attr, self.cx.parse_sess, features); // macros are expanded before any lint passes so this warning has to be hardcoded - if attr.item.path == sym::derive { + if attr.has_name(sym::derive) { self.cx.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations") .note("this may become a hard error in a future release") .emit(); @@ -1547,11 +1548,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { let meta = attr::mk_list_item(Ident::with_dummy_span(sym::doc), items); *at = attr::Attribute { - item: AttrItem { path: meta.path, tokens: meta.kind.tokens(meta.span) }, + kind: ast::AttrKind::Normal( + AttrItem { path: meta.path, tokens: meta.kind.tokens(meta.span) }, + ), span: at.span, id: at.id, style: at.style, - is_sugared_doc: false, }; } else { noop_visit_attribute(at, self) diff --git a/src/libsyntax_expand/proc_macro.rs b/src/libsyntax_expand/proc_macro.rs index 53cd4d3519f..1f4c481e3ea 100644 --- a/src/libsyntax_expand/proc_macro.rs +++ b/src/libsyntax_expand/proc_macro.rs @@ -181,7 +181,7 @@ impl<'a> Visitor<'a> for MarkAttrs<'a> { crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> { let mut result = Vec::new(); attrs.retain(|attr| { - if attr.item.path != sym::derive { + if !attr.has_name(sym::derive) { return true; } if !attr.is_meta_item_list() { @@ -196,7 +196,7 @@ crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) } let parse_derive_paths = |attr: &ast::Attribute| { - if attr.item.tokens.is_empty() { + if attr.get_normal_item().tokens.is_empty() { return Ok(Vec::new()); } parse::parse_in_attr(cx.parse_sess, attr, |p| p.parse_derive_paths()) |
