diff options
| author | bors <bors@rust-lang.org> | 2022-01-01 02:03:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-01-01 02:03:23 +0000 |
| commit | c9cf9c65072a35585f9521ab95044f32d5fcb9ec (patch) | |
| tree | da4d7b058007b67b96335ce0a9720758f99b45a8 | |
| parent | 4d2e0fd96ccbb9ade41f1a3f07b14b7437f8e4ef (diff) | |
| parent | 047275a68266033b2d7646e5380d8491ec550677 (diff) | |
| download | rust-c9cf9c65072a35585f9521ab95044f32d5fcb9ec.tar.gz rust-c9cf9c65072a35585f9521ab95044f32d5fcb9ec.zip | |
Auto merge of #92294 - Kobzol:rustdoc-meta-kind, r=GuillaumeGomez
Add Attribute::meta_kind The `AttrItem::meta` function is being called on a lot of places, however almost always the caller is only interested in the `kind` of the result `MetaItem`. Before, the `path` had to be cloned in order to get the kind, now it does not have to be. There is a larger related "problem". In a lot of places, something wants to know contents of attributes. This is accessed through `Attribute::meta_item_list`, which calls `AttrItem::meta` (now `AttrItem::meta_kind`), among other methods. When this function is called, the meta item list has to be recreated from scratch. Everytime something asks a simple question (like is this item/list of attributes `#[doc(hidden)]`?), the tokens of the attribute(s) are cloned, parsed and the results are allocated on the heap. That seems really unnecessary. What would be the best way to cache this? Turn `meta_item_list` into a query perhaps? Related PR: https://github.com/rust-lang/rust/pull/92227 r? rust-lang/rustdoc
| -rw-r--r-- | compiler/rustc_ast/src/attr/mod.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/util.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/lib_features.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/collect.rs | 6 |
4 files changed, 32 insertions, 11 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 927d7c6aaf6..d66774040f7 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -136,15 +136,15 @@ 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_kind().and_then(|kind| kind.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) { - Some(MetaItem { kind: MetaItemKind::List(list), .. }) => Some(list), + AttrKind::Normal(ref item, _) => match item.meta_kind() { + Some(MetaItemKind::List(list)) => Some(list), _ => None, }, AttrKind::DocComment(..) => None, @@ -228,6 +228,10 @@ impl AttrItem { span, }) } + + pub fn meta_kind(&self) -> Option<MetaItemKind> { + Some(MetaItemKind::from_mac_args(&self.args)?) + } } impl Attribute { @@ -242,7 +246,7 @@ impl Attribute { match self.kind { AttrKind::DocComment(.., data) => Some(data), AttrKind::Normal(ref item, _) if item.path == sym::doc => { - item.meta(self.span).and_then(|meta| meta.value_str()) + item.meta_kind().and_then(|kind| kind.value_str()) } _ => None, } @@ -270,6 +274,13 @@ impl Attribute { } } + pub fn meta_kind(&self) -> Option<MetaItemKind> { + match self.kind { + AttrKind::Normal(ref item, _) => item.meta_kind(), + AttrKind::DocComment(..) => None, + } + } + pub fn tokens(&self) -> AttrAnnotatedTokenStream { match self.kind { AttrKind::Normal(_, ref tokens) => tokens @@ -436,6 +447,16 @@ impl MetaItem { } impl MetaItemKind { + pub fn value_str(&self) -> Option<Symbol> { + match self { + MetaItemKind::NameValue(ref v) => match v.kind { + LitKind::Str(ref s, _) => Some(*s), + _ => None, + }, + _ => None, + } + } + pub fn mac_args(&self, span: Span) -> MacArgs { match self { MetaItemKind::Word => MacArgs::Empty, diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index b04f91634cc..cb51555f5ca 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -484,7 +484,7 @@ pub(crate) fn check_attr_crate_type( return; } - if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().kind { + if let ast::MetaItemKind::NameValue(spanned) = a.meta_kind().unwrap() { let span = spanned.span; let lev_candidate = find_best_match_for_name( &CRATE_TYPES.iter().map(|(k, _)| *k).collect::<Vec<_>>(), diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 55ae808dc30..40d12c4a22d 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -4,7 +4,7 @@ // and `#[unstable (..)]`), but are not declared in one single location // (unlike lang features), which means we need to collect them instead. -use rustc_ast::{Attribute, MetaItem, MetaItemKind}; +use rustc_ast::{Attribute, MetaItemKind}; use rustc_errors::struct_span_err; use rustc_hir::intravisit::{NestedVisitorMap, Visitor}; use rustc_middle::hir::map::Map; @@ -34,8 +34,8 @@ impl<'tcx> LibFeatureCollector<'tcx> { // Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`, // `#[rustc_const_unstable (..)]`). if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.has_name(**stab_attr)) { - let meta_item = attr.meta(); - if let Some(MetaItem { kind: MetaItemKind::List(ref metas), .. }) = meta_item { + let meta_kind = attr.meta_kind(); + if let Some(MetaItemKind::List(ref metas)) = meta_kind { let mut feature = None; let mut since = None; for meta in metas { diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index e7b728d491b..2fb5590016e 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2894,7 +2894,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { } } } else if attr.has_name(sym::instruction_set) { - codegen_fn_attrs.instruction_set = match attr.meta().map(|i| i.kind) { + codegen_fn_attrs.instruction_set = match attr.meta_kind() { Some(MetaItemKind::List(ref items)) => match items.as_slice() { [NestedMetaItem::MetaItem(set)] => { let segments = @@ -2999,7 +2999,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { if !attr.has_name(sym::inline) { return ia; } - match attr.meta().map(|i| i.kind) { + match attr.meta_kind() { Some(MetaItemKind::Word) => InlineAttr::Hint, Some(MetaItemKind::List(ref items)) => { inline_span = Some(attr.span); @@ -3038,7 +3038,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { return ia; } let err = |sp, s| struct_span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s).emit(); - match attr.meta().map(|i| i.kind) { + match attr.meta_kind() { Some(MetaItemKind::Word) => { err(attr.span, "expected one argument"); ia |
